# Setup ## Backend Base URL Build-time (recommended): ```bash flutter run --dart-define=BACKEND_BASE_URL=https://api.example.com ``` Runtime override (for future settings screens): ```dart AppConfig.overrideBackendBaseUrl('https://staging.example.com'); ``` ## Run With Fake Gateway Use fake gateway for local/offline development: ```bash flutter run --dart-define=USE_FAKE_BACKEND=true ``` ## Background Sync Background sync (startup + resume + periodic ticks while authenticated) is disabled by default. The current product direction is backendless/local-first, so backend sync should be enabled only for REST transport development. In REST mode, auto-triggers are reachability-gated to avoid unnecessary sync attempts while offline. When connectivity returns (offline -> online), sync now triggers immediately in addition to startup/resume/periodic ticks. Control flags: ```bash flutter run \ --dart-define=ENABLE_BACKGROUND_SYNC=true \ --dart-define=BACKGROUND_SYNC_INTERVAL_SECONDS=180 ``` Disable it explicitly: ```bash flutter run --dart-define=ENABLE_BACKGROUND_SYNC=false ``` ## Reminder Delivery Scaffold Reminder scheduling is now wired through `ReminderScheduler` and reconciled from `LocalRepository` on startup/state changes. Default implementation now uses local notifications runtime where supported. Control flag: ```bash flutter run --dart-define=ENABLE_LOCAL_NOTIFICATIONS=true ``` Disable notifications explicitly: ```bash flutter run --dart-define=ENABLE_LOCAL_NOTIFICATIONS=false ``` Behavior notes: - web: no-op fallback - linux: schedule fallback (no-op) due platform scheduling limitations in plugin - android/iOS/macOS/windows: scheduled local notifications - settings screen includes `Request Notification Access` action for runtime permission prompts - tapping a reminder notification opens reminder management UI in-app ## Phone-Only Private AI Digest The app can run without a production backend by keeping `USE_FAKE_BACKEND=true` and using the LLM integration for local profile extraction and private digest generation. Selected product flow: - share messages/text from WhatsApp, iMessage, Notes, Safari, or similar apps into the app - auto-match only when identity evidence is strong - keep ambiguous or low-information shares in `Share Inbox` - let the user gradually resolve inbox items over days, weeks, and months - run local/profile-building extraction opportunistically and on scheduled nightly windows when the OS allows it - run grounded weekly recommendations on request or on the configured digest schedule Backend sync is not part of this path. The fake backend is intentionally inert for sync pulls and must not seed people or other relationship records. Digest behavior: - relationship data remains local-first in the Hive/shared-preferences store - scheduled digest payloads use pseudonymous tokens such as `person_001` - names, aliases, sender names, source URLs, raw shared text, and sensitive notes are not sent in the scheduled digest prompt - repeated LLM work should be avoided by fingerprinting unresolved/new share batches and skipping extraction when the same batch has already completed - weekly recommendation prompts should include previously suggested/dismissed items so the model avoids repeats - LLM results are saved as pending AI review drafts first - accepting a draft creates a local idea, task, or reminder - dismissing a draft leaves existing local data unchanged Scheduling: - default cadence is weekly - default run window is Sunday 21:00 - default policy is Wi-Fi + charging - iOS background execution is best-effort because the OS controls exact timing - Settings includes `Run Private Digest Now` for physical-phone debug builds iOS setup now includes: - `UIBackgroundModes`: `fetch`, `processing` - `BGTaskSchedulerPermittedIdentifiers`: `com.relationshipsaver.llm.digest` - Workmanager registration in `AppDelegate.swift` Local notifications are used for the digest-ready alert. No APNs/FCM remote push payload is required. ## WhatsApp Share Intake (MVP) Inbound WhatsApp share-intake is now wired behind a listener in the authenticated app shell. Control flag: ```bash flutter run --dart-define=ENABLE_WHATSAPP_SHARE_INTAKE=true ``` Disable explicitly: ```bash flutter run --dart-define=ENABLE_WHATSAPP_SHARE_INTAKE=false ``` Behavior notes: - iOS/Android: integrates with share-intent plugin (`receive_sharing_intent`) - shared text is parsed and ingested into: - person profile (auto-create when identity is confident) - source->profile link map for follow-up matching - moment history (`type=whatsapp`) - ambiguous or missing-identity shares are queued in `Share Inbox` for manual resolution - near-name conflicts now also route to `Share Inbox` to avoid accidental profile mismatches - follow-up routing prefers stable source fingerprint matching (when source user/thread IDs are available) - Share Inbox now provides a `Review & Match` conflict flow with candidate confidence scoring and side-by-side preview before confirming profile link - app launch from initial share intent auto-opens the relevant destination: - resolved import -> `People` with imported profile selected - unresolved import -> `Share Inbox` - Settings includes: - `Simulate WhatsApp Share` for local/dev testing - `Open Share Inbox` to resolve queued items People view includes `Merge duplicates` action for resolving duplicate profile records after import. ## Local Persistence Backend Default local store: - `Hive` (`USE_HIVE_LOCAL_DB=true` by default) - first-run migration imports legacy `shared_preferences` payload when present - applies to both: - local product state (`LocalRepository`) - sync queue state (`SyncQueueRepository`) Optional migration path: ```bash flutter run --dart-define=USE_HIVE_LOCAL_DB=true ``` Use legacy mode explicitly if needed: ```bash flutter run --dart-define=USE_HIVE_LOCAL_DB=false ``` ## Run Tests ```bash flutter test ``` ## Generate Code ```bash dart run build_runner build --delete-conflicting-outputs ```