# 1.2.0 Flow-Closure Plan (UX usability pass)

Source: 5 parallel live flow audits, 2026-06-07 (monetization, analytics,
emails/notifications, import/migration, lifecycle/privacy). Full tables in the
audit transcripts; this doc is the consolidated work plan.

Verdict: every 1.2.0 feature CORE works (verified by build-wave journeys), but
flows leak at the HANDOFFS - discoverability, onward links, failure feedback,
opt-outs, and cross-feature stitching. ~11 blockers / ~32 annoying / ~12 polish.

## Consolidated blockers

| # | Flow break | Family |
|---|---|---|
| 1 | Review-reminder has NO user opt-out toggle anywhere; email "Manage preferences" link broken for logged-in AND logged-out users (#profile hash + BP conflict + login dead-end) | Emails |
| 2 | Digest mode silently swallows review reminders (never delivered, queue forever) | Emails |
| 3 | Zero-result keywords displayed with zero onward action (no copy/export/create) | Analytics |
| 4 | Owner Analytics tab off-screen at 390px (10-tab nav, no scroll affordance) | Analytics |
| 5 | Import failure state swallows messages[] - admin cannot see what failed | Import |
| 6 | Failure notice promises "re-run from Settings -> Advanced" which does not exist | Import |
| 7 | Free CSV import synchronous (timeouts >~500 rows) while Background_Import::queue_file() sits UNWIRED | Import |
| 8 | Failed wizard import widget stuck in failed state even after AS retry succeeds | Import |
| 9 | Buyer never notified when admin refunds credits (no Credit_Notifier email; only the contextless re-pause email) | Monetization |
| 10 | Buy-credits path dead-ends on this env: credit packs empty + no gateway configured, empty states give no admin guidance. NEEDS VERIFICATION: SDK ships Stripe/PayPal direct gateways + 5 plugin adapters - likely CONFIG/onboarding gap, not missing product. | Monetization |
| 11 | Refund button click reportedly navigated away in one Playwright session (code is correct; 4 triggers verified in DOM) - NEEDS RE-VERIFY for an admin-delegation.js interception | Monetization |

## Wave plan (proposed): one flow-closure wave per repo

### Free wave-10-flow-closure (5 directions, disjoint scopes)
1. f10-email-optout - token-based one-click unsubscribe REST endpoint (HMAC,
   works logged-out) + footer link swap; review_reminder added to: tab-profile
   per-user prefs, admin Settings toggle list, CLI test-email list, test-send
   dropdown (feed from Email_Templates_Page::get_event_map()); test-send echoes
   recipient; dashboard_url var fixed.
2. f10-import-feedback - render messages[] in failed widget; done-step count
   server-side; failure links to AS screen; "Re-run demo import" action in
   Settings Advanced (the promised one); View-Listings links on wizard Done +
   CSV result; wire CSV import to Background_Import::queue_file() + existing
   progress widget; post-AS-retry re-poll.
3. f10-views-everywhere - render 0 instead of hiding view counts (dashboard +
   admin column); link admin Views count to the listing; "-" vs 0 semantics.
4. f10-lifecycle-polish - is_24h checkbox in the wizard hours builder + inline
   open/closed preview chip; bulk-edit notices surface the per-row WP_Error
   message (incl. invalid transition); Privacy row in Settings pointing at WP
   export/erase tools; SSR-visible reviews panel when landing on #reviews +
   per-review anchors (reminder deep link targets oldest unanswered).
5. f10-mobile-nav - dashboard tablist scroll affordance <=640px (Analytics tab
   reachable); settings-nav overflow-x at narrow widths.

### Pro wave-10-flow-closure (4 directions, disjoint scopes)
1. p10-refund-loop - Credit_Notifier: credits-refunded buyer email (mirrors
   Plan_Notifier); paused-by-refund email gains cause=refund context branch;
   receipt_url added to purchase_plan response + Receipt column in dashboard
   history table; admin prompt when business-details empty but credits in use;
   re-verify refund button click (delegation guard if intercepted).
2. p10-monetization-onboarding - credit-packs/gateway empty states link the
   ADMIN to the right settings; paused email credits_url fallback; document/
   surface the SDK gateway + adapter options on the Credits settings screen.
   (Pre-req: verify blocker 10 config-vs-product.)
3. p10-analytics-actions - zero-result keywords: copy button + per-row Add
   Listing link; CSV export on overview + search tabs; Top Listings details
   link; "Search" tab subtitle; digest: review_reminder routed via
   $owner_events in Notification_Digest::send_digest() (blocker 2, Pro side);
   digest settings list urgent/digested/dropped buckets; per-user prefs note
   when digest active.
4. p10-migration-polish - competitor section description lists real migrators
   (adds HivePress, drops Connections); one-time "Migration moved to
   Import/Export" notice for Free-tab bookmarks; View Listings button after
   migration run; Retry button on failed Visual Import.

## Architecture items - PULLED INTO 1.2.0 (DEC-5, owner 2026-06-07: why wait)
- Unify the TWO parallel background-import systems (Free run_id vs Pro batch_id).
- Competitor migration -> background pipeline (currently synchronous).
- Shared is_bot_request() helper (Free+Pro duplicate).
- Gateway/payments-table end-to-end once a gateway is configured (incl.
  payment_id>0 refund path with real data); public token receipt URLs.
- Analytics retention health visibility (Site Health check).

Every direction: additive-only, journeys updated in the same change, 390px
verification, manifest deltas. Execution via autovap v2. DEC-5 adds a wave-11-architecture per repo: import-system unification (Pro visual-import consumes Free Background_Import - dedupe rule), competitor migration backgrounded, shared bot helper (Free-first), receipt token URLs, retention health. Gateway e2e stays conditional on the blocker-10 config verification.
