glp-companion/docs/architecture.md

17 KiB

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.

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:

<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:

                        ┌────────────────────────────────────┐
                        │      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.

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:

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

               ┌────────────────────────────────────────────────────────┐
               │           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:

// 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):

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:

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.