// The module's migrations are its own files, each exactly `schemaStatements()` over the entities it adds // (decision AT-D20: the entity definitions are the one source of a column). The module ships the // Postgres profile; the Convex binding is provided for the integration owner and has no SQL. import { readFileSync } from "node:fs" import { schemaStatements } from "@conusai-kit/data-kysely" import { describe, expect, it } from "vitest" import { autoIndex, KNOWLEDGE_ENTITIES, KNOWLEDGE_ENTITIES_V1, knowledgeModule, passageSets } from "../index.js" /** The statements for these tables alone: `schemaStatements` leads with the kernel's own two. */ function tablesOf(entities: Parameters[0]): string { const kernel = schemaStatements([]).length return `${schemaStatements(entities) .slice(kernel) .map((statement) => `${statement};`) .join("\n\n")}\n` } describe("the migration of the knowledge module", () => { it("is its own file, exactly its three tables as first shipped", async () => { await expect( `-- SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0\n${tablesOf(KNOWLEDGE_ENTITIES_V1)}`, ).toMatchFileSnapshot("../migrations/0001_knowledge.sql") }) it("adds the auto-index opt-in in the second file, exactly its table", async () => { await expect( `-- SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0\n${tablesOf([autoIndex])}`, ).toMatchFileSnapshot("../migrations/0002_knowledge_auto_index.sql") }) it("adds the PDF intake's passage record in the third file, exactly its table", async () => { await expect( `-- SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0\n${tablesOf([passageSets])}`, ).toMatchFileSnapshot("../migrations/0003_knowledge_passage_set.sql") expect(KNOWLEDGE_ENTITIES).toEqual([...KNOWLEDGE_ENTITIES_V1, autoIndex, passageSets]) }) it("is declared by the manifest, so the migrate job finds it, and every table is row-level secured", () => { expect(knowledgeModule.migrations).toEqual({ postgres: "migrations" }) expect(knowledgeModule.profiles).toEqual(["postgres"]) const sql = ["0001_knowledge.sql", "0002_knowledge_auto_index.sql", "0003_knowledge_passage_set.sql"] .map((file) => readFileSync(new URL(`../migrations/${file}`, import.meta.url), "utf8")) .join("\n") for (const table of [ "knowledge_collection", "knowledge_document", "knowledge_config", "knowledge_auto_index", "knowledge_passage_set", ]) { expect(sql).toContain(`create table "${table}"`) expect(sql).toContain(`alter table "${table}" force row level security`) } }) })