Promote dev → uat: GRO-2359 OOBE portal-creation routing #76

Merged
Flea Flicker merged 1 commits from promote/GRO-2359-dev-to-uat into uat 2026-06-11 16:44:51 +00:00
Member

Phase 2 — dev → uat: GRO-2359 OOBE portal-creation routing

Promotion branch: promote/GRO-2359-dev-to-uat cut from origin/uat (bfe3ccf3, frozen GRO-2358 promotion) with the dev squash 250c7a5a cherry-picked on top. Net diff is exactly the GRO-2359 OOBE fix — no UAT_PLAYBOOK conflict (the dev squash was on the same 5.25.5–6e section rewrite, and uat is a strict superset of dev from the GRO-2358 promotion).

What's in this PR

  • src/portal/OOBE.tsx — new OOBE component (form: name, phone, address, notes) with shared signOut().
  • src/portal/CustomerPortal.tsx — bridge 404 mounts OOBE inline (not the legacy no-access card).
  • src/App.tsx — new /onboarding route for direct deep-link access to OOBE.
  • src/__tests__/portal.test.tsx — 7 new OOBE tests + 2 P1 signOut tests reworked to use ?noAccess=deleted-portal (the only surviving path to the no-access card).
  • UAT_PLAYBOOK.md — §5.25.5–6e rewritten.

Paired API PR

api#212 was already merged to api dev (commit cdeebec); the api dev→uat promotion is a separate PR (same branch name promote/GRO-2359-dev-to-uat).

SDLC

Handing to QA (Lint Roller) for review. On approval → self-merge → spawn UAT regression (Shedward) + Security review (Barkley) → uat→main PR (CTO Gitea review per uat-to-main-requires-cto-gitea-review-when-whitelist-fixed).

