mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
Fold six nullable columns into user_health_profiles: three closed-set enums (blood type, organ-donor status, advance-directive status) read as plaintext, and three AES-256-GCM free-text columns (emergency contacts, implants, ICE note). Migration 0331 is additive only: three CREATE TYPE plus one ALTER TABLE with nullable ADD COLUMNs. An integration test asserts the columns and enum types exist on the migrated schema.
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
/**
|
|
* Migration 0331 shape check, against the real migrated Postgres.
|
|
*
|
|
* The testcontainer applies every migration on boot, so this asserts the
|
|
* three enum types and the six nullable columns migration 0331 adds actually
|
|
* exist on the live schema. A migration that never ran, or one that named a
|
|
* column differently from the Prisma model, turns this red before any feature
|
|
* test that depends on the columns runs.
|
|
*/
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import { getPrismaClient } from "./setup";
|
|
|
|
describe("migration 0331 — emergency profile schema", () => {
|
|
it("adds the six nullable emergency columns to user_health_profiles", async () => {
|
|
const rows = await getPrismaClient().$queryRawUnsafe<
|
|
Array<{ column_name: string; is_nullable: string; data_type: string }>
|
|
>(
|
|
`SELECT column_name, is_nullable, data_type
|
|
FROM information_schema.columns
|
|
WHERE table_name = 'user_health_profiles'
|
|
AND column_name IN (
|
|
'emergency_blood_type',
|
|
'organ_donor_status',
|
|
'advance_directive_status',
|
|
'emergency_contacts_encrypted',
|
|
'emergency_implants_encrypted',
|
|
'emergency_note_encrypted'
|
|
)
|
|
ORDER BY column_name`,
|
|
);
|
|
|
|
const byName = new Map(rows.map((r) => [r.column_name, r]));
|
|
for (const col of [
|
|
"emergency_blood_type",
|
|
"organ_donor_status",
|
|
"advance_directive_status",
|
|
"emergency_contacts_encrypted",
|
|
"emergency_implants_encrypted",
|
|
"emergency_note_encrypted",
|
|
]) {
|
|
expect(byName.get(col), `${col} is missing`).toBeDefined();
|
|
expect(byName.get(col)!.is_nullable, `${col} must be nullable`).toBe(
|
|
"YES",
|
|
);
|
|
}
|
|
expect(byName.get("emergency_contacts_encrypted")!.data_type).toBe("bytea");
|
|
expect(byName.get("emergency_blood_type")!.data_type).toBe("USER-DEFINED");
|
|
});
|
|
|
|
it("creates the three emergency enum types with their members", async () => {
|
|
const rows = await getPrismaClient().$queryRawUnsafe<
|
|
Array<{ typname: string; enumlabel: string }>
|
|
>(
|
|
`SELECT t.typname, e.enumlabel
|
|
FROM pg_type t
|
|
JOIN pg_enum e ON e.enumtypid = t.oid
|
|
WHERE t.typname IN (
|
|
'emergency_blood_type',
|
|
'organ_donor_status',
|
|
'advance_directive_status'
|
|
)
|
|
ORDER BY t.typname, e.enumsortorder`,
|
|
);
|
|
|
|
const byType = new Map<string, string[]>();
|
|
for (const r of rows) {
|
|
(byType.get(r.typname) ?? byType.set(r.typname, []).get(r.typname)!).push(
|
|
r.enumlabel,
|
|
);
|
|
}
|
|
|
|
expect(byType.get("emergency_blood_type")).toEqual([
|
|
"A_POS",
|
|
"A_NEG",
|
|
"B_POS",
|
|
"B_NEG",
|
|
"AB_POS",
|
|
"AB_NEG",
|
|
"O_POS",
|
|
"O_NEG",
|
|
"UNKNOWN",
|
|
]);
|
|
expect(byType.get("organ_donor_status")).toEqual(["YES", "NO", "UNKNOWN"]);
|
|
expect(byType.get("advance_directive_status")).toEqual([
|
|
"EXISTS",
|
|
"NONE",
|
|
"UNKNOWN",
|
|
]);
|
|
});
|
|
});
|