Software Architecture Description
| Type | Level | MID | UID | REFS | Title | Statement | Rationale | Comment |
|---|---|---|---|---|---|---|---|---|
| REQUIREMENT | 1 | ARCH-001 | Parents: Children: | Local persistence subsystem |
The local persistence subsystem owns the application's local database — a SQLite file encrypted at rest via SQLCipher, located under the configured AppData path — applies schema migrations via Drift on first open, and exposes a typed API to the application layer for the clinic, patient, and recording domain entities. |
Hexagonal layer realising the broader local persistence concern. Encapsulates file lifecycle, encryption (SQLCipher), schema migration (Drift), and the typed domain-API contract — keeps the rest of the application unaware of storage details. |
||
| REQUIREMENT | 2 | ARCH-002 | Parents: Children: | Local database encryption |
The local SQLite database is encrypted on disk via the SQLCipher extension. The encryption key is held by flutter_secure_storage, which on Windows persists it as an entry in a DPAPI-encrypted file (flutter_secure_storage.dat) under the user's local app-data directory. On application bootstrap, the key is retrieved from secure storage and generated-and-persisted on first launch if absent. On every database connection open, the database connection service applies the key as the first statement (PRAGMA key) before any other operation; SQLCipher then transparently encrypts and decrypts SQLite pages. |
Page-level encryption via SQLCipher avoids per-record encryption logic in application code. Holding the key in flutter_secure_storage (rather than alongside the database file) ensures a copy of the database file alone cannot be opened. Bootstrap-time key generation lets the application be self-installing on a fresh workstation without a manual setup step. |