// Simulated adapter dispatch; these fixtures do not prove gateway or partition isolation. // The module on its own, wired the way apps/web wires a request -- tenancy on the in-memory data // source, the crm module, and the CRM port bound to the real generated client over the // business-services fake of @conusai-kit/testing -- so its procedures are tested whether or not this // app turned the module on. import { businessClient } from "@conusai-kit/business" import { type Actor, buildRegistry, Container, createCaller, type TransportCaller } from "@conusai-kit/core" import { createMemoryDataSource, DATA_SOURCE, entitiesOf, SYSTEM_DATA } from "@conusai-kit/data" import { createTenancyHooks, TENANCY, tenancyModule, users } from "@conusai-kit/tenancy" import { type FakeBusinessServices, fakeBusinessServices } from "@conusai-kit/testing" import { createClient } from "@conusai-sdk/crm/client" import { simulatedBusinessAdmission } from "../../../test/helpers/business-admission.js" import { sdkCrmService } from "../adapters/service.js" import { CRM_SERVICE } from "../core/ports.js" import { crmModule } from "../module.js" /** The platform project of the fake deployment. */ export const BINDING_ID = "01900000-0000-7000-8000-000000000001" export interface Tenant { readonly owner: Actor readonly call: TransportCaller readonly orgSlug: string readonly orgId: string readonly workspaceSlug: string readonly workspaceId: string readonly projectSlug: string readonly projectId: string readonly slugs: { org: string; workspace: string; project: string } } export function crmApp(options: Parameters[0] = {}) { const fake: FakeBusinessServices = fakeBusinessServices(options) const client = businessClient({ apiUrl: fake.apiUrl, token: fake.token, orgSlug: fake.orgSlug }, createClient) client.setConfig({ fetch: fake.fetch as typeof fetch }) const registry = buildRegistry([tenancyModule, crmModule]) const entities = entitiesOf(registry, "postgres") const data = createMemoryDataSource({ entities }) const root = new Container() root.value(DATA_SOURCE, data) root.value(SYSTEM_DATA, data) root.value(CRM_SERVICE, sdkCrmService({ client, orgSlug: fake.orgSlug, bindingId: BINDING_ID })) const caller = (actor: Actor): TransportCaller => { const tenancy = createTenancyHooks({ data, registry }) const container = root.child() container.value(TENANCY, tenancy) return createCaller({ registry, container, tenancy, serviceReadiness: simulatedBusinessAdmission }, { actor }) } const signUp = async (email: string): Promise => { const user = await data.global(users).insert({ issuer: "https://id.example.test", subject: email, email, displayName: email.split("@")[0] ?? email, locale: "en", }) return { userId: user.id } } /** An organization with one workspace and one project, owned by a new user. */ const tenant = async (slug: string): Promise => { const owner = await signUp(`owner@${slug}.test`) const call = caller(owner) const org = (await call.callByName("tenancy.org.create", { slug, name: slug })) as { orgId: string; slug: string } const workspace = (await call.callByName("tenancy.workspace.create", { org: slug, slug: `ws-${slug}`, name: `Workspace ${slug}`, visibility: "org", })) as { workspaceId: string; slug: string } const project = (await call.callByName("tenancy.project.create", { org: slug, workspace: workspace.slug, slug: `p-${slug}`, name: `Project ${slug}`, moduleKey: "crm", })) as { projectId: string; slug: string } return { owner, call, orgSlug: org.slug, orgId: org.orgId, workspaceSlug: workspace.slug, workspaceId: workspace.workspaceId, projectSlug: project.slug, projectId: project.projectId, slugs: { org: org.slug, workspace: workspace.slug, project: project.slug }, } } /** A second user who joins `t`'s organization with the org role `role`. */ const member = async (t: Tenant, email: string, role: "viewer" | "member"): Promise => { const invite = (await t.call.callByName("tenancy.member.invite", { org: t.orgSlug, email, role })) as { token: string } const actor = await signUp(email) const call = caller(actor) await call.callByName("tenancy.invitation.accept", { org: t.orgSlug, token: invite.token }) return call } return { fake, registry, data, caller, signUp, tenant, member } }