@@ -0,0 +1,56 @@
|
||||
// The port the crm module's use cases are written against: the platform's CRM service, in this
|
||||
// module's own words. adapters/service.ts is the one place that knows `@conusai-sdk/crm` exists, and
|
||||
// it turns every refusal into the kit's app errors (`businessAppError` of
|
||||
// `@conusai-kit/business`) before core sees it.
|
||||
|
||||
import { token } from "@conusai-kit/core"
|
||||
import type { ContactView, PartyView } from "../contract/index.js"
|
||||
|
||||
export interface Page<T> {
|
||||
readonly rows: T[]
|
||||
readonly after?: string
|
||||
}
|
||||
|
||||
/** What a `read` procedure may ask the service: nothing that changes a row. */
|
||||
export interface CrmReads {
|
||||
/** The immutable app/environment binding UUID for attributed member references. */
|
||||
readonly bindingId: string
|
||||
listParties(query: { q?: string; after?: string; limit: number }): Promise<Page<PartyView>>
|
||||
getParty(partyId: string): Promise<PartyView>
|
||||
listContacts(partyId: string, query: { after?: string; limit: number }): Promise<Page<ContactView>>
|
||||
}
|
||||
|
||||
export interface CrmService extends CrmReads {
|
||||
createParty(input: {
|
||||
kind: "person" | "organization"
|
||||
displayName: string
|
||||
legalName?: string
|
||||
country: string
|
||||
identifiers: { scheme: string; value: string }[]
|
||||
key: string
|
||||
}): Promise<PartyView>
|
||||
addContact(input: {
|
||||
partyId: string
|
||||
kind: "email" | "phone" | "web"
|
||||
value: string
|
||||
purposes: ContactView["purposes"]
|
||||
isPrimary: boolean
|
||||
/** `YYYY-MM-DD`: the day the contact point starts to hold. */
|
||||
effectiveFrom: string
|
||||
key: string
|
||||
}): Promise<ContactView>
|
||||
}
|
||||
|
||||
/** The read view a `read` or `write` handler receives: the kind is a capability, not a label. */
|
||||
export const crmReadsOf = (service: CrmReads): CrmReads => ({
|
||||
bindingId: service.bindingId,
|
||||
listParties: (query) => service.listParties(query),
|
||||
getParty: (partyId) => service.getParty(partyId),
|
||||
listContacts: (partyId, query) => service.listContacts(partyId, query),
|
||||
})
|
||||
|
||||
/**
|
||||
* Bound by a composition root or a test that brings its own client (another organization, the
|
||||
* business-services fake). With nothing bound, the module calls this deployment's service.
|
||||
*/
|
||||
export const CRM_SERVICE = token<CrmService>("crm.service", { views: { read: crmReadsOf, write: crmReadsOf } })
|
||||
Reference in New Issue
Block a user