UX audit · 2026-09-25 · updated evening · main after #353 · staging self-serve enabled (00141-wkv) · staging 00246-kim (pre-#330) · production hotfix afff36b (00037-wag)

Page completion audit

Every page in the page inventory, checked against its hi-fi prototype. Reachable pages were walked on staging and production at 1060px and 390px; signed-in steps on staging. Operator pages and states behind payment were not re-walked and carry the 09-24 findings.

Complete44redesigned on main; most not yet released
Partial3
Old design1
Missing1
External / deferred5
Total55incl. 1 internal

Where things stand

Staging (staging.signalanalyst.ai) runs main with self-serve switched on: the new Plan, Status, Account Home and Claude pages; Stripe test mode (Startup $59/$99, Scaling $249 + overage, 7-day card trial); and shared migrations 0040 and 0048–0053 applied. Production still runs the pre-redesign app plus the legal/Google sign-in hotfix.

Flow change (2026-09-25 check-in): connect stores before the credit card. The order is Account → Connect → Plan → Status (#354, in review). Also agreed there: a promo code for alpha testers, still to build.

Blocking the end-to-end test: staging shares production's Shopify app, so a dev-store install is tested with a signed staging link. The import service is staging-only, so production self-serve can't import yet.

Critical

Nothing from the redesign is on staging or production yet. The self-serve pages sit behind SELF_SERVE_SHARED_ENABLED and need shared migrations 0048–0053, two new database logins, Stripe test-mode setup and a staging deploy. The rollout kit and runbook are in #349; applying them needs owner approval.
The end-to-end journey hasn't run anywhere. Sign-up → trial → Shopify dev store → import → published binding → Claude answering is unproven. In particular, Pipelines filling orders_final in the managed dataset has never been observed (task 9.1).

Moderate

Deferred for MVP, labelled honestly in product: self-serve team invites (C09), a multi-workspace Add to Slack (C11), Klaviyo for self-serve accounts, Scaling overage billing (task 3.4), and the Slack welcome DM (C12).
Connect-result polish: the Shopify and Meta account confirmation (E09/E10) aren't yet matched line by line to the prototypes; Google Ads still asks for typed customer IDs (E11).
The Stripe Billing Portal must allow plan switching and cancellation before Account Home's copy is true (runbook step 7).

Every page

IDPageStatusmainstagingprodEvidenceFindingNext
P01●HomePublicPartial✓n/aoldP01 screenshotMain has the S1 homepage with the new Startup/Scaling/Enterprise pricing and a working Pricing link. Production still serves the old homepage.Release main.
P02●Account · sign upCustomerComplete✓✓oldP02 screenshotGoogle-first, no name field. The official Google “G” is on main (#330); staging still shows the old circle. Desktop vertical centring unchanged.Top-align the form on tall desktop screens; release.
P03●Account · log in (incl. returning to Claude)CustomerComplete✓old—P03 screenshotDone on main (#330): /login?next=/mcp/install shows “Sign in to connect Claude” with the official Google mark. Staging still has the older build.Deploy main to staging, then release.
P04●Plan stepCustomerComplete✓oldoldP04 screenshotShared mode (#339): shop name + Startup 12 months $59 / lifetime $99 / Scaling $249, 7-day card trial, nothing preselected, Enterprise → support. Owner-checked checkout; a duplicate subscription is cancelled by the webhook. Standalone mode keeps the old step.Staging rollout (#349), then release.
P05●Connect stepCustomerComplete✓oldoldP05 screenshotShared mode (#341): Shopify connects to the owner's shop before it is eligible; Meta/Google Ads unlock after the first import; Klaviyo 'coming soon' for self-serve; Continue waits for Shopify.Staging journey (9.1).
P06●StatusCustomerComplete✓oldoldP06 screenshotShared mode (#341): Plan / Shopify / First import / Claude checklist from /api/status, live polling, Connect Claude when ready, working Reconnect Shopify.Staging journey (9.1).
P07●Connect ClaudeCustomerComplete✓✓oldP07 screenshotPublic, copy button, plan choice, plain access note. Production still redirects signed-out visitors (S2 not released).Release S2.
P08●Operations · SourcesOperatorComplete✓oldoldIn the shared operations shell and nav (#347); admin guards and nonces unchanged.—
P09●Operations · ConnectionsOperatorComplete✓oldoldIn the shared operations shell and nav (#347); admin guards and nonces unchanged.—
P10●Operations · PipelinesOperatorComplete✓oldoldIn the shared operations shell and nav (#347); admin guards and nonces unchanged.—
P11●Operations · Slack thread replayOperatorComplete✓oldoldIn the shared operations shell and nav (#347); admin guards and nonces unchanged.—
P12●Operations · Source testsOperatorComplete✓oldoldIn the shared operations shell and nav (#347); admin guards and nonces unchanged.—
E01●Magic link · request and sentCustomerComplete✓✓—E01 screenshotMatches the prototype. The footer Help link points to /help on main (#330).Deploy main to staging.
E02●Magic link · landingCustomerComplete✓oldoldMagic-link landing says 'You're signed in.' (#345).—
E03●Forgot password · requestCustomerComplete✓✓—E03 screenshotMatches the prototype. Help points to /help on main (#330).As E01.
E04●Reset password · set newCustomerComplete✓oldoldReset landing has its own heading; the 15-minute single-use claim is verified in code (#345).—
E05Google sign-in returnCustomerComplete✓✓✓Verified on production 2026-09-25 with an external account (david@helloconvo.com): consent shows signalanalyst.ai with Privacy/Terms, lands signed in.—
E06●Stripe checkoutCustomerExternal / deferredn/an/an/aE06 screenshotHosted by Stripe.—
E07●Checkout return · paid / cancelledCustomerComplete✓oldoldShared checkout return: 'Starting your trial…', waits for the webhook, holds re-submission (#339).—
E08Stripe billing portalCustomerExternal / deferredn/an/an/aHosted by Stripe.Link from C05.
E09●Shopify consent → confirmCustomerComplete✓oldoldInside the new Connect step: provider-specific copy and a "Connect <store>" button (#350); explicit selection is kept.—
E10●Meta consent → confirmCustomerComplete✓oldoldAs E09, for Meta ad accounts (#350).—
E11Google Ads connect resultCustomerOld designoldoldoldTyped customer IDs; no account picker.S5 Google Ads picker.
E12●Klaviyo connect resultCustomerComplete✓oldoldThe Klaviyo card says read-only access is enough and links to Klaviyo's API-key settings (#353). Klaviyo is locked for self-serve accounts until its self-serve connection lane exists.—
E13Shopify App Store installCustomerExternal / deferredn/an/an/aDeferred: App Store path out of scope; S7 is a redirect only.S7.
E14●Claude · shop pickerCustomerComplete✓oldoldE14 screenshotPlain-language consent (#343); the destination trust heading and form are unchanged.—
E15●Claude · unrecognized destinationCustomerComplete✓oldoldThe unrecognized-destination warning is kept; copy updated with E14 (#343).—
E16●Slack · install startCustomerComplete✓oldoldOn the public shell (#344), same status codes and no-oracle refusals; the CSP is stricter.—
E17●Slack · install resultCustomerComplete✓oldoldAs E16.—
E18●Slack · link can't be usedCustomerComplete✓oldoldE18 screenshotBranded 'This link can't be used' with Open Slack and Get help (#344).—
E19●Slack · configure channelCustomerComplete✓oldoldChannel shop picker on the shell; form fields unchanged (#344).—
E20●Slack · channel savedCustomerComplete✓oldoldAs E16.—
E21●Operations · Source detailOperatorComplete✓oldoldIn the shared operations shell and nav (#347); admin guards and nonces unchanged.—
E22●Operations · Backfill session callbackOperatorComplete✓oldoldThe failed handoff shows a readable page to browsers (JSON for API callers), same status codes (#347).—
E23●Email · sign-in linkEmailComplete✓oldoldE23 screenshotBranded layout on main (#331): logo, brand button, fallback link, footer with Signal Collective LLC and support@. EMAIL_FROM now required.Deploy.
E24●Email · password resetEmailComplete✓oldoldE24 screenshotBranded layout on main (#331).Deploy.
E25●Email · organization invitationEmailComplete✓oldoldE25 screenshotBranded on main (#331); names the recipient and role.Deploy.
E26●Email · thread invitationEmailExternal / deferredn/aoldoldE26 screenshotRemoved on main (#331): thread invitations no longer send an email.—
I01Design system showcaseOperatorInternal✓✓✓Exists at /design-system.—
C01●Start asking (final step)CustomerComplete✓——C01 screenshotShared mode (#341): example questions and Open Claude once Claude is connected (K-3 status, #340).Staging journey (9.1).
C02●Privacy policyPublicComplete✓—✓C02 screenshotLive on production with Signal Collective LLC (registered agent), Delaware, support@. Staging lacks the LEGAL_* settings (404).Set LEGAL_* on staging.
C03●Terms of servicePublicComplete✓—✓C03 screenshotLive on production.As C02.
C04●PricingPublicCompletesectionn/a—C04 screenshot/pricing (#330); the phone header menu now reaches Pricing and Help (#342).Release.
C05●Plan & billingCustomerComplete✓——C05 screenshotAccount Home (#341): plan and trial; Manage billing opens the Stripe portal (owner-checked, Stripe host only).Configure the Stripe portal (runbook, #349).
C06●Manage data sourcesCustomerComplete✓——C06 screenshotAccount Home: sources summary and Manage sources → Connect; Reconnect Shopify on Status.—
C07●Connected apps (Claude, Slack)CustomerComplete✓——C07 screenshotAccount Home: Claude status and Set up Claude; how to disconnect in Claude.—
C08●Account settingsCustomerComplete✓——C08 screenshotAccount Home: signed-in email and Sign out.—
C09●Team and invitationsCustomerPartial✓——C09 screenshotAccount Home says inviting teammates is coming soon and to email support.Self-serve team invites (post-MVP).
C10●Delete account and dataCustomerComplete✓——C10 screenshotAccount Home: deletion request to support; the copy matches the privacy policy (within 30 days).Operator deletion runbook.
C11●Add to Slack entry pointCustomerPartial✓——Add to Slack appears when SLACK_APP_INSTALL_URL is a slack.com install link; otherwise 'coming soon'. There is no multi-workspace Slack install yet.Slack app distribution (post-MVP).
C12Slack welcome DM and App HomeCustomerMissing———Slack surface not designed in-product.Later.
C13Shopify embedded app homeCustomerExternal / deferredn/an/an/aOut of scope (App Store path).—
C14●Branded 404 and error pagePublicComplete✓✓—C14 screenshot404 and a branded 500 with a reference id (#330) on main; browser page routes are wrapped. Production still returns Bun's empty 404.Release.
C15●Help and supportCustomerComplete✓——C15 screenshot/help on main (#330): setup, Claude, billing and account answers; contact from SUPPORT_EMAIL.Set SUPPORT_EMAIL on staging and production; release.
C16●Operations index and shared navOperatorComplete✓——/operations index on main (#330), admin-only (401 signed out).Release.

✓ = redesigned version present · old = page exists in the pre-redesign form · — = absent · n/a = not applicable.

Fixes, in priority order

  1. Merge the rollout kit (#349) and, with owner approval, run the staging rehearsal, then the apply (runbook docs/runbooks/self-serve-shared-staging.md).
  2. Stripe test mode: prices, webhook and billing portal. Then deploy main to staging with the self-serve settings.
  3. Walk the 9.1 journey with a Shopify dev store and a disposable Google account, including cancel, duplicate tabs, a delayed webhook and uninstall.
  4. K-6 read-only production check, then the owner's go-ahead for production migrations and the release of main.
  5. Post-MVP: E09–E12 polish, team invites, Slack distribution, overage billing, Slack welcome DM.