Files
HealthLog/prisma/migrations/0227_document_vault/migration.sql
T
Marc-André Bombeck 7f1cd575f4 feat(documents): add the vault data model (migration 0227)
REFERRAL joins the document-kind enum (Überweisung — LOINC 57133-1 / ePA
ANF). inbound_documents gains content_sha256 (plaintext hash for same-user
duplicate detection; pre-existing rows stay NULL) and content_codec
(base64v1 legacy string codec | binary2 binary codec, explicit column —
never header-sniffed), plus a partial unique index that allows at most one
LIVE row per (user_id, content_sha256) so a tombstoned document never
blocks a re-upload.

document_condition_links is the m:n join between a document and an
illness/condition episode (a discharge letter legitimately touches two
conditions); both sides cascade. app_settings carries the two admin-tunable
limits (per-file cap, default 25 MiB; per-user quota, default 1 GiB) and
users the nullable per-user quota override.

Task: W1-T1.
2026-07-07 11:04:31 +02:00

79 lines
3.3 KiB
SQL

-- Document vault: re-enable the parked inbound-documents module with the
-- hardened storage contract.
--
-- 1. `inbound_document_kind` gains REFERRAL (Überweisung — clean LOINC
-- 57133-1 / ePA ANF mapping).
-- 2. `inbound_documents` gains `content_sha256` (lowercase hex of the
-- plaintext, for same-user duplicate detection; pre-existing rows stay
-- NULL and never dedupe) and `content_codec` ("base64v1" legacy string
-- codec | "binary2" binary codec; the default keeps existing rows
-- correct) plus a partial unique index enforcing at most one LIVE row
-- per (user_id, content_sha256).
-- 3. `document_condition_links` — m:n join between a document and an
-- illness/condition episode. Both sides cascade.
-- 4. `app_settings` gains the two admin-tunable limits (per-file cap,
-- default 25 MiB; per-user quota, default 1 GiB); `users` gains the
-- nullable per-user quota override.
--
-- Additive and idempotent-safe on an existing database; applies clean on a
-- fresh database as part of the ordered migration chain.
-- 1. Kind enum
ALTER TYPE "inbound_document_kind" ADD VALUE IF NOT EXISTS 'REFERRAL';
-- 2. Document columns + live-dedupe partial unique index
ALTER TABLE "inbound_documents"
ADD COLUMN "content_sha256" VARCHAR(64),
ADD COLUMN "content_codec" TEXT NOT NULL DEFAULT 'base64v1';
-- Partial unique index (documented in schema.prisma — Prisma cannot express
-- a partial index, so it lives here as raw SQL). Tombstoned rows are
-- excluded: a soft-deleted document must not block re-uploading the same
-- file, and restore re-enters the constraint (a conflicting restore 409s).
CREATE UNIQUE INDEX "inbound_documents_user_sha_live"
ON "inbound_documents" ("user_id", "content_sha256")
WHERE "deleted_at" IS NULL AND "content_sha256" IS NOT NULL;
-- 3. Document ⇄ condition links
CREATE TABLE "document_condition_links" (
"id" TEXT NOT NULL,
"document_id" TEXT NOT NULL,
"episode_id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "document_condition_links_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "document_condition_links_document_id_episode_id_key"
ON "document_condition_links" ("document_id", "episode_id");
CREATE INDEX "document_condition_links_episode_id_idx"
ON "document_condition_links" ("episode_id");
CREATE INDEX "document_condition_links_user_id_idx"
ON "document_condition_links" ("user_id");
ALTER TABLE "document_condition_links"
ADD CONSTRAINT "document_condition_links_document_id_fkey"
FOREIGN KEY ("document_id") REFERENCES "inbound_documents" ("id")
ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "document_condition_links"
ADD CONSTRAINT "document_condition_links_episode_id_fkey"
FOREIGN KEY ("episode_id") REFERENCES "illness_episodes" ("id")
ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "document_condition_links"
ADD CONSTRAINT "document_condition_links_user_id_fkey"
FOREIGN KEY ("user_id") REFERENCES "users" ("id")
ON DELETE CASCADE ON UPDATE CASCADE;
-- 4. Admin limits
ALTER TABLE "app_settings"
ADD COLUMN "document_max_file_bytes" INTEGER NOT NULL DEFAULT 26214400,
ADD COLUMN "document_quota_bytes" BIGINT NOT NULL DEFAULT 1073741824;
ALTER TABLE "users"
ADD COLUMN "document_quota_bytes" BIGINT;