feat(documents): add inbound clinical-document data model (migration 0218)

Store an uploaded doctor report / discharge letter and stage extracted
structured facts for review. Two models:

- InboundDocument: the uploaded document, raw bytes encrypted at rest via
  the shared AES-256-GCM Bytes codec (content_encrypted), with queryable
  metadata (kind, mime, size, status, report date).
- ExtractedFact: the review-then-confirm staging row — fact type, status,
  per-field provenance, a confidence score, and a needs-review gate, plus
  the FHIR-staged payload (stated codes/status only) as JSONB.

Wire content_encrypted into the encryption-key rotation registry and the
rotation script so a key drop never strands a stored document.
This commit is contained in:
Marc-André Bombeck committed 2026-06-28 16:56:54 +02:00
1 parent 2563690e4b
commit 5280c183bd
4 files changed
+294

No files matched your search

+6
View File
@@ -173,6 +173,12 @@ export const ENCRYPTED_COLUMNS: readonly EncryptedColumn[] = [
{ model: "Allergy", field: "reactionEncrypted", kind: "bytes" },
{ model: "Allergy", field: "notesEncrypted", kind: "bytes" },
{ model: "FamilyHistoryEntry", field: "notesEncrypted", kind: "bytes" },
// ───── v1.25 (W-DOCS-IN) inbound clinical document (Bytes column) ─────
// The raw uploaded doctor report / discharge letter, base64-of-binary →
// AES-256-GCM string → UTF-8 bytes. The most sensitive blob in the wave
// (a full clinical document); never logged, never in wide-event meta.
{ model: "InboundDocument", field: "contentEncrypted", kind: "bytes" },
] as const;
/** Stable `Model.field` key for a registry entry. */