61 lines
2.2 KiB
TypeScript
61 lines
2.2 KiB
TypeScript
// Fixed server declarations. The same pure plan is used by the real core and
|
|
// generated SDK body encoder; declarations alone grant no approval/permission.
|
|
import { requestBusinessBinding } from "@conusai-kit/business"
|
|
import { type Container, forbidden, type TenantScope } from "@conusai-kit/core"
|
|
import { contactAdd, partyCreate } from "../contract/index.js"
|
|
import { contactActionData, contactEncodedRequest, partyActionData, partyEncodedRequest } from "../core/action-plan.js"
|
|
|
|
import { CRM_SERVICE } from "../core/ports.js"
|
|
|
|
interface Context {
|
|
readonly scope: TenantScope
|
|
readonly container: Container
|
|
readonly now: Date
|
|
}
|
|
function current(context: Context) {
|
|
if (context.container.has(CRM_SERVICE)) throw forbidden("app action requires prepared business transport")
|
|
if (context.scope.level !== "project" || context.scope.actor.system) throw forbidden("app action refused")
|
|
const binding = requestBusinessBinding(context.container)
|
|
if (binding.actorId !== context.scope.actor.userId || binding.appTenantId !== context.scope.orgId)
|
|
throw forbidden("app action refused")
|
|
return { binding, scope: context.scope }
|
|
}
|
|
function bindingFields(binding: ReturnType<typeof requestBusinessBinding>) {
|
|
return {
|
|
bindingId: binding.bindingId,
|
|
environmentUuid: binding.environmentUuid,
|
|
appTenantId: binding.appTenantId,
|
|
actorId: binding.actorId,
|
|
orgSlug: binding.orgSlug,
|
|
platformProjectId: binding.platformProjectId,
|
|
}
|
|
}
|
|
export const crmAppActionTargets = Object.freeze([
|
|
{
|
|
procedure: partyCreate,
|
|
encode(input: unknown, context: Context) {
|
|
const { binding, scope } = current(context)
|
|
return {
|
|
binding: bindingFields(binding),
|
|
request: partyEncodedRequest(
|
|
binding.orgSlug,
|
|
partyActionData(scope, binding.bindingId, partyCreate.input.parse(input)),
|
|
),
|
|
}
|
|
},
|
|
},
|
|
{
|
|
procedure: contactAdd,
|
|
encode(input: unknown, context: Context) {
|
|
const { binding, scope } = current(context)
|
|
return {
|
|
binding: bindingFields(binding),
|
|
request: contactEncodedRequest(
|
|
binding.orgSlug,
|
|
contactActionData(scope, contactAdd.input.parse(input), context.now),
|
|
),
|
|
}
|
|
},
|
|
},
|
|
])
|