Files
2026-11-14 09:56:45 +00:00

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),
),
}
},
},
])