This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
// 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")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user