glp-companion/docs/architecture.md

275 lines
17 KiB
Markdown

# Architectural Specification: GLP-1 Companion Platform
**Document Version:** 1.0.0
**Target Runtimes:** iOS, Android, Web (Wasm/CanvasKit), macOS, Windows
**Framework:** Flutter 3.x (Dart 3.x)
**Security & Compliance Level:** HIPAA & GDPR-Ready Tier 1 Health Application
---
## 1. System Vision & Domain Boundaries
The GLP-1 Companion is designed to address the clinical and behavioral realities of GLP-1/GIP receptor agonist pharmacotherapy (Semaglutide, Tirzepatide, Liraglutide). The architecture is structured around five core pillars:
1. **Pharmacokinetics & Dose Logistics:** Modeling dosage curves, biological half-lives, titrations, and physical injection site rotation.
2. **Lean Mass Preservation:** Monitoring protein intake targets and hydration volumes to mitigate muscle atrophy and kidney/GI adverse events.
3. **Recipe Scraping & Pantry Ingestion:** De-duplicating grocery overhead via automated microdata extraction and local inventory delta checks.
4. **Decoupled Biometric Ingestion:** Unifying OS-native health ecosystems (HealthKit, Health Connect) with cloud APIs (MyFitnessPal, Withings) across mobile, desktop, and web.
5. **Zero-Knowledge / High-Privacy Local Persistence:** End-to-end encrypted local databases (SQLCipher) paired with passwordless federated authentication.
---
## 2. Architectural Paradigm: Feature-First Clean Architecture
The platform rejects monolithic and layered-by-technical-type layouts in favor of **Bounded Contexts (Feature-First Clean Architecture)**. Each business domain operates as an autonomous module.
```text
lib/
├── app/ # Top-level application bootstrap
│ ├── app.dart # Multiplatform root widget
│ ├── observers/ # Routing & state lifecycle observers
│ └── router/ # GoRouter route declarations & redirect guards
├── core/ # Shared foundation & cross-cutting concerns
│ ├── error/ # Failures, exceptions, and error boundary handlers
│ ├── network/ # HTTP/REST clients, retry policies, TLS pinning
│ ├── platform/ # Abstract hardware & OS platform wrappers
│ ├── security/ # SQLCipher key generation, biometric locks, keychain
│ ├── theme/ # Dynamic Material 3 & Apple Cupertino theme engines
│ └── utils/ # DateTime calculations, pharmacokinetics math, formatters
└── features/ # Modular business domains
├── auth/ # Passwordless, OAuth SSO, passkey integration
├── medication/ # Titration tracking, dose logging, injection rotation
├── nutrition/ # Micro/macro logs, protein density, hydration
├── recipes/ # Schema.org JSON-LD web scraper, recipe catalog
├── meal_planner/ # Weekly calendar, portion scaler
├── pantry/ # Food inventory, expiration date manager
└── health_sync/ # HealthKit, Health Connect, MFP abstraction
```
### Clean Architecture Layers per Feature
Within each feature module in `lib/features/<feature_name>/`, separation of concerns is strictly enforced:
```text
<feature_name>/
├── domain/ # Pure Dart - ZERO external framework imports
│ ├── entities/ # Immutable domain business objects
│ ├── value_objects/ # Validated value types (e.g., DosageMg, ProteinTarget)
│ ├── repositories/ # Abstract repository interfaces
│ └── usecases/ # Isolated business operations (single responsibility)
├── data/ # Infrastructure & data persistence
│ ├── datasources/
│ │ ├── local/ # Drift tables, secure key-value stores
│ │ └── remote/ # Supabase REST, GraphQL, third-party APIs
│ ├── models/ # Data Transfer Objects (DTOs), JSON serialization
│ └── repositories/ # Concrete repository implementations
└── presentation/ # UI & State management
├── controllers/ # Riverpod AsyncNotifiers / StateNotifiers
├── screens/ # Responsive top-level views
└── widgets/ # Reusable components (Adaptive Dialogs, Pickers, Cards)
```
---
## 3. Technology Stack & Multiplatform Dependencies
| Capability | Selection | Rationale |
|---|---|---|
| **Core UI Framework** | Flutter 3.x (Dart 3.x) | Native AOT compilation on iOS, Android, macOS, and Windows; CanvasKit/Wasm rendering on Web. |
| **State Management** | Riverpod 2.x (`riverpod_generator`) | Compile-time safe dependency injection, automatic provider disposal, testability without `BuildContext`. |
| **Navigation & Deep Linking** | `go_router` 14.x | Declarative routing, browser URL synchronizer, deep linking for dose alerts and magic links. |
| **Encrypted Database** | `drift` + `sqlcipher_flutter_libs` | Type-safe reactive SQLite interface with AES-256 transparent database encryption at rest. |
| **Secure Vault** | `flutter_secure_storage` | OS-native credential storage: Apple Keychain, Android EncryptedSharedPreferences, Windows Credential Manager, Linux Secret Service. |
| **Backend & Identity** | Supabase (PostgreSQL + RLS + GoTrue) | Built-in passwordless authentication, OAuth provider support, Row-Level Security, Edge Functions. |
| **Recipe Scraping** | Dart `html` parser + Supabase Edge Node | Client-side parsing of `application/ld+json` Schema.org/Recipe with cloud fallback for bot-protected sites. |
| **Platform Health Sync** | `health` package (Mobile) + OAuth REST (Web/Desktop) | Unified interface isolating native HealthKit/Health Connect from cross-platform desktop/web code. |
| **Push Notifications** | `flutter_local_notifications` | Cross-platform offline-scheduled alerts for injections and hydration checks. |
---
## 4. Multiplatform UX/UI Adaptation Engine
The UI layer implements an **Adaptive Design Strategy** rather than a lowest common denominator approach:
```text
┌────────────────────────────────────┐
│ Platform Theme Director │
└─────────────────┬──────────────────┘
│
┌───────────────────────┴───────────────────────┐
▼ ▼
[Apple: iOS & macOS] [Material: Android, Web, Win]
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ Cupertino Engine │ │ Material 3 Engine │
│ • CupertinoNavigationBar │ │ • NavigationRail / NavigationBar│
│ • CupertinoSliverRefreshControl │ │ • FloatingActionButtons │
│ • SF Pro System Typography │ │ • Roboto / Adaptive Font Scaler │
│ • Haptic Feedback & Swipe-Back │ │ • Dynamic Color / ColorScheme │
└─────────────────────────────────┘ └─────────────────────────────────┘
```
### Breakpoint Matrix
- **Compact (< 600dp - Mobile):** Bottom `CupertinoTabBar` or `NavigationBar`. Full-screen sheets for dose logging.
- **Medium (600dp - 1024dp - Foldables / Tablets):** Persistent navigation rail, split-view list/detail pane for recipe browsing and pantry audits.
- **Expanded (> 1024dp - Desktop / Web):** Multi-column dashboard, persistent sidebar navigation rail, keyboard shortcuts (e.g., `Cmd/Ctrl + N` for quick food logging), modal popovers rather than full-screen sheets.
---
## 5. Security & Passwordless Authentication Architecture
Password-based login is explicitly deprecated to eliminate credential-stuffing vectors and streamline onboarding.
```text
User Device Supabase Auth Gateway OAuth Identity Provider
│ │ │
├─── Selects Provider ───────────┼───────────────────────────────────>│ (Apple / Google / MS)
│ (Apple/Google/Microsoft) │ │
│<── Returns Auth Token/Nonce ───┼────────────────────────────────────┤
│ │ │
├─── Exchange Nonce / Verify ───>│ │
│<── Issue JWT + Refresh Token ──┤ │
│ │ │
│─── Or Request Magic Link ─────>│ │
│ (Email OTP / Deep Link) ├───── Dispatches Secure Link ──────>│ (User Email Box)
│<── Deep Link Activated ────────┤ │
│ │ │
└─── Store Session in Keychain ──┴────────────────────────────────────┘
```
### Zero-Knowledge Local Storage Scheme
Local encryption relies on a three-tier lifecycle:
1. On initial app bootstrap, a cryptographic salt and 256-bit AES master key are generated via `core/security/crypto_manager.dart`.
2. The master key is committed directly to the platform hardware vault.
3. The SQLCipher SQLite instance initializes using this hardware-backed key.
Platform vault targets:
- **iOS / macOS:** Apple Keychain Services (`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`)
- **Android:** Android KeyStore backing `EncryptedSharedPreferences` (AES-256 GCM)
- **Windows:** Windows Data Protection API (DPAPI / Credential Manager)
- **Web:** Ephemeral in-memory key unlocked by biometric WebAuthn / session credentials
SQLCipher database initialization parameters:
```sql
PRAGMA key = 'x2C5D8F91B4E6A30C8D7E1F2A5B8C0D3E...';
PRAGMA cipher_page_size = 4096;
PRAGMA kdf_iter = 256000;
PRAGMA cipher_hmac_algorithm = HMAC_SHA512;
```
---
## 6. Pharmacokinetics & GLP-1 Tracking Engine
The `medication` feature models drug serum concentration to deliver realistic physiological insights rather than simple calendar alarms.
### Half-Life Modeling Formulation
Active serum levels are calculated using standard single-compartment open pharmacokinetic decay curves:
$$C(t) = \sum_{i=1}^{n} D_i \cdot \left(\frac{1}{2}\right)^{\frac{t - t_i}{t_{1/2}}}$$
Where:
- $D_i$ = Dose administered at timestamp $t_i$ (mg)
- $t_{1/2}$ = Elimination half-life of compound:
- **Semaglutide (Ozempic / Wegovy):** $\approx 168\text{ hours (7 days)}$
- **Tirzepatide (Mounjaro / Zepbound):** $\approx 120\text{ hours (5 days)}$
- **Liraglutide (Saxenda):** $\approx 13\text{ hours}$
- $t$ = Current evaluation timestamp
### Injection Site Rotation Matrix
To prevent lipohypertrophy, injection events map to a 12-quadrant anatomical topological matrix:
- **Abdomen:** Right Upper, Right Lower, Left Upper, Left Lower
- **Thighs:** Right Anterior/Lateral, Left Anterior/Lateral
- **Upper Arms:** Right Tricep/Lateral, Left Tricep/Lateral
Rotation alerts automatically flag and suggest the least recently utilized site.
---
## 7. Recipe Parsing & Smart Pantry Delta Engine
```text
┌────────────────────────────────────────────────────────┐
│ Web Scraping Pipeline (Recipes) │
└───────────────────────────┬────────────────────────────┘
│
1. Fetch HTML Document ───────┴───────> 2. Query <script type="application/ld+json">
│
Found Valid Schema.org/Recipe?
├── YES ──> Parse Ingredients & Macros
└── NO ──> Trigger Edge LLM Regex Fallback
│
▼
[Parsed Recipe Entity]
- Title & Yield
- Ingredient List & Units
- Protein / Carb / Fat Counts
│
▼
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Smart Pantry Delta Generator │
│ │
│ [Weekly Meal Plan] [Active Pantry Inventory] [Shopping List Engine] │
│ • 800g Chicken Breast ─── Compare ──> • 300g Chicken Breast ──────> • Add 500g Chicken │
│ • 4 Avocados ─── Compare ──> • 4 Avocados ──────> • Item Satisfied (0) │
│ • 100g Greek Yogurt ─── Compare ──> • Empty ──────> • Add 100g Greek Yog. │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
```
---
## 8. Cross-Platform Health Data Integration (`HealthGateway`)
Cross-platform parity requires an abstract interface with decoupled implementations:
```dart
// lib/core/platform/health_gateway.dart
abstract class IHealthGateway {
Future<bool> requestPermissions();
Future<List<BiometricEntry>> fetchWeightHistory({required DateTime start, required DateTime end});
Future<List<ExerciseEntry>> fetchWorkouts({required DateTime start, required DateTime end});
Future<void> pushNutritionalIntake({required NutritionalRecord record});
Stream<BiometricEntry> get realTimeWeightStream;
}
```
### Implementation Matrix
1. **iOS (`health_gateway_apple.dart`):** Wraps `HealthKit` (`HKQuantityTypeIdentifierBodyMass`, `HKQuantityTypeIdentifierActiveEnergyBurned`).
2. **Android (`health_gateway_android.dart`):** Wraps `Health Connect API` (`WeightRecord`, `ExerciseSessionRecord`).
3. **Desktop / Web (`health_gateway_cloud.dart`):** Communicates with cloud partner REST endpoints (MyFitnessPal API, Withings API, Google Fit REST) via OAuth token grants, falling back to manual entry dialogs.
---
## 9. Error Handling, Telemetry & Extensibility Architecture
### Functional Error Handling
The codebase bans throwing unhandled raw exceptions across layer boundaries. All use-cases return a functional `Result<T, Failure>` union pattern (`fpdart` / `freezed`):
```dart
typedef AsyncResult<T> = Future<Either<Failure, T>>;
```
### Modular Plugin Registration (Open-Closed Principle)
To support post-launch capabilities (e.g., continuous glucose monitor [CGM] Bluetooth LE integration, Telehealth lab panels), the app exposes a modular plugin registry:
```dart
abstract class ICompanionPlugin {
String get pluginId;
String get displayName;
Future<void> initialize(ProviderContainer container);
List<RouteBase> get pluginRoutes;
Widget buildDashboardWidget(BuildContext context);
}
```
Plugins declare isolated database tables, register their own routes into `GoRouter`, and inject dashboard summary tiles without altering the core application codebase.