Market Sweep + Outreach iOS Parity Map
1. **Market Sweep** discovers and qualifies cafes in a market. 2. **Outreach** turns qualified prospects into conversations, follow-ups, visits, and eventual accounts.
Full Public Reader
Market Sweep + Outreach iOS Parity Map
Product Contract
The web app splits growth work into two connected systems:
1. Market Sweep discovers and qualifies cafes in a market.
2. Outreach turns qualified prospects into conversations, follow-ups, visits, and eventual accounts.
The source of truth is Supabase, not local app state.
Web Pipeline
1. Create `market_sweeps` row for a city/state/neighborhood.
2. Run `market-sweep-search` to populate `sweep_prospects`.
3. Run enrichment stages:
- `market-sweep-enrich`
- `market-sweep-prospeo-enrich`
- `market-sweep-instagram-enrich`
- `market-sweep-visual-score`
4. Import qualified prospects into CRM:
- `market-sweep-import`
- `inbound_leads`
- `accounts`
- `locations`
5. Generate outbound content:
- `market-sweep-ai-generate`
- `subject_variants`
- `ai_subject`
- `ai_body`
6. Send and track outreach:
- `market-sweep-email`
- `market-sweep-followup`
- `email_outreach`
- `outreach_send_log`
7. Classify replies and schedule field work:
- `market-sweep-classify`
- `response_type`
- `qualification_tier`
- `outreach_stage`
- `prospect_visits`
Backend Contract
Primary tables:
- `market_sweeps`: market-level operation status, totals, distributor context, search config.
- `sweep_prospects`: discovery staging, enrichment, contact data, AI email copy, outreach status, ICP scores.
- `sweep_contacts`: multi-contact enrichment from Prospeo/manual sources.
- `inbound_leads`: promoted CRM leads after import.
- `email_outreach`: immutable email-send/audit log.
- `outreach_send_log`: daily send cadence and recipient-domain tracking.
- `outreach_templates`, `email_sequences`, `prospect_sequence_state`: template and sequence management.
- `prospect_visits`: visit scheduling from interested replies.
Edge functions used by the native Growth surface:
- `market-sweep-search`: SerpAPI discovery into `sweep_prospects`.
- `market-sweep-enrich`: website/email/IG scrape enrichment.
- `market-sweep-prospeo-enrich`: company and decision-maker enrichment.
- `market-sweep-instagram-enrich`: IG follower/profile enrichment.
- `market-sweep-instagram-aesthetic`: Gemini visual scoring from feed screenshots.
- `market-sweep-visual-score`: cafe photo ICP scoring.
- `market-sweep-import`: promotion into CRM tables.
- `market-sweep-ai-generate`: personalized outbound subject/body generation.
- `market-sweep-classify`: reply classification and tiering.
- `market-sweep-assign`: territory assignment and visit sequence creation.
- `market-sweep-email`: approved intro email send.
- `market-sweep-followup`: follow-up email send.
Native Baseline
The iOS app already has pieces:
- `FieldRouteService` reads selected-market `sweep_prospects`, clusters route-ready prospects, and can consume Growth handoff payloads.
- `LeadDiscoveryService` uses `MKLocalSearch`, but it is a local search tool, not the web market-sweep pipeline.
- `FieldRoutesTabView` can cluster prospects and record visit outcomes.
- Native now has delivery-grid parity foundation.
- Native now has a first Growth command center backed by `market_sweeps` and `sweep_prospects`.
- Native now has a first Inbound command board backed by `inbound_leads`, `lead_scores`, and `inbound_actions`.
- Native now has a first Response Inbox backed by responded `sweep_prospects` and `prospect_visits`.
- Native now has a first Sequence Manager backed by `email_sequences` and `prospect_sequence_state`.
- Native now has a first Market Detail surface backed by `market_sweeps` and `sweep_prospects`.
- Native now has first Supabase Realtime subscriptions for Growth progress refreshes.
- Native now has route handoff from Market Detail, Response Inbox, and assigned sweep prospects into Field Routes.
- Native now promotes Field Routes outcomes back into visit, prospect, account, and location state.
- Live DB audit is captured in `docs/ios-parity/database-contract-audit.md`.
Implemented Native Growth Slice
The iOS app now has a native Growth tab and sidebar section that can:
- List recent market sweeps.
- Show sweep status, counters, and errors.
- Show prospects for a selected sweep.
- Show cross-sweep outreach queue.
- Create new sweeps with city/state/coordinate/distributor context.
- Run backend pipeline actions from iOS:
- search
- enrich
- Prospeo enrichment
- Instagram enrichment
- Instagram aesthetic scoring
- visual scoring
- import to leads
- AI email generation
- response classification
- territory assignment
- Manage prospect state:
- approve/reject generated email
- skip/hold prospect
- mark responded
- Work inbound leads:
- list and search recent `inbound_leads`
- filter by status, priority, and pipeline stage
- show lead score, source, location, territory, owner, and last contact state
- show totals for new/contacted/sampled/high-priority/overdue/active/conversion
- edit status, priority, pipeline stage, and assigned owner
- log email, call, sample, note, follow-up, and check-back actions into `inbound_actions`
- complete or skip pending inbound actions
- advance sample actions into sampled/sample pipeline state
- Work outreach responses:
- list and search responded `sweep_prospects`
- filter by interested, auto-reply, not-now, wrong-contact, unsubscribe, and unclassified replies
- show response counts, interested count, hot tier count, unclassified count, and scheduled-visit count
- classify replies into `response_type`, `qualification_tier`, `email_status`, and `outreach_stage`
- schedule `prospect_visits` for interested accounts
- move scheduled prospects to `outreach_stage = visit_scheduled`
- pause open `prospect_sequence_state` rows with `pause_reason = Visit scheduled`
- generate local safe reply drafts and expose copy/share actions instead of silent sending
- Work sequence/follow-up state:
- list active `email_sequences`
- decode JSONB sequence steps
- show enrolled prospects from `prospect_sequence_state`
- show active, paused, and due-now counts
- visualize email/wait/condition/branch steps
- show enrollment funnel progress by email step
- pause, resume, and skip sequence state without sending external mail
- Work market detail:
- list available city/state markets from recent `market_sweeps`
- aggregate all sweeps and prospects for a selected market
- dedupe prospects by `place_id` or normalized business name
- group prospects by neighborhood with Portland/Seattle address heuristics
- show total prospects, HOT/WARM/COLD distribution, average trend/ICP scores, email readiness, generated/sent/reply/imported counts, and sweep count
- hand off a neighborhood or individual prospect into Field Routes
- Hand off Growth work into Field Routes:
- persist source, market program, prospect ids, title, and subtitle in a `FieldRouteHandoff`
- switch the app to Field Routes when a handoff is created
- filter Field Routes to the handed-off route-ready prospects when coordinates exist
- fall back to the full selected-market route when a handoff has no route-ready coordinates
- clear a handoff from the Field Routes banner to return to the full market route
- show Assigned Field Route panels in Prospects and Outreach for account-linked, imported, visit-scheduled, visited, or converted prospects
- hand off assigned route-ready prospects through `FieldRouteHandoffSource.assignedProspects`
- append field visit outcome history, complete or create `prospect_visits`, and promote outcome state back into Growth and linked CRM rows
- Refresh Growth from Supabase Realtime:
- subscribe to `market_sweeps` and `sweep_prospects` for sweep/prospect/outreach/market progress
- subscribe to `sweep_prospects`, `prospect_visits`, and `prospect_sequence_state` for response work
- subscribe to `email_sequences`, `prospect_sequence_state`, and `sweep_prospects` for sequence work
- debounce row-change bursts before refetching so backend batch pipelines do not spam the UI
Email send/follow-up remains a guarded action. iOS can expose it as a user-triggered command, but automation must not send externally without explicit user intent.
Territory assignment is also guarded because it writes downstream routing and visit sequence records.
Next Native Implementation Order
1. Inbound command board hardening
- Add table/kanban/map layouts on top of the native lead board.
- Add territory, assigned owner, and date filters beyond the current status/priority/pipeline/search filters.
- Add multi-select bulk status/priority/stage/owner updates.
- Add native score breakdown and lead-score recomputation parity with the web scoring helper.
2. Sequence and follow-up manager hardening
- Add manual enrollment from an eligible prospect.
- Add sequence detail editing only after backend ownership is settled.
- Add completed enrollment history and send-log inspection.
3. Response inbox hardening
- Add live Mail/IMAP ingestion or a backend bridge that writes replies into Supabase.
- Add editable response body capture for manually imported replies.
- Add visit list/history inside the response detail sheet.
- Add defer/skip actions for non-interested responses.
4. Market detail hardening
- Add scorecard drill-downs and conversion-funnel charts on top of the current native market rollups.
- Add market history/campaign list parity once the web campaign contract is finalized.
5. Realtime hardening
- Verify live `supabase_realtime` publication membership for all Growth tables.
- Add per-row filters once scale requires narrower subscriptions.
- Use optimistic UI only for local prospect state actions; backend pipeline counts remain source of truth.
Parity Gaps After First Native Target
- Full sweep wizard with market presets and coordinate lookup.
- Realtime publication validation and per-row filters for high-volume sweep progress.
- Email approval swiper.
- Mail bridge replacement for iOS-native or backend reply ingestion.
- Response inbox visit history and defer/skip polish.
- Sequence enrollment creation, completed history, and send-log drill-down.
- City scorecard, franchise list, campaign history.
- Market detail drill-down charts and campaign history.
- Inbound kanban/map/table-density parity, bulk updates, date filters, territory analytics, and score recompute.
- Full outcome history drill-down from Growth and Market Detail.
- Public share route page has no native equivalent.
Backend Risks
- Local native migrations under `[home]/Desktop/Milk Men/supabase` diverge from the web schema. The live app points at the web Supabase project, so native code should follow the web table names and columns.
- Some native migrations use `sweep_campaigns/campaign_id/business_name`; web uses `market_sweeps/sweep_id/name`.
- Local native inbound migrations use `due_date` in older files; web/live `inbound_actions` uses `scheduled_date`. Native code follows the web/live `scheduled_date` contract.
- Milkmen Supabase MCP is not connected to the Milkmen project. Live verification must use REST/API or the web app project config.
- RLS must permit authenticated native reads/writes for `market_sweeps`, `sweep_prospects`, `sweep_contacts`, `inbound_leads`, `email_outreach`, and `prospect_visits`.
- Supabase Postgres Changes only emits for tables included in the `supabase_realtime` publication; apply `[home]/Desktop/milkmendelivery/supabase/migrations/20260521000003_growth_realtime_publication.sql` before relying on realtime in production.
- Live DB checks on 2026-05-22 verified `prospect_visits` and the native runtime tables exist after the dashboard migration apply. Remaining DB risk is RLS and app-session smoke, not table absence.
Promotion Decision
Promote into a technical note or architecture paper with implementation anchors.
Source Anchor
Milk Men/docs/ios-parity/market-sweep-outreach-system-map.md
Detected Structure
Method · Code Anchors · Architecture