50 lines
2.7 KiB
TypeScript
50 lines
2.7 KiB
TypeScript
// The module's migrations are its own files, each exactly `schemaStatements()` over the entities it
|
|
// added (decision AT-D20: the entity definition is the one source of a column). Forward-only: the
|
|
// first file stays the ledger's as first shipped, the revocation outbox is the second, and the
|
|
// ledger's step record (`steps`, `provider`) is the third, two added columns. All global tables: an
|
|
// account and an app session belong to no organization, so they carry no tenant column and no policy.
|
|
|
|
import { readFileSync } from "node:fs"
|
|
import { schemaStatements } from "@conusai-kit/data-kysely"
|
|
import { describe, expect, it } from "vitest"
|
|
import { ACCOUNT_ENTITIES, accountDeletions, accountModule, accountSessionRevocations } from "../index.js"
|
|
|
|
function tablesOf(entities: Parameters<typeof schemaStatements>[0]): string {
|
|
const kernel = schemaStatements([]).length
|
|
return `${schemaStatements(entities)
|
|
.slice(kernel)
|
|
.map((statement) => `${statement};`)
|
|
.join("\n\n")}\n`
|
|
}
|
|
|
|
describe("the migration of the account module", () => {
|
|
const migration = (name: string) => readFileSync(new URL(`../migrations/${name}`, import.meta.url), "utf8")
|
|
|
|
// A migration that has run is never edited: the columns added since are a file of their own, and
|
|
// the files together are exactly the entity.
|
|
it("is its own file, the ledger table as first shipped, and a third file adds the step record", () => {
|
|
const added = ',\n "steps" jsonb,\n "provider" text\n'
|
|
const generated = tablesOf([accountDeletions])
|
|
expect(generated).toContain(added)
|
|
expect(generated.replace(added, "\n")).toBe(migration("0001_account.sql"))
|
|
expect(migration("0003_deletion_steps.sql")).toBe(
|
|
'alter table "account_deletion" add column "steps" jsonb;\n\nalter table "account_deletion" add column "provider" text;\n',
|
|
)
|
|
})
|
|
|
|
it("adds the revocation outbox in a second file, exactly its table", async () => {
|
|
await expect(tablesOf([accountSessionRevocations])).toMatchFileSnapshot("../migrations/0002_session_revocation.sql")
|
|
expect(ACCOUNT_ENTITIES).toEqual([accountDeletions, accountSessionRevocations])
|
|
const sql = readFileSync(new URL("../migrations/0002_session_revocation.sql", import.meta.url), "utf8")
|
|
expect(sql).not.toContain("org_id")
|
|
})
|
|
|
|
it("is declared by the manifest for Postgres; on Convex the schema comes from the same entities", () => {
|
|
expect(accountModule.migrations).toEqual({ postgres: "migrations" })
|
|
expect(accountModule.profiles).toEqual(["postgres", "convex"])
|
|
const sql = readFileSync(new URL("../migrations/0001_account.sql", import.meta.url), "utf8")
|
|
expect(sql).toContain('create table "account_deletion"')
|
|
expect(sql).not.toContain("org_id")
|
|
})
|
|
})
|