## Phase 2 — dev → uat: GRO-2359 OOBE portal-creation routing Promotion branch: `promote/GRO-2359-dev-to-uat` cut from `origin/uat` (`bfe3ccf3`, frozen GRO-2358 promotion) with the dev squash `250c7a5a` cherry-picked on top. Net diff is exactly the GRO-2359 OOBE fix — no UAT_PLAYBOOK conflict (the dev squash was on the same `5.25.5–6e` section rewrite, and uat is a strict superset of dev from the GRO-2358 promotion). ### What's in this PR - `src/portal/OOBE.tsx` — new OOBE component (form: name, phone, address, notes) with shared signOut(). - `src/portal/CustomerPortal.tsx` — bridge 404 mounts OOBE inline (not the legacy no-access card). - `src/App.tsx` — new `/onboarding` route for direct deep-link access to OOBE. - `src/__tests__/portal.test.tsx` — 7 new OOBE tests + 2 P1 signOut tests reworked to use `?noAccess=deleted-portal` (the only surviving path to the no-access card). - `UAT_PLAYBOOK.md` — §5.25.5–6e rewritten. ### Paired API PR [api#212](https://git.farh.net/groombook/api/pulls/212) was already merged to api dev (commit `cdeebec`); the api dev→uat promotion is a separate PR (same branch name `promote/GRO-2359-dev-to-uat`). ### SDLC Handing to QA (Lint Roller) for review. On approval → self-merge → spawn UAT regression (Shedward) + Security review (Barkley) → uat→main PR (CTO Gitea review per `uat-to-main-requires-cto-gitea-review-when-whitelist-fixed`).
Flea Flicker added 1 commit 2026-06-11 16:35:59 +00:00
feat(GRO-2359): route Authentik new-SSO users into OOBE (web)
CI / Test (pull_request) Successful in 21s
CI / Lint & Typecheck (pull_request) Successful in 29s
CI / Build & Push Docker Image (pull_request) Successful in 15s
a12bf019fa
The post-auth handler in CustomerPortal previously rendered the
"Portal access not configured" card when the SSO bridge returned 404
(no client row for the user's email). That trapped first-time SSO
users on a dead-end screen with no path to portal creation.

This change routes the 404 to a new OOBE component (src/portal/OOBE.tsx)
that drives portal creation:
  * Mounts inline inside CustomerPortal so the post-auth flow stays
    inside the portal render tree (no App-level router needed).
  * Also reachable as a direct deep-link via the new /onboarding route
    in App.tsx (for grooming admins or recovery flows).
  * Submits to a new POST /api/portal/clients-from-auth endpoint in
    groombook-api (companion commit) that creates a fresh client row
    bound to the Better Auth email. 409 means the email already has a
    portal record — the OOBE shows a portal-selection message.
  * Uses the canonical shared signOut() from lib/auth-client (GRO-2358
    invariant) for the Sign out button.
  * Full window.location.href reload on submit success to reset the
    bridge's cached state and land the user in their portal.

The no-access card itself is preserved for the deep-link deleted-portal
case (a customer whose portal was disabled/deleted), signalled via
?noAccess=deleted-portal on a portal sub-route. The OOBE handles the
first-time-creation case; the no-access card handles the "had a portal
but lost it" case.

Test coverage:
  * "routes to /onboarding when session-from-auth returns 404 (GRO-2359)"
    — proves the post-auth 404 mounts the OOBE inline, not the legacy
    no-access card.
  * 6 new OOBE tests: render from direct link, name prefill, form
    submission, 409 portal-selection, required-name validation, shared
    signOut(), redirect on no-session.
  * P1 no-access tests reworked to use ?noAccess=deleted-portal so the
    GRO-2358 signOut invariant is still verified on the only surviving
    path to the no-access card.

UAT_PLAYBOOK §5.25.5–6e rewritten to cover the OOBE flow (form submit,
409, deep-link mount, deleted-portal no-access card).

Paired with the api PR on feature/2357-p2-portal-clients-from-auth.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
(cherry picked from commit 250c7a5ac9)
Lint Roller approved these changes 2026-06-11 16:42:00 +00:00
Lint Roller left a comment
Member

QA approved. CI green (lint, typecheck, test, build). Code review PASS.

  • OOBE.tsx: auth-gated, shared signOut(), onCompleted prop for testability, name prefill from Better Auth session, 409/network error handling correct.
  • CustomerPortal.tsx: 404 bridge now mounts OOBE inline; deleted-portal case preserved via ?noAccess=deleted-portal. Full reload on onCompleted correctly resets bridge state.
  • App.tsx: /onboarding excluded from showCustomerPortal; standalone OOBE route renders correctly.
  • Tests: 7 new OOBE tests + updated SSO bridge tests for the 404→OOBE routing change. Coverage complete.
  • UAT_PLAYBOOK.md: §5.25.5–6e rewritten with 5 new test cases including deleted-portal deep-link (TC-WEB-5.25.6e).
QA approved. CI green (lint, typecheck, test, build). Code review PASS. - OOBE.tsx: auth-gated, shared signOut(), onCompleted prop for testability, name prefill from Better Auth session, 409/network error handling correct. - CustomerPortal.tsx: 404 bridge now mounts OOBE inline; deleted-portal case preserved via ?noAccess=deleted-portal. Full reload on onCompleted correctly resets bridge state. - App.tsx: /onboarding excluded from showCustomerPortal; standalone OOBE route renders correctly. - Tests: 7 new OOBE tests + updated SSO bridge tests for the 404→OOBE routing change. Coverage complete. - UAT_PLAYBOOK.md: §5.25.5–6e rewritten with 5 new test cases including deleted-portal deep-link (TC-WEB-5.25.6e).
Flea Flicker merged commit a7f2e2e6b3 into uat 2026-06-11 16:44:51 +00:00
Flea Flicker deleted branch promote/GRO-2359-dev-to-uat 2026-06-11 16:44:51 +00:00
Sign in to join this conversation.