# 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 ```text 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: ```bash 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.