mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 14:40:52 +00:00
Directions such as "30 to 60 minutes before food" had nowhere to go: a medication carried no free text of its own, only the notes on a dose change or a course. The medication now has one note, edited on the last step of the wizard and shown under the name on the detail page, above the dose actions on both card variants, under the picked medication in the log-dose sheet, and per row in the take-all-due list. One MedicationNote component renders it everywhere, in foreground text. The note is sealed at rest in Medication.noteEncrypted (migration 0498_medication_note, lock-bounded), with no plaintext column. Create and update take an optional `note`: trimmed, at most 500 characters, an empty string or null clears it, absent keeps it. The wizard sends it on an edit only when it changed, so an unrelated save never clears it. The list and detail reads strip the ciphertext and answer `note`. Both ends of the data path carry it: the backup (decrypted in a portable file, ciphertext in a disaster-recovery file), the restore, the data export, the key-rotation registry and script, and the MCP medication schedule, resources and fetch, fenced as user text. The doctor report and the FHIR export leave it out: it is the person's own reminder, and the report has no selection for personal prose. The size baselines rise by the one-line wiring of the field in the medication page, detail tabs, cards, log-dose sheet, wizard step and list read; the wizard payload grows by the field's own encode and hydrate.
prisma/
The database layer. HealthLog runs on PostgreSQL 18 (the compose default) or 16 via Prisma 7. This directory holds the single schema file and the forward-only migration history; the generated client is emitted elsewhere.
Contents
schema.prisma— 61 models, one file.cuid()primary keys,snake_casecolumns via@map(...), encrypted columns mostly suffixed*Encrypted(search the file; there are 24 encrypted column references). Thegenerator clientblock emits to../src/generated/prisma(imported as@/generated/prisma).migrations/— numbered, forward-only SQL migrations (0001_…upward).migration_lock.tomlpins the provider topostgresql.
Migration workflow
# author a migration from a schema edit
pnpm dlx prisma migrate dev --name <short_snake_case_name>
# regenerate the client after any schema change
pnpm dlx prisma generate
Number a new migration with the next free prefix. The production entrypoint runs prisma migrate deploy on boot, so every migration must apply cleanly forward — there is no down-migration path. Always include the migration file in the same change as the schema edit.
Conventions
- Encryption is fail-closed:
*Encryptedcolumns are written through@/lib/crypto(AES-256-GCM, versioned key ids); never store plaintext in an encrypted column. Key rotation isscripts/rotate-encryption-key.ts+docs/ops/encryption-key-rotation.md. - The generated client under
src/generated/prismais build output — do not edit it. - Schema-touching changes that affect the API surface must regenerate
docs/api/openapi.yaml(pnpm openapi:generate; CI fails on drift).
Related: ../src/lib/README.md (db.ts, rollups/), ../docs/ops/ (migrations + backup runbooks).