// The enablement flow's semantics: idempotent enable, typed denials from the platform checks, nothing // provisioned on the app's side, and disable that preserves every row and every indexed document. import type { TenantScope } from "@conusai-kit/core" import { createMemoryDataSource } from "@conusai-kit/data" import { DEFAULT_FILES_POLICY } from "@conusai-kit/files" import { fakeObjectStore } from "@conusai-kit/testing" import { describe, expect, it } from "vitest" import { collections, config, documents, KNOWLEDGE_ENTITIES } from "../contract/index.js" import { createCollection } from "../core/collections.js" import type { DocumentAiPlatform } from "../core/ports.js" import { disableDocumentAi, enableDocumentAi, getSettings } from "../core/settings.js" const ORG = "01900000-0000-7000-0000-000000000001" const scope: TenantScope = { level: "org", actor: { userId: "01900000-0000-7000-0000-000000000009" }, orgId: ORG } const platform = (over: Partial = {}): DocumentAiPlatform => ({ checkEligibility: async () => ({ ok: true }), indexingQuota: async () => 1000, ...over, }) const deps = (data: ReturnType, p: DocumentAiPlatform) => ({ data, platform: p, now: () => Date.UTC(2026, 9, 23), }) describe("the enablement flow", () => { it("enables idempotently: the second call writes nothing and answers the same configuration", async () => { const data = createMemoryDataSource({ entities: [...KNOWLEDGE_ENTITIES] }) const first = await enableDocumentAi(deps(data, platform()), scope) expect(first).toEqual({ enabled: true, backend: "platform" }) const second = await enableDocumentAi(deps(data, platform()), scope) expect(second).toEqual(first) expect((await getSettings(deps(data, platform()), scope)).enabled).toBe(true) }) it("surfaces the platform's denials as typed reason codes, retirable", async () => { const data = createMemoryDataSource({ entities: [...KNOWLEDGE_ENTITIES] }) const denied = await enableDocumentAi( deps(data, platform({ checkEligibility: async () => ({ ok: false, reason: "plan_required" }) })), scope, ).catch((error: unknown) => error) expect((denied as { code?: string }).code).toBe("plan_required") // Nothing was persisted by the denied attempt; the retry path runs the same checks again. expect((await getSettings(deps(data, platform()), scope)).enabled).toBe(false) const quota = await enableDocumentAi(deps(data, platform({ indexingQuota: async () => 0 })), scope).catch( (error: unknown) => error, ) expect((quota as { code?: string }).code).toBe("quota_exhausted") }) it("provisions nothing of the app's own: enabling records that the platform serves this organization", async () => { const data = createMemoryDataSource({ entities: [...KNOWLEDGE_ENTITIES] }) const asked: string[] = [] const watched: DocumentAiPlatform = new Proxy(platform(), { get: (target, name, receiver) => { asked.push(String(name)) return Reflect.get(target, name, receiver) }, }) await enableDocumentAi(deps(data, watched), scope) expect(asked).toEqual(["checkEligibility", "indexingQuota"]) const rows = await data.forScope(scope).of(config).list({ limit: 1 }) expect(rows.items[0]).toMatchObject({ enabled: true, backend: "platform", serviceId: null, url: null }) expect(await getSettings(deps(data, platform()), scope)).toEqual({ enabled: true, backend: "platform" }) }) it("disable preserves collections, documents and the recorded configuration; re-enable resumes without duplication", async () => { const data = createMemoryDataSource({ entities: [...KNOWLEDGE_ENTITIES] }) const projectScope: TenantScope = { level: "project", actor: { userId: "01900000-0000-7000-0000-000000000009" }, orgId: ORG, workspaceId: "01900000-0000-7000-0000-000000000002", projectId: "01900000-0000-7000-0000-000000000003", } const knowledgeDepsForProject = { data, files: { data, store: fakeObjectStore(), policy: DEFAULT_FILES_POLICY }, flags: { enabled: async () => true }, } await enableDocumentAi(deps(data, platform()), scope) const collection = await createCollection(knowledgeDepsForProject, projectScope as never, "contracts") expect(collection.name).toBe("contracts") // Seed a document row directly (the upload half is the files module's own suite). await data.forScope(projectScope).of(documents).insert({ collectionName: "contracts", fileId: "01900000-0000-7000-0000-000000000099", filename: "a.txt", status: "indexed", error: null, indexedAt: "2026-10-23T00:00:00.000Z", requestedBy: "01900000-0000-7000-0000-000000000009", }) const disabled = await disableDocumentAi(deps(data, platform()), scope) expect(disabled.enabled).toBe(false) // Everything is still there. expect((await getSettings(deps(data, platform()), scope)).backend).toBe("platform") const collectionsAfter = await data .forScope(projectScope) .of(collections) .list({ where: [{ field: "name", op: "eq", value: "contracts" }], limit: 1 }) expect(collectionsAfter.items).toHaveLength(1) const documentsAfter = await data .forScope(projectScope) .of(documents) .list({ where: [{ field: "collectionName", op: "eq", value: "contracts" }], limit: 1 }) expect(documentsAfter.items[0]?.status).toBe("indexed") // Re-enable: idempotent, same row, no second collection. await enableDocumentAi(deps(data, platform()), scope) const again = await data .forScope(projectScope) .of(collections) .list({ where: [{ field: "name", op: "eq", value: "contracts" }], limit: 1 }) expect(again.items).toHaveLength(1) }) })