☰ MenuUAT Client

UAT — client workflow (Phase 6–10 acceptance)

Test account: dorian@redpoint-vision.com (client, Wakecut, magic-link — no password). Site: https://wakecut.com Stripe test card: 4242 4242 4242 4242, any future expiry, any CVC. Role handoffs: steps marked ⚙️ need the editor/ops walkthrough running in parallel (another browser profile or private window).

The one promise this whole flow must keep: your card is authorized at booking but only charged when you approve — and finals stay locked until then.

🧱 Phase-10 migration prerequisite. The new sections below (voice notes §2b, specify-editor add-on §1b, rate-your-edit §4b) depend on migrations 00340039. The shared dev/prod DB was last verified at 0033, so until the operator applies these each surface probe-and-skips (stays dark) — that is by design, not a bug. Confirm the live level first (CLAUDE.md rule 8: probe the object over REST with the service-role key, don't trust docs). If a section's surface never appears, check the migration is applied before logging a fail.

📧 Email prerequisite (Phase 7). Steps marked 📧 verify the transactional emails that now fire on each transition. They only send once the operator has set RESEND_API_KEY (rotate the two keys that transited chat during SMTP setup FIRST) in the Vercel prod env; migration 0020_notifications is already applied live. Sender is hello@wakecut.com (verified domain). If the key isn't set yet, the flow still passes — the email just doesn't send and a failed/absent notifications row is expected; skip the 📧 cells and note it. dorian@redpoint-vision.com is a real inbox, so client emails are directly checkable here.

1 · Landing & order

# Do Expect
1.1 Open / logged out (phone width too) Marketing home: hero, 3 steps, real package cards with prices, trust strip, FAQ opens on tap. No yacht clichés, no lorem ipsum
1.1a In the FAQ, open "What if no editor picks up my job?" New Phase-6b entry: honest framing — editors choose their work; a job that needs a tweak gets more time / lighter brief / better pay and you hold the levers. NEVER "rejected"/"failed"; no invented numbers
1.2 "Start an order" → login with dorian@redpoint-vision.com Magic-link email arrives; link returns you to the site logged in
1.3 Revisit / while logged in Hero CTA becomes "My jobs" + welcome-back line
1.4 /order: pick a package, fill the brief, continue to payment Stripe Checkout opens; the hold is explained BEFORE you pay ("authorized now, charged only when you approve")
1.5 Pay with the test card Success page → job visible at /jobs as "Order received"
1.5📧 Check dorian@…'s inbox Receipt email "Wakecut — order received (…)" from hello@wakecut.com. Line items match the order; total only, NO VAT line (Wakecut is unregistered — billing_config.vat unset). Editor never named
1.6 In Stripe dashboard (test mode): find the payment Status "Uncaptured" — authorized, NOT charged

1b · Specify your editor — paid add-on (0038)

Precondition (operator setup): the client must have a prior APPROVED/DELIVERED job with an editor — run the §1–§4 spine once first, or use an existing delivered job for dorian@…. Needs migration 0038 live and the tenant's package_extras row key='specify_editor' priced in GBP (live on wakecut at £10 — the repo seed carries only a dummy price, so read the live figure; never assert an invented number). The add-on offers the same pool-hold continuity as set_preferred_editor but as a paid, refund-on-miss upsell. Copy + price are tenant config (rule 5).

# Do Expect
1b.1 As dorian@… (who has a prior delivered edit), start a fresh /order in GBP The add-on "Work with your previous editor again" appears with the live price (£10 on wakecut) and a pseudonym picker of the editors who delivered for you before. Under it: "If they can't take this one, this add-on is refunded automatically." Only pseudonyms — never a real editor name
1b.2 As a first-order client (no delivered job yet — a fresh account, or before your first delivery) The add-on is ABSENT — hidden entirely for anyone with no prior delivered editor
1b.3 Switch the order currency to EUR (if the tenant offers it) The add-on is ABSENT for EUR buyers unless the tenant set a EUR price — wakecut's specify_editor has no EUR price, so it is hidden and never charged
1b.4 Pick your previous editor's pseudonym and pay Order placed; the job holds for that editor on the claim board for the hold window (tenant billing_config.specify_editor_hold_hours, code default 48h). The editor still has to claim — it is never auto-assigned
1b.5 ⚙️ If the requested editor claims within the window The add-on is honoured; nothing is refunded. Job proceeds normally
1b.6 ⚙️ If the requested editor does NOT claim before the window ends (a "miss"), and the base payment has been captured, the specify-editor cron sweeps The job opens to the wider pool automatically; the extra (only) auto-refunds to your original card — the base charge, editor payout and job status are untouched
1b.6📧 Check dorian@…'s inbox after a miss-refund Email "Wakecut — add-on refunded (…)" — "…we've refunded that add-on — £X goes back to your original payment method" + "Your project continues as normal with our wider editor team; everything else about your order is unchanged." CTA "View your project". No editor named

Manual-capture timing. The extra can only be refunded once the base payment is captured (that happens at approval, §4). A miss on a job that is still pre-approval / uncaptured stays pending (reported as deferred by the sweep) and refunds on the first sweep after capture — design the UAT timing around that, don't expect an instant refund on an unapproved order.

2 · Footage

# Do Expect
2.1 Open the job → upload page Drag-drop is the obvious primary path
2.2 Upload a real video file (any mp4) Progress, resumable, lands in the file list
2.3 (Optional) paste a WeTransfer/URL link instead Import chip shows progress → done

2b · Voice notes for your editor (0034)

Precondition: migration 0034 live; the job in an early state (NEW/ASSIGNED/IN_PROGRESS — i.e. before review). dorian@… owns the job. Voice notes are a brief-intake / early-edit tool — client-authored only (an editor can never record one). What the editor sees is covered in the editor sheet §3b.

# Do Expect
2b.1 On the job page while the edit is being prepared, find "Voice notes for your editor" Section shows with helper "Optional — record a quick note telling your editor what you want. You can add more later." and a "Record a voice note" button
2b.2 Record a short note; watch the meter, then "Stop & save" Live "Recording m:ss / 5:00" counter while recording; then "Saving your voice note…"; the note then appears with its own audio player + a timestamp
2b.3 Record again The button now reads "Add another note"; the new note APPENDS — the earlier one is KEPT (full history, newest first). Nothing is replaced
2b.4 Cap checks Recording auto-stops at 5:00 (5-minute cap). An oversized upload (over 15MB) is refused: "That recording is too large — please record a shorter note."
2b.5 Once the job reaches review/approval and beyond The recorder is no longer offered (recording is limited to the early window); notes already recorded stay listed and playable

The assigned editor plays your latest note prominently (older ones kept under an "Earlier notes" disclosure) and gets a "New brief voice note" email + push on each new note — cross-check editor §3b.

3 · Waiting states (⚙️ editor claims + works the job, ops QC-passes)

# Do Expect
3.1 Watch the job page as the job progresses Client-friendly labels only: "In production", "Quality check" — NEVER raw enums like IN_PROGRESS/QC_REJECTED, never the editor's identity or deadline
3.2 Open /jobs/[id]/review too early Calm "Not ready yet" guard — no player, no error

4 · Review & approve (the money moment)

# Do Expect
4.1 When status = "Ready for your review": open the job Loud CTA to the review page
4.1📧 Check dorian@…'s inbox Email "Wakecut — your edit is ready to review (…)" with a review CTA. Editor never named
4.2 Review page Watermarked preview plays in a framed player, labelled "watermarked preview — your final files are clean"; "N of M revisions left" chip; NO finals visible anywhere
4.3 Try "Request changes" with an empty note, then spaces only Button stays disabled until real text
4.4 Request a change with a note Status → "Revisions under way"; your note echoed back; ⚙️ editor sees the note, re-submits; ops QC-passes again
4.5 Back in review: count decremented ("N−1 of M") Correct arithmetic
4.6 Approve → confirmation modal Designed modal (not a browser popup): "Approving releases your payment and your final files." Escape closes it; nothing charged yet
4.7 Confirm approve Page flips to "Approved — your final files are ready"; finals section appears; downloads work and are CLEAN (no watermark)
4.7📧 Check dorian@…'s inbox Delivery email "Wakecut — your files are ready (…)". Exactly ONE arrives even though delivery is automatic on approval (auto + manual paths share one dedupe key)
4.8 Stripe dashboard Payment now captured (charged); ⚙️ editor's payout appears in their workspace
4.9 Log in as rp.client2@example.com (non-participant) and try the same job/review URLs 404 — never someone else's job

4b · Rate your edit (0037) + the high-rating tie-in (#79)

Precondition: the job is APPROVED or DELIVERED (post §4), an editor is set, migration 0037 live. The rating is one per job, immutable, and pseudonym-only — a client never sees the editor's real name.

# Do Expect
4b.1 On the delivered job page find "How was your edit?" Prompt "Rate your experience with {pseudonym}. Optional — you can skip this anytime." — 5 stars + an optional comment ("Add a comment (optional)", capped at 2000 chars). Only the editor's pseudonym shown
4b.2 Skip it (just navigate away without rating) Nothing blocks you — rating is skippable by design; approval/delivery already stand
4b.3 Pick stars ("Submit rating" stays disabled until a star is chosen), optionally comment, submit Button shows "Sending…", then flips to the done view: "Thanks for rating your edit." with your stars read-only and "You rated {pseudonym} N out of five" + your comment quoted back
4b.4 Reload / revisit the job The rating is IMMUTABLE — the already-rated view shows your own stars; you cannot re-rate. A forced re-submit is rejected ("You've already rated this edit.")
4b.5 Rate 4 or 5 stars (on a job whose editor you could re-request) The done view shows the tie-in: "Want {pseudonym} on your next edit? Request them again when you order (+£X)" linking to /order (the specify-editor add-on, §1b)
4b.6 Rate 1–3 stars (on another delivered job) NO tie-in — the "work with them again" offer is absent on a low rating

The 4-5★ tie-in only renders when the tenant actually sells the specify_editor extra (priced above zero in the order currency) and you are eligible to re-request that editor — otherwise the done view has no offer even after a 5★ rating. The (+£X) figure is the live tenant price, not an invented number.

5 · Edge checks (optional but valuable)

5b · Pushback intervention copy (Phase 6b — ⚙️ needs ops)

Only appears when a pool job stalls and ops releases the prompt. To see it: ⚙️ on a fresh unclaimed order, have editors pass it (or ops opens /ops → the job → "release pushback prompt"), then reload the client job page.

# Do Expect
5b.1 Open the job showing the intervention card Headline "A small change could get this picked up faster"; honest body ("editors choose the jobs they take on… we're telling you straight"). NEVER "rejected"/"no one wants it"; NO editor identity, NO count of who passed or why
5b.2 Read the three levers Give it more time / Adjust the brief / Boost the pay — boost only shows if ops set an amount, and its button reads "Boost by £X" with the real amount (no invented number)
5b.3 Pick a lever (e.g. extend) Job goes straight back to the pool; calm confirmation, no blame framing

6 · iOS app (installable client app — 2026-07-11)

Prerequisite (once, before this section): the Supabase magic-link email template must contain {{ .Token }} (Dashboard → Auth → Email Templates), otherwise sign-in emails carry no code and step 6.4 cannot pass. Device: a real iPhone, Safari.

# Do Expect
6.1 Safari → the site root, logged out Dismissible hint appears: install via Share → Add to Home Screen (it must NOT appear on desktop)
6.2 Share → Add to Home Screen from any client page App named "Wakecut" with the engine icon; opens full-screen (no Safari chrome), status bar/notch area looks intentional, nothing clipped
6.3 Dismiss the install hint in Safari, reload Hint stays gone (per-app dismissal)
6.4 In the INSTALLED app: sign in as dorian@… — request the magic link, then use "enter the code from the email" with the code (8 digits) from the same email Signed in INSIDE the app, landed per your role. (Tapping the emailed link instead opens Safari, not the app — that's exactly why the code path exists)
6.5 Re-run the spine in the app: /order → pay (Stripe Checkout) → upload an mp4 → job list Checkout completes and returns into the app; drag-drop upload path degrades to the photo picker; keyboard never hides inputs
6.6 Kill the app, reopen Still signed in (session survives)

Pass bar (§6): the app installs with the right identity, the code path signs you in without ever leaving it, and the §1–§4 promises hold identically inside standalone mode.

Pass bar: every promise in §4 holds, no raw enum/editor identity ever visible, payment state in Stripe matches the UI story at every step, and each lifecycle email (§1.5📧/§4.1📧/§4.7📧) arrives exactly once, correctly branded, naming no editor.

Phase-10 pass bar (§1b/§2b/§4b): the specify-editor add-on shows only for a returning client (hidden first-order and for unpriced-EUR), and a miss refunds only the extra with the base charge untouched; voice notes append (never replace) and stay under the early-window/15MB/5-min caps; the rating is one-per-job immutable and pseudonym-only, with the re-request tie-in present on 4-5★ and absent on ≤3★. Every one of these surfaces names no editor and shows no invented price — all money/label copy is the live tenant config.