docs: add project orientation notes

This commit is contained in:
Rijad Zuzo
2026-05-17 00:17:03 +02:00
parent 6c4a139448
commit dab50abf0e
6 changed files with 701 additions and 12 deletions
+139
View File
@@ -0,0 +1,139 @@
# Client Audit: Relationship Assistant App
Date: 2026-04-01
## Current implementation summary
The client is a Flutter app using Riverpod for state management and a single
`MaterialApp` rooted at `lib/main.dart`. Authenticated users land in a custom
shell with index-based navigation across dashboard, people, moments, signals,
ideas, reminders, sync, and settings.
The app is already local-first in practice. Product state lives in
`LocalRepository` and is persisted through a `LocalDataStore` abstraction with
Hive as the default backend and shared preferences as a fallback/migration
path. There is also background sync scaffolding, notification scheduling, and a
fake backend mode for offline development.
Share intake exists, but the implementation is narrow. Flutter-side logic
supports a WhatsApp-oriented share parser, source-link resolution, and a manual
share inbox. Native platform wiring is incomplete for production-grade cross-app
sharing, especially on iOS and likely also on Android for text share intents.
## A. Current implementation inventory
| Feature Area | Current State |
| --- | --- |
| Client technology | Flutter |
| State management | Riverpod (`Notifier`, `AsyncNotifier`, provider overrides in tests) |
| Navigation | Single `MaterialApp`, custom shell, route pushes for secondary flows |
| Local persistence | Hive by default, shared preferences fallback/migration |
| Auth | Local/fake-friendly sign-in flow with token-store abstractions |
| People list/detail | Implemented, responsive, searchable, editable |
| Person creation/editing | Implemented with validation and duplicate-name warning |
| Notes/profile context | Implemented as a single freeform notes field plus tags |
| Moments/captures | Implemented |
| Ideas | Implemented |
| Reminders | Implemented with local notification scaffold |
| Shared message history | Implemented per profile |
| Share intake | Implemented in Flutter, but WhatsApp-specific and not fully generalized |
| Share inbox | Implemented for unresolved profile matching |
| Source linking | Implemented for repeated source-to-profile matching |
| Preference inference | Implemented locally from shared chat text |
| Search/filtering | Implemented for people; limited elsewhere |
| Theming/design system | Implemented via `AppTheme`, custom frosted cards, responsive layouts |
| Tests | Good targeted widget/unit coverage, no true end-to-end native share tests |
| Backend sync readiness | Good scaffolding, still fake/offline-friendly |
| Privacy/trust UX | Limited; local-first behavior exists more in code than in user-facing copy |
| Cross-platform share viability | Partial; Flutter layer exists, native integration incomplete |
## B. Grading
| Feature Area | Status | Grade | Notes | Risk / Missing Pieces | Recommended Next Step |
| --- | --- | --- | --- | --- | --- |
| App architecture | Present | B | Clear enough separation between UI, local repository, sync, and integrations | Some large UI files, especially `PeopleView` | Add smaller share/fact modules instead of broad refactors |
| Local-first persistence | Present | A- | Hive-backed state with migration path and test coverage | Still JSON-in-Hive rather than richer queryable store | Keep current approach for this iteration |
| People management | Present | B | Good responsive UI, editing, duplicate warning, merge flow | Person model is too thin for relationship intelligence | Extend model with aliases, facts, dates, timestamps |
| Moments / history | Present | B | Useful local activity log | History is not yet strongly typed for preferences/dates/fact provenance | Add structured facts on top rather than replacing moments |
| Ideas / reminders | Present | B | Solid founder-mode utility already | Not tightly connected to share capture | Reuse future share classification to feed these areas later |
| Share intake pipeline | Partial | C | Flutter-side ingest and inbox exist | WhatsApp-specific, no generic text/URL pipeline, native wiring incomplete | Generalize payload normalization and improve clarification UX |
| Person resolution | Partial | B- | Exact/near-match logic and source links already exist | Resolution is tied to sender matching and not broader share assignment | Add explicit assign/create/save-to-inbox review flow |
| Inbox / triage | Partial | C+ | Resolves ambiguous source matching | Cannot yet classify into structured facts/dates/preferences | Add fact classification and later reassignment/edit support |
| Search / discoverability | Partial | C+ | People search/filter exists | No real inbox/fact/date search | Keep scope limited; prepare data for later search expansion |
| Privacy / trust UX | Weak | D | Local-first architecture exists | App does not clearly explain on-device storage or future AI sharing controls | Add clear local-first settings copy and sensitive-data affordances |
| Cross-platform share readiness | Weak | D | Plugin added, listener implemented | Android manifest missing share intent filters; iOS share extension not configured | Fix Android now, document iOS as deferred native work |
| Test posture | Present | B+ | Good unit/widget coverage for local repo and share inbox | Missing tests for generalized share parsing and structured triage | Add targeted parser/repository/widget tests |
## C. Product readiness assessment
### Solo founder daily use
Current usefulness is moderate. The app already supports keeping people,
captures, reminders, and ideas locally, which is enough for founder testing.
However, the most important real-world capture path, sharing snippets from other
apps, is not yet strong enough to rely on daily.
### Friction of data entry
Manual entry is acceptable. Cross-app capture still has too much friction
because it is optimized around one parser path instead of a general intake
flow. Ambiguous content can be saved, but not yet shaped into structured,
reviewable facts.
### Trust / privacy feel
The implementation is local-first, but the UX does not communicate that clearly
enough. For a relationship app, trust is part of the product. The app should
say what stays on device, what is not yet shared, and how users can correct or
delete imported facts.
### Extensibility for future LLM support
Reasonably good. The repository pattern, fake backend mode, and local inferred
preference signals create a workable foundation. The main gap is data shape:
profile context is still too flat, and shared content is not normalized into a
recommendation-ready structure.
### Cross-platform viability
Good at the Flutter layer, incomplete at the native share-entry layer. Android
needs explicit share intent wiring. iOS still lacks a real share extension.
### Likely adoption blocker
The biggest blocker is not “AI quality”; it is capture friction. If sharing a
snippet from WhatsApp, Safari, Notes, or Messages into the app is unreliable or
too manual, the product will not accumulate enough high-value context to become
habit-forming.
## D. Top implementation priorities
1. Generalize share capture into a platform-aware text/URL pipeline with a
clear internal payload model and Android native entry wiring.
2. Add an inbox-first clarification flow that lets the user assign to an
existing person, create a new person quickly, or save unresolved data for
later.
3. Extend the local person knowledge model with aliases, structured facts,
important dates, timestamps, and source traceability.
4. Upgrade the inbox from “resolve person only” to “triage into note / like /
dislike / date / idea-ish fact”.
5. Improve privacy/trust wording and make correction paths more obvious.
## Recommended scope for this iteration
Implement a disciplined client-only slice:
- generic shared text / URL normalization
- Android text share intent support
- share clarification sheet for assign/create/inbox
- richer local fact/date models with provenance
- inbox triage into structured facts or important dates
- person detail UI for reviewing captured facts/dates
- targeted tests
Explicitly defer:
- native iOS share extension target work
- real backend sync of new fact/date entities
- real LLM or recommendation calls
- large navigation or persistence rewrites
+173
View File
@@ -0,0 +1,173 @@
# Client Implementation Plan
Date: 2026-04-01
## Chosen scope for this iteration
This iteration focuses on the smallest slice that materially improves founder
testing:
1. Generalize intake from WhatsApp-only text import to a broader shared payload
pipeline that supports:
- plain text
- URL
- text + URL
2. Add an explicit clarification flow for ambiguous shares:
- assign to existing person
- create person quickly
- save to inbox for later
3. Improve the local person knowledge model with:
- aliases
- structured captured facts
- important dates
- timestamps
- source/provenance metadata
4. Upgrade inbox triage so unresolved shares can be converted into:
- note
- like
- dislike
- important date
- gift idea
- place idea
- activity idea
- misc fact
5. Add trust-facing settings copy and targeted tests.
## Why this scope
- It directly improves the most important product workflow: fast capture from
outside the app.
- It stays client-side and local-first.
- It does not require a storage rewrite or backend coupling.
- It produces data structures that future LLM/recommendation work can consume.
- It keeps risk contained by extending the existing repository and views rather
than replacing them.
## Affected files / modules
### Expected to change
- `lib/main.dart`
- `lib/features/local/local_models.dart`
- `lib/features/local/local_repository.dart`
- `lib/features/people/people_view.dart`
- `lib/features/settings/settings_view.dart`
- `lib/features/share_intake/share_inbox_view.dart`
- `lib/features/share_intake/whatsapp_share_listener.dart` or replacement
- `android/app/src/main/AndroidManifest.xml`
- `test/features/local/local_repository_test.dart`
- `test/features/share_intake/share_inbox_view_test.dart`
### Expected to add
- generic share payload parser / models
- share review sheet / dialog component
- parser unit tests
- iteration summary doc
## Architecture decisions
### 1. Keep `LocalRepository` as the orchestration layer
Reason:
- It already owns local persistence, entity updates, and ingestion logic.
- Extending it is safer than introducing a second persistence coordinator.
Tradeoff:
- The file remains large.
Mitigation:
- Add focused helpers/models for share parsing and captured-fact typing rather
than pushing more UI logic into the repository.
### 2. Add structured fact/date entities instead of overloading `notes`
Reason:
- Future recommendation features need provenance, timestamps, and type-safe
context.
- Users need auditability and correction, not just a bigger notes blob.
Tradeoff:
- More model surface area now.
Mitigation:
- Keep entity types intentionally small and local-only for this iteration.
### 3. Prefer inbox-first safety over aggressive auto-assignment
Reason:
- Wrong person attachment is worse than extra triage work in this domain.
Decision:
- Only auto-assign when confidence is genuinely high.
- Otherwise open clarification UI or save to inbox.
### 4. Fix Android share entry now, defer iOS native extension
Reason:
- Android manifest support is low-cost and unblocks real testing.
- Proper iOS share extension work is native-project-heavy and should be treated
as a separate scoped task.
## UX flows
### Flow A: direct share received with high-confidence target
1. Normalize incoming share into `SharedPayload`.
2. If a stable source link or clear unique alias/name match exists, allow direct
save to the person.
3. Persist the payload history plus a structured fact defaulting to `note`
unless a better classification is explicitly chosen.
4. Show confirmation snackbar and navigate to the relevant destination on cold
start.
### Flow B: share received without safe target
1. Normalize into `SharedPayload`.
2. Open a lightweight review sheet when possible.
3. Offer:
- recent people / candidate people
- quick create person
- save to inbox
4. If the user saves to inbox, persist payload + draft classification and leave
the item unresolved.
### Flow C: inbox triage later
1. Open `Share Inbox`.
2. Review the preview text/URL and suggested candidates.
3. Choose person or create one.
4. Choose classification and edit the extracted content.
5. Save as structured fact/date.
## Risks
### Risk: model expansion causes migration issues
Fallback:
- Keep new JSON fields backward-compatible with defaults in `fromJson`.
### Risk: generic share parsing creates false confidence
Fallback:
- Default to inbox / manual clarification for unclear payloads.
### Risk: too much UI churn in `PeopleView`
Fallback:
- Add new review sections for facts/dates without reworking the whole people
editor architecture.
### Risk: native plugin behavior differs across platforms
Fallback:
- Keep settings-based share simulation path for deterministic local testing.
## Intentionally deferred
- iOS share extension target creation and App Group setup
- image/file share support
- sync mapping for new fact/date entities
- AI-driven classification/recommendations
- full-text search across inbox/facts/dates
- notification engine hooks for new entities
+146
View File
@@ -0,0 +1,146 @@
# Client Iteration Summary
Date: 2026-04-01
## What was implemented
This iteration focused on client-side share capture, local-first structure, and
safer person assignment.
Implemented:
- generic shared payload normalization for:
- plain text
- URL
- text + URL
- a review-first share capture sheet for:
- assign to existing person
- create person quickly
- save to inbox
- richer local person model support:
- aliases / nicknames
- last updated / last interacted timestamps
- richer local knowledge entities:
- structured captured facts
- important dates
- source/provenance metadata
- sensitive flag scaffolding
- inbox triage improvements:
- draft mapping to note / like / dislike / date / gift / place / activity / misc
- create person directly from inbox
- resolve to existing person with fact mapping
- people profile UI improvements:
- aliases visible in profile context
- captured facts section
- important dates section
- edit/delete support for facts and dates
- Android native text share entry:
- `ACTION_SEND` text intent filter added to `AndroidManifest.xml`
- trust/privacy wording:
- clearer local-first copy in settings
- tests:
- generic share payload parser tests
- repository tests for inbox-to-fact and date persistence
- updated share inbox widget test flow
## Architecture decisions
### Kept the existing repository-centered local architecture
`LocalRepository` remains the orchestrator for local persistence and ingest.
This avoided a risky refactor and let the new share pipeline build on existing
person/source-link/moment infrastructure.
### Added structured fact/date entities instead of overloading notes
This creates a cleaner bridge to future recommendation, summarization, and sync
work. Shared captures can now produce auditable, typed local knowledge instead
of only raw note blobs.
### Used a review-first share flow for safety
Rather than silently guessing in generic share cases, the app now asks for a
target person or lets the user save to inbox. This is the safer default for a
relationship product.
## Known limitations
- iOS still does not have a real share extension target configured. The Flutter
share logic exists, but native iOS share-sheet presence remains deferred.
- Android share support added here is text-focused only.
- Generic share flows do not infer advanced semantic structure automatically
beyond the existing preference extractor.
- Captured facts and important dates are local-only and not yet mapped into the
backend sync protocol.
- Inbox triage currently converts one structured draft per inbox item. It does
not yet split a single payload into multiple facts.
- Search is still strongest in People and not yet expanded across facts/dates/
inbox.
## What should happen next in a backend / LLM session
1. Define backend entity contracts for:
- person aliases
- structured facts
- important dates
- shared payload provenance
2. Add sync-envelope mappings for the new local entities.
3. Introduce optional AI-assisted extraction that proposes:
- multiple facts from one payload
- date detection
- confidence scoring
- recommendation context packaging
4. Add server-compatible merge/reconciliation rules for conflicting profile
facts and dates.
5. Implement explicit privacy controls for any future cloud or AI sharing.
## Manual walkthrough
### 1. Create person
- Open `People`.
- Tap `Add person`.
- Enter:
- `Name`
- `Relationship`
- optional `Aliases`
- optional notes/tags/location
- Save.
### 2. Share text into app
- On Android, share any text snippet into the app from another app.
- Or use `Settings` -> `Simulate Share Capture`.
- The review sheet should open showing the parsed text/URL preview.
### 3. Resolve ambiguity
- In the review sheet, choose a fact type such as `Like` or `Note`.
- Pick an existing person from recent chips or the full dropdown.
- Save to that person.
### 4. Save to inbox
- Repeat with another shared snippet.
- In the review sheet, choose `Save To Inbox`.
- Open `Share Inbox`.
### 5. Assign later
- In `Share Inbox`, open the queued item.
- Confirm or change the fact mapping.
- Choose `Review & Save` to match an existing person, or `Create Person`.
- Complete the flow.
### 6. Edit captured fact
- Open `People`.
- Select the person.
- In `Captured facts`, tap `Edit` on the new fact.
- Change the text/label/type or sensitive flag and save.
### 7. Edit captured date
- If the capture was saved as a date, open `Important dates`.
- Tap `Edit`.
- Adjust label/classification/date and save.
+1 -1
View File
@@ -1,6 +1,6 @@
# Relationship Saver Progress Log
Updated: 2026-02-22
Updated: 2026-02-23
## Collaboration Rule (Carry Forward)