48 lines
1.7 KiB
TypeScript
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))
|
|
}
|