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

122 lines
3.4 KiB
Markdown

# 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.