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

4.1 KiB

Data Model

The app stores most relationship data in LocalDataState, persisted by LocalRepository.

Aggregate State

Source: lib/app/state/local_data_state.dart

Field Type Meaning
people List<PersonProfile> primary relationship profiles
moments List<RelationshipMoment> interaction and capture history
ideas List<RelationshipIdea> gift, activity, and follow-up ideas
reminders List<ReminderRule> local reminder rules
tasks List<DashboardTask> dashboard task surface
dismissedSignalIds List<String> dismissed generated signal IDs
sourceLinks List<SourceProfileLink> external sender/thread to profile mapping
sharedMessages List<SharedMessageEntry> imported shares attached to profiles
sharedInbox List<SharedInboxEntry> unresolved or ambiguous shares
personFacts List<PersonFact> structured relationship facts
importantDates List<PersonImportantDate> birthdays, anniversaries, events
preferenceSignals List<PersonPreferenceSignal> inferred/confirmed likes/dislikes
aiSuggestionDrafts List<AiSuggestionDraft> pending AI review items

Profile Model

Source: lib/features/people/domain/person_models.dart

PersonProfile is the stable profile root. Important fields:

  • id: internal local ID
  • name, aliases: local identity only
  • relationship: user-facing relationship category
  • affinityScore: rough closeness score
  • nextMoment: next planned contact or relationship moment
  • tags, notes, location: user-authored context
  • lastUpdatedAt, lastInteractedAt: operational recency fields

SourceProfileLink maps an external source to a local profile. It is used by share intake to avoid asking again after the user resolves a source identity.

Share Models

Source: lib/features/share_intake/domain/share_models.dart

SharedPayload is normalized input from share sheets, action extensions, or simulation tools.

Key timestamp fields:

  • createdAt: when the app created the normalized payload
  • receivedAt: when the app received/imported the share
  • sharedMessageDateTime: best-effort original message timestamp extracted from shared text, or null

Use sharedMessageDateTime as temporal evidence. Do not assume it exists. Do not infer it from arbitrary content dates such as "birthday is May 20".

CapturedFactDraft is the review/edit draft before a share becomes a durable fact or important date.

SharedMessageEntry is the durable record attached to a person. Its sharedAt getter prefers sharedMessageDateTime when present.

SharedInboxEntry is unresolved intake. Reasons include missing identity, ambiguous profile match, near-profile conflict, and manual selection needs.

Facts, Dates, And Signals

PersonFact is durable structured context:

  • type: note, like, dislike, importantDate, giftIdea, placeIdea, activityIdea, misc
  • sourceKind: manual, shareSheet, or shareInbox
  • sharedMessageId or inboxEntryId: provenance
  • needsReview and isSensitive: prompt and UI filtering controls

PersonImportantDate is a dated profile-owned record. It can come from manual input, share review, or AI-assisted extraction.

PersonPreferenceSignal is inferred or confirmed preference evidence. It tracks first/last seen timestamps, occurrence count, source apps, message IDs, and evidence snippets.

AI Suggestion Drafts

Source: lib/features/ai_digest/domain/ai_digest_models.dart

AI suggestions are saved as drafts first. Accepted drafts can become local ideas, reminders, or tasks. Dismissed drafts stay in history so future digest prompts can avoid repeats.

Schema Versioning

LocalRepository owns _schemaVersion. When adding persisted fields:

  1. Add nullable/defaulted fields where possible.
  2. Update toJson, fromJson, and copyWith.
  3. Increase _schemaVersion only when a migration has meaning beyond default compatible parsing.
  4. Add repository and serialization tests.
  5. Verify legacy/missing field behavior.

The current fromJson patterns are intentionally tolerant for many optional lists and fields. Keep that property.