Half-onboarded org fixture
Scope: producing the fixture the UX-4 "waiting on owner" banner needs — a non-owner member of an org whose onboarding gates are still tripped (FLOW-002). Not the banner's behavior itself (→ portal-app/onboarding).
Source-checked against optolink-portal @ 7d31d45 and optolink-backend @ 29f8589, 2026-10-06 (
WaitingOnOwnerinsrc/app/(auth)/onboarding/page.tsx: banner text with owner name, fallback string without;RequireOrggates on the onboarding state and routes to/onboarding; the invite endpoint stampspublicMetadata.optoRolebackend-side, and acceptance applies the invitation'soptoRoleto the membership —team.controller.ts,clerk-sync.service.ts). OTP424242and Testing Mode are instance config — see clerk-dev-instance.
Base fixture: [email protected] / Ux357Verify!2026 — owner
of an org parked at wizard step 3 (app-config saved, plan NULL).
- Sign in as the owner →
/settings?tab=team→ invite[email protected]as Viewer (the backend stamps the Clerk invitation withpublicMetadata.optoRole=viewer). - Register the invitee at
/registerusing that+clerk_testemail (password of your choice, OTP424242) → accept the pending org invitation → theorganizationMembership.*webhooks mirror the member and stamppublicMetadata.role=viewer(relay must be live — webhook-event-mirroring, path 1). - As the invitee: open
/—RequireOrgroutes to/onboarding→ step-3 chrome (stepper marks "Your plan") with the info banner "Setup is waiting on your organisation's owner, {owner name}. Ask them to complete configuration & plan selection." — no plan cards mounted. - Direct-API fallback if the relay is down: create the user + membership
via
POST /v1/organizations/{orgId}/memberships(form-encodeduser_id,role=org:member), then stampPATCH …/memberships/{mid}withpublicMetadata={"role":"viewer"}— and expect the banner's owner-name fallback ("your organisation's owner") until the localOrgMemberrow syncs.
Cleanup (cleanup.md): delete the invitee user; the org stays parked at step 3 for reuse.