# Add Months Local-first Flutter app that identifies the single behavioral change most likely to extend lifespan using hazard-based modeling. ## Quick Start ```bash flutter pub get flutter test test/risk_engine/ # 23 unit tests flutter run # Debug mode flutter run --release -d # Release build ``` ## Architecture ``` lib/ ├── main.dart # App entry, routing logic ├── theme.dart # Muted clinical color palette ├── models/ │ ├── enums.dart # Sex, SmokingStatus, AlcoholLevel, etc. │ ├── user_profile.dart # Age, sex, country, height, weight, diagnoses │ ├── behavioral_inputs.dart # Modifiable behaviors │ └── result.dart # LifespanDelta, RankedFactor, CalculationResult ├── risk_engine/ │ ├── hazard_ratios.dart # HR constants from meta-analyses │ ├── mortality_tables.dart # 50 countries → 4 mortality groups │ └── calculator.dart # Core ranking algorithm ├── screens/ │ ├── welcome_screen.dart # Onboarding │ ├── baseline_screen.dart # Demographics, BMI, conditions │ ├── behavioral_screen.dart # Modifiable factors input │ └── results_screen.dart # Dominant challenge display └── storage/ └── local_storage.dart # SQLite persistence ``` ## Core Principles 1. **Local-first**: All data on device, no cloud, no accounts, no analytics 2. **Evidence-based**: Hazard ratios from peer-reviewed meta-analyses 3. **Privacy**: Delete All Data = full wipe including encryption keys 4. **Neutral tone**: "Exposure", "Factor", "Estimated gain" — no moral language ## Risk Engine ### Hazard Ratio Model Combined HR = Smoking × Alcohol × Sleep × Activity × BMI × Driving × WorkHours Capped at 4.0 to prevent unrealistic compounding. ### Key Hazard Ratios | Factor | Level | HR | |--------|-------|-----| | Smoking | Never | 1.0 | | | Former | 1.3 | | | Current (<10/day) | 1.8 | | | Current (10-20/day) | 2.2 | | | Current (>20/day) | 2.8 | | Alcohol | None/Light | 1.0 | | | Moderate (8-14/wk) | 1.1 | | | Heavy (15-21/wk) | 1.3 | | | Very Heavy (21+/wk) | 1.6 | | Sleep | 7-8 hrs | 1.0 | | | 6-7 hrs | 1.05 | | | <6 hrs | 1.15 | | | >8 hrs | 1.10 | | | + Inconsistent | ×1.05 | | Activity | High | 1.0 | | | Moderate | 1.05 | | | Light | 1.15 | | | Sedentary | 1.4 | | BMI | 18.5-25 | 1.0 | | | 25-30 | 1.1 | | | 30-35 | 1.2 | | | 35-40 | 1.4 | | | 40+ | 1.8 | | Driving | <50 mi/wk | 1.0 | | | 50-150 | 1.02 | | | 150-300 | 1.04 | | | 300+ | 1.08 | | Work Hours | <40 | 1.0 | | | 40-55 | 1.05 | | | 55-70 | 1.15 | | | 70+ | 1.3 | ### Existing Conditions (Non-modifiable) | Condition | HR Multiplier | |-----------|---------------| | Cardiovascular | 1.5 | | Diabetes | 1.4 | | Cancer (active) | 2.0 | | COPD | 1.6 | | Hypertension | 1.2 | ### Delta Calculation ```dart // Simplified Gompertz-style approximation rawDeltaYears = baselineYears × (1 - modifiedHR/currentHR) × 0.3 // Convert to months with uncertainty range lowMonths = rawDeltaYears × 12 × 0.6 highMonths = rawDeltaYears × 12 × 1.4 ``` ### Ranking Algorithm 1. For each modifiable behavior: - Compute HR with behavior set to optimal - Calculate delta months gained 2. Sort by midpoint delta descending 3. Filter out behaviors already at optimal 4. Return ranked list with confidence levels ### Confidence Levels | Factor | Confidence | Rationale | |--------|------------|-----------| | Smoking | High | Extremely well-documented | | Alcohol (heavy) | High | Strong epidemiological data | | Physical Activity | High | Large meta-analyses | | BMI (extreme) | High | Well-established | | Sleep | Moderate | Growing evidence, some confounding | | Work Hours | Moderate | Decent studies, cultural variation | | Driving | Emerging | Harder to isolate, regional variation | ## Mortality Tables ### Country Groups | Group | LE at Birth (M) | Countries | |-------|-----------------|-----------| | A | 81 | Japan, Switzerland, Singapore, Spain, Italy, Australia, Iceland, Israel, Sweden, France, South Korea, Norway | | B | 77 | USA, UK, Germany, Canada, Netherlands, Belgium, Austria, Finland, Ireland, New Zealand, Denmark, Portugal, Czech Republic, Poland, Chile, Costa Rica, Cuba, UAE, Qatar, Taiwan | | C | 72 | China, Brazil, Mexico, Russia, Turkey, Argentina, Colombia, Thailand, Vietnam, Malaysia, Iran, Saudi Arabia, Egypt, Ukraine, Romania, Hungary, Peru, Philippines | | D | 65 | India, Indonesia, South Africa, Pakistan, Bangladesh, Nigeria, Kenya, Ghana, Ethiopia, Myanmar, Nepal, Cambodia | Female LE = Male LE + 4.5 years ### Remaining Life Expectancy ```dart // Survivors have higher LE than birth cohort suggests survivorBonus = currentAge × 0.15 // capped at 5 remainingLE = (leAtBirth - currentAge) + survivorBonus ``` ## Storage ### SQLite Schema ```sql CREATE TABLE user_data ( key TEXT PRIMARY KEY, value TEXT NOT NULL, -- JSON updated_at INTEGER NOT NULL ) ``` ### Stored Keys - `profile`: UserProfile JSON - `behaviors`: BehavioralInputs JSON - `lastResult`: CalculationResult JSON ### Delete All Data ```dart await db.delete('user_data'); // Wipes all rows ``` ## UI Theme ### Colors (Muted Clinical) ```dart primary: #4A90A4 // Muted teal primaryDark: #2D6073 primaryLight: #7BB8CC surface: #F8FAFB textPrimary: #1A2B33 textSecondary: #5A6B73 success: #4A9A7C warning: #B8934A error: #A45A5A ``` ### Typography - Headlines: SF Pro Display style, tight letter-spacing - Body: 16px, 1.5 line height - Labels: 600 weight ## Testing ```bash # Run all risk engine tests flutter test test/risk_engine/ # 23 tests covering: # - Hazard ratios for each behavior # - Mortality table lookups # - Combined HR calculation # - Ranking algorithm # - Confidence assignments # - Existing conditions impact ``` Widget tests require SQLite mocking — integration test on device. ## App Icon Generated programmatically: muted teal tree on white background. ```bash dart run tool/generate_icon.dart dart run flutter_launcher_icons ``` ## Model Versioning ```dart const modelVersion = '1.0'; ``` Stored with each calculation result. Future updates can show: "Results updated under model v1.1" ## Screen Flow ``` Welcome → Baseline → Behavioral → Results ↑ ↓ └────── Recalculate ───┘ ``` Results screen shows: - Dominant Challenge (largest gain) - Estimated Gain range (e.g., "36-60 months") - Confidence level (High/Moderate/Emerging) - Secondary factor - All other factors (if any) - Delete All Data button ## Key Design Decisions 1. **BMI is baseline only** — affects calculation but not shown as a "challenge" 2. **Cigarettes/day** — slider with haptic at 20 (one pack), max 40 3. **Country** — full dropdown (50 countries), mapped internally to groups 4. **No gamification** — no streaks, badges, or progress tracking 5. **No notifications** — user controls when to recalculate ## Dependencies ```yaml dependencies: sqflite: ^2.3.0 # Local database path: ^1.8.3 # Path utilities flutter_secure_storage: # Encryption key storage (future) dev_dependencies: flutter_launcher_icons: ^0.14.1 ``` ## Future Enhancements (Out of MVP Scope) - Partner mode (compare two profiles) - Export PDF summary - Drug use factor - Diet quality factor - Stress/mental health factor - Location-based mortality refinement - Longitudinal tracking