Skip to content

05. Database

Nicolás Baier Quezada edited this page Jun 5, 2026 · 3 revisions

05. Database

DIRD+ stores all clinical data in a local SQLite database, encrypted at rest with SQLCipher (AES-256). The encryption key is derived from the application password with Argon2id (OWASP 2025 parameters) and passed to SQLCipher as a raw key (PRAGMA key = x'…'), bypassing SQLCipher's internal PBKDF2.

  • Rust side: src-tauri/src/db.rs (via rusqlite, feature bundled-sqlcipher-vendored-openssl).
  • Frontend access layer: src/lib/db-sql/ — a thin TableShim per table, column ↔ object mappers, and a one-time migrator.
  • Schema: src-tauri/migrations/0001_init.sql.

Tables

Table Key fields Purpose
patients patientId, name, diabetes (type/duration), HTN, dyslipidemia, medications Demographics & clinical data
sessions patientId, date, modelVersions, locked, type (normal/combined) Clinical visits
images sessionId, eyeType (OD/OI), originalBlob, order Fundus images
detections imageId, type (ai/manual), bbox, class, confidence Lesion bounding boxes
segmentations imageId, type (ai/manual), maskData, class, opacity Segmentation masks
imageClassifications imageId, severity, guideline, treatments[], followupDays, urgency, rationale, manuallyModified Per-guideline DR classification
reports sessionId, type (preview/final), pdfBlob, evaluatorNotes, conclusionEdited Generated PDF reports
measurements imageId, origin, destination, distancePixels, distanceDD Calibrated measurements

(8 tables. The former pending_contributions table was removed with the data-sharing subsystem.)

Migration from older installs

Installations created before the SQLite swap used Dexie / IndexedDB (src/lib/db/schema.ts). On upgrade, a one-time migration:

  1. Backs up the existing data to a .dird container first.
  2. Copies every table from IndexedDB into the SQLite database (src/lib/db-sql/migrator.ts).
  3. Marks completion idempotently via meta.migrated_from, so it never runs twice.

The legacy Dexie schema is kept only for this migration path; new installs go straight to SQLite.

Reactivity

The frontend reads the database through a useLiveQuery shim (src/lib/db-sql) that re-runs queries when the underlying tables change, keeping the UI in sync without manual refresh.

Clone this wiki locally