Files
rely/docs/SETUP.md
T
2026-05-19 19:17:35 +02:00

6.8 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');

Bugsink Error Tracking

Release builds initialize sentry_flutter with the project Bugsink DSN by default. Bugsink is Sentry API compatible, so the app uses the normal Sentry Flutter SDK.

The default DSN is:

https://97fb0a56bc35440fba0ba139dc3b1ccc@bugs.zuzo.ch/2

Override metadata at build time when needed:

flutter build apk --release \
  --dart-define=SENTRY_ENVIRONMENT=production \
  --dart-define=SENTRY_RELEASE=relationship_saver@1.0.0+1

To point a build at a different Sentry-compatible project:

flutter build apk --release \
  --dart-define=SENTRY_DSN=https://public-key@example.com/1

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

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

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)
  • iOS also ships a Save to Relationship Saver Action extension for the lower share-sheet action row; use it when that row is easier to reach than the app share row
  • 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:

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