BioFlow Requirements
Software Architecture Description

Software Architecture Description

UID: DOC-ARCH
ARCH-001
reviewed 1. Local persistence subsystem
UID: ARCH-001
RELATIONS (Parent): RELATIONS (Child):
STATEMENT:

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.

RATIONALE:

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.

TYPE:

subsystem

SAFETY_CLASS:

B

ACTIVE:

true

REVIEWED_HASH:

1910b72998ec774f37586ae58434e21b6689aab3a07dcda6d78d70caf0cdf592

REVIEWED_BY:

@DougYoungberg

ARCH-002
unreviewed 2. Local database encryption
UID: ARCH-002
RELATIONS (Parent): RELATIONS (Child):
STATEMENT:

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.

RATIONALE:

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.

TYPE:

data

ACTIVE:

true