Files
rely/docs/SHARE_INTAKE.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

3.4 KiB

Share Intake

Share intake is the app's highest-friction capture path. It should be reliable, reviewable, and conservative about identity matching.

Entry Points

Flutter listener:

  • lib/features/share_intake/presentation/incoming_share_listener.dart

Native iOS:

  • ios/Share Extension/ShareViewController.swift
  • ios/Save Action/SaveActionViewController.swift
  • ios/Share Extension/Info.plist
  • ios/Save Action/Info.plist
  • ios/Runner.xcodeproj/project.pbxproj

Android:

  • android/app/src/main/AndroidManifest.xml
  • receive_sharing_intent plugin integration

Developer simulation:

  • Settings -> Simulate Share Capture

Pipeline

native share / simulation
  -> IncomingShareListener
  -> SharePayloadParser
  -> startShareCaptureReview
  -> capture to existing profile, create profile, or save to inbox
  -> LocalRepositoryShareOperations
  -> LocalDataState + sync queue + optional facts/dates/signals

Payload Normalization

SharePayloadParser normalizes:

  • source app labels
  • text vs URL vs text-with-URL payloads
  • WhatsApp sender prefixes
  • Signal sender prefixes
  • source-message timestamp evidence

SharedPayload keeps both app-side timestamps and source-message timestamps:

  • createdAt: normalized payload creation time
  • receivedAt: app receive/import time
  • sharedMessageDateTime: best-effort original message time, nullable

Source Message Timestamp Extraction

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

The extractor tries multiple metadata-like patterns:

  • bracketed chat prefixes such as [19/05/2026, 14:30] Sender: text
  • exported chat prefixes such as 5/19/26, 2:30 PM - Sender: text
  • labelled lines such as Received at: 19 May 2026 at 14:30
  • ISO-like timestamps
  • today at HH:mm and yesterday at HH:mm
  • numeric and month-name date variants

It returns null instead of throwing. It intentionally avoids arbitrary content dates, for example birthday is May 20, because those are not message receive times.

Identity Matching

Matching order:

  1. Existing SourceProfileLink by source fingerprint/user/thread metadata.
  2. Exact normalized display name when exactly one profile matches.
  3. Near-name conflict detection.
  4. Inbox when missing, ambiguous, or risky.

Do not auto-link when evidence is weak. The inbox is the safety valve.

Inbox Resolution

Share Inbox supports:

  • resolving to an existing person
  • creating a person
  • editing structured draft type/text/date
  • reviewing conflict candidates
  • saving provenance for facts and source links

Relevant files:

  • lib/features/share_intake/presentation/share_inbox_view.dart
  • lib/features/share_intake/presentation/share_capture_review_sheet.dart
  • lib/app/data/relationship_repository_share.dart

Native iOS Notes

The repository currently contains Share Extension and Save Action target entries in the Xcode project. The iOS Podfile still only has the Runner target, so verify extension build behavior after plugin updates or Pod changes.

Physical iPhone testing is required for real chat apps. Simulators are useful for Notes/Safari-style text and URL sharing, but not enough for WhatsApp, iMessage, or app-specific metadata behavior.

Tests

Useful focused tests:

flutter test test/features/share_intake
flutter test test/features/local/local_repository_test.dart

Add parser tests for every new source format. Add repository tests when matching, inbox, source links, facts, or signals change.