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

48 lines
1.7 KiB
TypeScript

// What the crm module does, as pure TypeScript over the port in ports.ts.
//
// Parties belong to the credential-bound app tenant and environment. Projects within
// that partition share its address book. Linked people use the actual resolved
// app member reference; another app tenant or environment has a different binding.
import type { ProjectScope } from "@conusai-kit/core"
import { type ContactView, PAGE_LIMIT, type PartyView } from "../contract/index.js"
import { type ContactActionInput, contactActionData, type PartyActionInput, partyActionData } from "./action-plan.js"
import type { CrmReads, CrmService, Page } from "./ports.js"
export function listParties(
reads: CrmReads,
query: { q?: string; after?: string; limit?: number },
): Promise<Page<PartyView>> {
const q = query.q?.trim()
return reads.listParties({
...(q ? { q } : {}),
...(query.after === undefined ? {} : { after: query.after }),
limit: query.limit ?? PAGE_LIMIT,
})
}
export async function getParty(
reads: CrmReads,
partyId: string,
): Promise<{ party: PartyView; contacts: ContactView[] }> {
const party = await reads.getParty(partyId)
const contacts = await reads.listContacts(partyId, { limit: PAGE_LIMIT })
return { party, contacts: contacts.rows }
}
export async function createParty(
service: CrmService,
scope: ProjectScope,
input: PartyActionInput,
): Promise<PartyView> {
return service.createParty(partyActionData(scope, service.bindingId, input))
}
export function addContact(
service: CrmService,
scope: ProjectScope,
input: ContactActionInput,
now: Date = new Date(),
): Promise<ContactView> {
return service.addContact(contactActionData(scope, input, now))
}