Migrate app code into canonical feature slices, add phone-only AI digest scheduling and review, wire local notification/background task support, and cover the flow with tests.
4.9 KiB
Setup
Backend Base URL
Build-time (recommended):
flutter run --dart-define=BACKEND_BASE_URL=https://api.example.com
Runtime override (for future settings screens):
AppConfig.overrideBackendBaseUrl('https://staging.example.com');
Run With Fake Gateway
Use fake gateway for local/offline development:
flutter run --dart-define=USE_FAKE_BACKEND=true
Background Sync
Background sync (startup + resume + periodic ticks while authenticated) is enabled by default.
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:
flutter run \
--dart-define=ENABLE_BACKGROUND_SYNC=true \
--dart-define=BACKGROUND_SYNC_INTERVAL_SECONDS=180
Disable it explicitly:
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:
flutter run --dart-define=ENABLE_LOCAL_NOTIFICATIONS=true
Disable notifications explicitly:
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 Accessaction 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 only for a private weekly digest.
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
- 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 Nowfor physical-phone debug builds
iOS setup now includes:
UIBackgroundModes:fetch,processingBGTaskSchedulerPermittedIdentifiers: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:
flutter run --dart-define=ENABLE_WHATSAPP_SHARE_INTAKE=true
Disable explicitly:
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 Inboxfor manual resolution - near-name conflicts now also route to
Share Inboxto 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 & Matchconflict 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 ->
Peoplewith imported profile selected - unresolved import ->
Share Inbox
- resolved import ->
- Settings includes:
Simulate WhatsApp Sharefor local/dev testingOpen Share Inboxto 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=trueby default)- first-run migration imports legacy
shared_preferencespayload when present - applies to both:
- local product state (
LocalRepository) - sync queue state (
SyncQueueRepository)
- local product state (
Optional migration path:
flutter run --dart-define=USE_HIVE_LOCAL_DB=true
Use legacy mode explicitly if needed:
flutter run --dart-define=USE_HIVE_LOCAL_DB=false
Run Tests
flutter test
Generate Code
dart run build_runner build --delete-conflicting-outputs