☰ MenuUAT Editor

UAT β€” editor workflow (Phase 6–10 acceptance)

Test account: rp.editor@example.com (approved editor, Wakecut, magic-link). Site: https://wakecut.com Runs opposite docs/ops/UAT-CLIENT-WALKTHROUGH.md (client = dorian@redpoint-vision.com) and the ops console (admin = man_on_rock@redpoint-vision.com). Use separate browser profiles.

The promises this flow must keep: pay/brief visible before you commit, no client contact ever, payouts per job via Stripe with nothing blocked while you set them up.

🧱 Phase-10 migration prerequisite. The new sections (Β§2b held jobs, Β§3b voice notes) and the operator notes (Β§8) depend on migrations 0034–0039, which the shared dev/prod DB was last verified below (at 0033). Until the operator applies them, the surfaces probe-and-skip (stay dark) by design. Confirm the live level first (rule 8: probe the object, don't trust docs).

πŸ“§ Editor emails (Phase 7) β€” verify via the notifications table, not an inbox. The editor test account is rp.editor@example.com, a non-deliverable @example.com address, so editor-facing emails (job_assigned, revision_requested, qc_rejected, payout_paid) won't land in a real inbox. Verify them as the admin (man_on_rock@…): the notifications table is admin-readable β€” one row per event, status = sent (or sendingβ†’sent), recipient = the editor address, unique dedupe_key. Substitute a real editor inbox if you want to eyeball the rendered mail. Requires RESEND_API_KEY in the Vercel prod env (rotate the chat-transited keys first); migration 0020 is already live.

1 Β· Payout setup (Stripe Connect β€” new)

# Do Expect
1.1 Log in β†’ /workspace Banner: "Payouts run on Stripe. Set up once, get paid per job." β€” informational, nothing else is blocked
1.2 "Set up payouts" Redirects to Stripe-HOSTED onboarding (test mode: fake data is fine, use test SSN/IBAN prompts as offered)
1.3 Abandon halfway, return to /workspace Banner switches to "Almost there β€” Stripe needs one more detail" + "Finish setup"; you can still claim/work jobs
1.4 Finish onboarding Banner gone; quiet "Payouts enabled" chip in the header (may take a moment β€” webhook-driven)

2 Β· Job board (claim)

# Do Expect
2.1 /board Pool jobs as cards: pay, deadline, and brief visible BEFORE accepting. No client name/identity
2.2 Tap Pass on a card Reveals optional pass-reason chips β€” "Timeframe too tight" / "Scope too big" / "Footage quality" / "Not my skill set" / "Other" β€” plus "Pass without a reason". Copy is tenant-config (Phase 6b slice 3), values unchanged. Either way the card leaves the board and stays gone on reload
2.2a If any card carries a boost badge Label reads "Boosted pay" (not "Rescued"/"Boosted"); the pay figure is the real boosted amount
2.3 Claim the UAT job (the one dorian created) Instant assign; deadline auto-set from the package turnaround; job appears in /workspace. No assignment email β€” a board self-claim deliberately doesn't email (only an admin assigning you fires "New job assigned"; check the notifications table shows no job_assigned row for this self-claim)
2.4 (If a second editor account is handy) try claiming the same job simultaneously Exactly one wins; the loser gets a clean conflict message, not an error dump

2b Β· Held jobs β€” specify-editor continuity (0038)

Precondition (βš™οΈ + operator setup): a client (dorian@…) placed a specify-editor order naming this editor's pseudonym (client sheet Β§1b) β€” dorian@… must have a prior delivered edit from rp.editor@… for the pseudonym to be offerable. Migration 0038 live; the hold window still open (tenant billing_config.specify_editor_hold_hours, default 48h).

# Do Expect
2b.1 On /board as rp.editor@…, find the held job It carries a "reserved for you" chip (hover: "A repeat client asked to work with you again β€” reserved for you for a limited window before it opens to the pool.") and sorts to the top (held-for-me first). Still no client identity
2b.2 During the hold window, from another editor account The held job is NOT visible to other editors β€” only you see it until the window expires (defence-in-depth: a hand-crafted claim by anyone else is rejected, "this job is reserved for another editor right now")
2b.3 Claim it Instant assign β€” you still claim it yourself, exactly like any board job; it is never auto-assigned
2b.4 If you do NOT claim before the window ends The job simply opens to the whole pool (nothing on your side changes); the client's add-on auto-refunds client-side β€” you see nothing about that money

No notification tells you a job is held for you β€” no email, no push. The only signal is the board chip, so an editor learns of a reserved job only by opening /board. That is deliberate; note it, don't log it as a missing email.

3 Β· Work the job

# Do Expect
3.1 Open the job in /workspace Full brief rendered, client footage downloadable one-click, client identity limited to what the brief needs
3.2 "Start work" Status ASSIGNED β†’ IN_PROGRESS
3.3 Upload panel Three distinct paths: draft / watermarked preview / final (new). Upload one of each (the "preview" should be a watermarked export; final = clean)
3.4 Submit for QC Status β†’ IN_REVIEW; βš™οΈ admin QC-passes in /ops/jobs/[id]
3.4πŸ“§ βš™οΈ If admin QC-rejects instead (with a note) Editor gets "Changes needed before review (…)" carrying the QC note verbatim; a second, differently-worded rejection sends a SECOND email (keyed by occurrence, not revision count). Verify via the notifications table
3.5 If the client requests changes The revision note arrives as written instructions on the job; rework β†’ resubmit
3.5πŸ“§ On that revision request Editor gets "Revision requested (…)" with the client's note relayed verbatim β€” and NOTHING else about the client (no name, no company, no other brief text). Verify via the notifications table

3b Β· Client voice notes in your workspace (0034)

Precondition: dorian@… recorded β‰₯1 voice note (client sheet Β§2b); migration 0034 live; you are the assigned editor. Editor-facing playback is double-blind β€” audio only, no client identity, no transcript.

# Do Expect
3b.1 Open the assigned job in /workspace A "Client voice note(s)" section: the newest note plays prominently, captioned "The client's spoken brief for this job." (single) or "The client's LATEST spoken brief (newest of N)." (many)
3b.2 If more than one note exists An "Earlier notes (Nβˆ’1)" disclosure holds the older notes, each with its own player β€” full history kept, nothing overwritten
3b.3πŸ“§ When the client adds a new note You get "New brief voice note (…)" β€” email and push ("The client added a voice note to the brief.", CTA "Open the job"). rp.editor@… is @example.com, so verify via the notifications table (one row, unique dedupe_key per note). Dedupe is per note, so each new note notifies afresh. No client identity in the mail
3b.4 If a note was added before any editor was assigned No email fires (no recipient yet) β€” you simply see it in the workspace when you pick up the job

4 Β· Getting paid (after the client approves)

# Do Expect
4.1 After βš™οΈ client approval: open the job in /workspace Payout card: amount in Β£ (from the package's editor split), state chip Pending β†’ Sent with timestamp
4.1πŸ“§ When the transfer actually succeeds Editor gets "You've been paid (…)" β€” fires ONLY on a confirmed transfer (never on pending/failed), amount in GBP. If a payout first fails then succeeds on admin retry, still exactly ONE email (shared dedupe key). Verify via the notifications table
4.2 Stripe test dashboard β†’ Connect β†’ your test account The transfer exists, amount matches the payout card
4.3 If a payout ever shows "Retrying" (amber) Copy says it's the platform's problem, NO action button for you β€” verify nothing asks the editor to fix money
4.4 Throughout: confirm payout state never blocked claiming or working other jobs Board + workspace fully usable at every payout state

5 Β· Boundary checks

6 Β· iOS app (installable editor app β€” 2026-07-11)

Prerequisite: same as the client sheet's Β§6 β€” {{ .Token }} in the Supabase email template. Device: a real iPhone, Safari.

# Do Expect
6.1 Safari β†’ /workspace (logged in as rp.editor@…) Install hint appears; Share β†’ Add to Home Screen yields a SECOND, distinct app β€” engine-dark identity, NOT named/coloured like the client "Wakecut" app; opens straight on the workspace
6.2 Both apps on the home screen side by side Two clearly different icons/names β€” installing one never replaced or restyled the other; hint dismissals are independent per app
6.3 In the INSTALLED editor app: sign out, then sign back in via the emailed code (not the link) Signed in inside the app, landed on the workspace
6.4 Run the core loop in the app: board card (pay/deadline/brief visible) β†’ claim β†’ open job β†’ download footage β†’ upload a draft All usable at phone width in standalone mode; uploads run in the foreground (backgrounding the app mid-upload may pause it β€” resume on return is acceptable; note what you see)
6.5 Payout card (Β§4) inside the app Renders correctly; Stripe Connect onboarding, if launched, completes in its hosted flow and returns

Pass bar (Β§6): two independent apps with the right identities, code-based sign-in works entirely in-app, and the Β§1–§4 promises hold in standalone mode.

Pass bar: pay-first board holds, all three upload kinds work, the payout card matches Stripe reality, nothing money-related ever blocks or blames the editor, and every editor email (Β§3.4πŸ“§/Β§3.5πŸ“§/Β§4.1πŸ“§) lands once with the client's identity absent.

Phase-10 pass bar (Β§2b/Β§3b/Β§8): a specify-editor job is reserved to you (and hidden from others) for the hold window, claimable only by you, with no notification beyond the board chip; client voice notes play newest-first with history kept and fire one "New brief voice note" alert per note, carrying no client identity; and the board stays byte-identical to Β§2 because supervision is dormant (1E ops UI pending). All double-blind holds.

7 Β· Operator notes β€” Phase 7 crons (admin/system, not an editor click-path)

The two scheduled sweeps are secret-gated and run on Vercel Cron, so they aren't part of the click-through above. Verify separately:

8 Β· Operator notes β€” Phase 10 (editor supervision + partner commissions)

Both are admin/system surfaces, not an editor click-path. Verify separately.

Editor supervision (0039) β€” DORMANT by default

Partner commissions dry-run (0035/0036) β€” ops β†’ finance