// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // The committed kernel schema, and the rule that keeps it committable. // // `migrations/postgres/0001_kernel.sql` is `schemaStatements()` over the kernel's own entities, // written once. It is a snapshot of the *kernel's* tables alone, not of the whole registry, so // adding a module does not change this file -- a module ships its own numbered migration, which // is what a forward-only runner needs (it refuses a migration whose text changed after it ran). // A kit upgrade that changes a kernel table does change it, and that is exactly the moment a // customer has to see a new migration in review. import { authModule } from "@conusai-kit/auth" import { buildRegistry } from "@conusai-kit/core" import { entitiesOf } from "@conusai-kit/data" import { schemaStatements } from "@conusai-kit/data-kysely" import { KIT_JOBS_ENTITIES } from "@conusai-kit/jobs-pgboss" import { appUserIdentities, tenancyModule } from "@conusai-kit/tenancy" import { describe, expect, it } from "vitest" import { kernelSchema } from "../apps/worker/src/migrations.js" import { SPDX_LINE } from "../scripts/licence.mjs" // Tenancy and sign-in alone: later kit tables have their own forward migrations, because 0001 is // never edited once it has run. app_user_identity belongs to 0006, not this historical snapshot. const kernelEntities = [ ...entitiesOf(buildRegistry([tenancyModule, authModule]), "postgres"), ...KIT_JOBS_ENTITIES, ].filter((entity) => entity.table !== appUserIdentities.table) describe("the kernel migration", () => { it("matches the committed 0001_kernel.sql", async () => { // The file leads with the template's SPDX line (AT5.1); the runner reads it as the comment it is. await expect(`-- ${SPDX_LINE}\n${kernelSchema(kernelEntities)}`).toMatchFileSnapshot( "../migrations/postgres/0001_kernel.sql", ) }) it("puts forced row-level security on every tenant table", () => { const sql = schemaStatements(kernelEntities).join(";\n") for (const entity of kernelEntities) { if (entity.tenancy === "global") continue expect(sql, `${entity.table} is not forced`).toContain(`alter table "${entity.table}" force row level security`) expect(sql).toContain(`create policy "${entity.table}_tenant" on "${entity.table}"`) } }) it("compares a tenant row against the transaction's organization and nothing else", () => { const sql = schemaStatements(kernelEntities).join(";\n") // The policy reads NULLIF(current_setting(...), '')::uuid: a pooled connection whose previous // transaction set app.org_id sees no rows rather than an error (kit-data-kysely's decision 2). expect(sql).toContain("nullif(current_setting('app.org_id', true), '')::uuid") }) })