// The enablement flow's semantics: idempotent enable, typed denials from the platform checks, the // operator endpoint's explicit validation, and disable that preserves every row and every vector. 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, 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, linkManagedQdrant: async () => ({ serviceId: "svc-1", url: null }), probeQdrant: async () => ({ ok: true }), operatorQdrant: () => null, ...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: "vectors", source: "managed", url: null }) 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("validates an operator-configured endpoint before it trusts it, and records it without the key", async () => { const data = createMemoryDataSource({ entities: [...KNOWLEDGE_ENTITIES] }) const p = platform({ operatorQdrant: () => ({ url: "http://qdrant:6333", apiKey: "secret-key" }), probeQdrant: async () => ({ ok: false, detail: "refused" }), }) const refused = await enableDocumentAi(deps(data, p), scope).catch((error: unknown) => error) expect((refused as { status?: number }).status).toBe(422) // A failed probe persists nothing. expect((await getSettings(deps(data, platform()), scope)).enabled).toBe(false) const ok = platform({ operatorQdrant: () => ({ url: "http://qdrant:6333", apiKey: "secret-key" }) }) const enabled = await enableDocumentAi(deps(data, ok), scope) expect(enabled.source).toBe("operator") expect(enabled.url).toBe("http://qdrant:6333") // The key never lands in the configuration row. const rows = await data .forScope(scope) .of((await import("../contract/index.js")).config) .list({ limit: 1 }) expect(JSON.stringify(rows.items[0])).not.toContain("secret-key") }) 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("vectors") 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) }) })