Files
rely/docs/ARCHITECTURE.md
Rijad Zuzo d80486b25e
Flutter CI / analyze_and_test (push) Has been cancelled
Add maintainer onboarding documentation
2026-07-03 12:44:15 +02:00

124 lines
4.0 KiB
Markdown

# Architecture
## High-Level Shape
The app is mid-migration to vertical slices.
```text
lib/
main.dart
app/ app bootstrap, shell, aggregate repository/state
core/ cross-cutting config, auth, networking, LLM, theme
features/ product slices
integrations/ backend gateway contracts and transport models
```
Canonical feature structure:
```text
lib/features/<slice>/
domain/ models and pure rules
application/ orchestration, providers, side effects
presentation/ screens, widgets, dialogs, UI state
data/ slice-owned persistence or adapters, when needed
```
Many files at `lib/features/<slice>/<name>.dart` are compatibility exports.
New implementation should go into the canonical subfolders.
## Runtime Flow
1. `lib/main.dart` initializes Flutter, Sentry/Bugsink, Workmanager, local
notifications, Hive, and Riverpod.
2. `RelationshipSaverApp` wires auth gates, share listeners, notification
listeners, and global app listeners.
3. `AppShell` owns responsive navigation between Dashboard, People, Moments,
Ideas, Reminders, Signals, Sync, and Settings.
4. `LocalRepository` exposes the aggregate `LocalDataState`.
5. Feature views read state through Riverpod providers and call repository
operations.
6. Repository writes persist state, reconcile reminder schedules, and enqueue
sync envelopes where applicable.
## State And Persistence Boundary
`LocalDataState` is the primary local aggregate. It contains:
- people
- moments
- ideas
- reminders
- dashboard tasks
- source links
- shared messages
- share inbox
- person facts
- important dates
- preference signals
- AI suggestion drafts
Most product writes should pass through `LocalRepository` because it handles:
- local state update
- persistent storage write
- reminder schedule reconciliation
- sync queue enqueue
- derived side effects such as preference extraction
The sync queue is intentionally separate from the product aggregate and lives in
`SyncQueueRepository`.
## Important Providers
| Provider | Purpose |
| --- | --- |
| `localRepositoryProvider` | primary local product state and write boundary |
| `syncQueueRepositoryProvider` | pending outbound sync mutations and sync status |
| `backendGatewayProvider` | fake vs REST backend transport selection |
| `sessionControllerProvider` | fake/REST auth session lifecycle |
| `llmConfigProvider` | LLM provider, endpoint, model, and API key state |
| `llmDigestConfigProvider` | digest cadence and grounding policy |
| `reminderSchedulerProvider` | local notification scheduler abstraction |
## Design Decisions
### Local-first aggregate first
The app persists one aggregate snapshot for product state. This is simple,
offline-safe, and pragmatic for a prototype. It also means entity-level
migrations and partial writes need care.
### Feature-owned models
Even though storage is aggregate-based, models live with features. This keeps
the migration toward vertical slices open without forcing a storage rewrite.
### Fake backend by default
Fake backend mode must stay stable because the product is not yet backend
dependent. REST transport exists behind `BackendGatewayRest`.
### Inbox-first share capture
Share intake should prefer user review when identity evidence is weak. A wrong
automatic profile match is more damaging than an extra inbox step.
### Pseudonymous AI digest
Scheduled digest prompts use person tokens and safe summaries. Identifying
details stay local. Share timestamps can be included as temporal evidence, but
raw shared text and sender identity should not be sent.
### Local notifications as best effort
Reminder and digest notifications should not block local data writes. Scheduler
errors are intentionally swallowed at the repository boundary.
## Cross-Cutting Rules
- Keep `AppConfig` flags as build-time `--dart-define` friendly values.
- Add tests around parsing, local repository state changes, and prompt payload
shape when changing sensitive flows.
- Keep docs aligned with verified code, especially native share and background
behavior.