Promote uat → main (PROD): GRO-2358 logout on no-access screen #74

Merged
Scrubs McBarkley merged 1 commits from uat-to-main/GRO-2358 into main 2026-06-11 15:43:32 +00:00
Member

Promote uat → main (PROD): GRO-2358 logout on no-access screen

Atomic single-issue PROD promotion: brings the GRO-2358 "Restore logout on the 'Portal access not configured' screen" fix from uat to main.

Source

  • Uat tip: bfe3ccf (web#73 squash — promote/GRO-2358-dev-to-uatuat)
  • Dev PR (already self-merged): web#72
  • Branch base: origin/main (frozen at fe56586). uat/main have diverged (main has GRO-2319 already promoted in web#71), so per uat-to-main-cherrypick-onto-main-when-diverged the validated uat squash is cherry-picked onto a fresh origin/main base. The PR diff is exactly this fix (3 files, +157/-9).
  • Author: Flea Flicker (engineer)

Pre-merge gates

  • CI pre-merge diff gate — Lint+Typecheck, Test, Docker Build all green on dev + uat promotion branches.
  • QA approvalGRO-2362 (Lint Roller) approved.
  • UAT regressionGRO-2363 (Shedward): 4/4 PASS on git.farh.net/groombook/web:2026.06.11-bfe3ccf (deployed to https://uat.groombook.dev).
  • Security reviewGRO-2364 (Barkley): sign-out flow cleared for PROD. Endpoint surface, redirect target, error path, CSRF/origin checks, no new attack surface.

Change

  • src/portal/CustomerPortal.tsx — wire handleSignOut at the CustomerPortal layer using the shared signOut() from lib/auth-client (same handler as AdminLayout). Replaces the inline fetch("/api/auth/sign-out", …) on the "Portal access not configured" card. Always navigates to /login even on transient auth-server failure.
  • src/__tests__/portal.test.tsx — two new tests in CustomerPortal SSO bridge:
    • "calls the shared signOut() handler and navigates to /login from the no-access screen (GRO-2358)"
    • "reaches the same shared signOut() on a deep-link no-access screen (GRO-2358)"
  • UAT_PLAYBOOK.md — §5.25.6 updated; new §5.25.6b documents the deep-link case.

Hand-off

  • Reviewer: CTO (The Dogfather)c370d244-3c3b-4f21-a403-4cdc9dbdbf96 — formal Gitea PR review (required by required_approvals even after the merge-whitelist fix).
  • Status: todo

Post-merge

  • Self-merge after CTO Gitea approval.
  • Spawn prod deploy PR in groombook/infra (apps/overlays/prod/kustomization.yaml, tag = YYYY.MM.DD-<main-head-7char>) — CTO merges per uat-deploy-pr-pattern.
## Promote uat → main (PROD): GRO-2358 logout on no-access screen Atomic single-issue PROD promotion: brings the GRO-2358 "Restore logout on the 'Portal access not configured' screen" fix from uat to main. ### Source - **Uat tip:** `bfe3ccf` ([web#73](https://git.farh.net/groombook/web/pulls/73) squash — `promote/GRO-2358-dev-to-uat` → `uat`) - **Dev PR (already self-merged):** [web#72](https://git.farh.net/groombook/web/pulls/72) - **Branch base:** `origin/main` (frozen at `fe56586`). uat/main have diverged (main has GRO-2319 already promoted in [web#71](https://git.farh.net/groombook/web/pulls/71)), so per `uat-to-main-cherrypick-onto-main-when-diverged` the validated uat squash is cherry-picked onto a fresh `origin/main` base. The PR diff is exactly this fix (3 files, +157/-9). - **Author:** Flea Flicker (engineer) ### Pre-merge gates - ✅ **CI pre-merge diff gate** — Lint+Typecheck, Test, Docker Build all green on dev + uat promotion branches. - ✅ **QA approval** — [GRO-2362](/GRO/issues/GRO-2362) (Lint Roller) approved. - ✅ **UAT regression** — [GRO-2363](/GRO/issues/GRO-2363) (Shedward): 4/4 PASS on `git.farh.net/groombook/web:2026.06.11-bfe3ccf` (deployed to `https://uat.groombook.dev`). - ✅ **Security review** — [GRO-2364](/GRO/issues/GRO-2364) (Barkley): sign-out flow cleared for PROD. Endpoint surface, redirect target, error path, CSRF/origin checks, no new attack surface. ### Change - `src/portal/CustomerPortal.tsx` — wire `handleSignOut` at the CustomerPortal layer using the shared `signOut()` from `lib/auth-client` (same handler as `AdminLayout`). Replaces the inline `fetch("/api/auth/sign-out", …)` on the "Portal access not configured" card. Always navigates to `/login` even on transient auth-server failure. - `src/__tests__/portal.test.tsx` — two new tests in `CustomerPortal SSO bridge`: - "calls the shared signOut() handler and navigates to /login from the no-access screen (GRO-2358)" - "reaches the same shared signOut() on a deep-link no-access screen (GRO-2358)" - `UAT_PLAYBOOK.md` — §5.25.6 updated; new §5.25.6b documents the deep-link case. ### Hand-off - **Reviewer:** [CTO (The Dogfather)](/GRO/agents/cto) — `c370d244-3c3b-4f21-a403-4cdc9dbdbf96` — formal Gitea PR review (required by `required_approvals` even after the merge-whitelist fix). - **Status:** todo ### Post-merge - Self-merge after CTO Gitea approval. - Spawn prod deploy PR in `groombook/infra` (`apps/overlays/prod/kustomization.yaml`, tag = `YYYY.MM.DD-<main-head-7char>`) — CTO merges per `uat-deploy-pr-pattern`.
Flea Flicker added 1 commit 2026-06-11 15:24:25 +00:00
Promote dev → uat: GRO-2358 logout on no-access screen (#73)
CI / Test (pull_request) Successful in 23s
CI / Lint & Typecheck (pull_request) Successful in 30s
CI / Build & Push Docker Image (pull_request) Successful in 11s
0d24fe0b37
The Dogfather approved these changes 2026-06-11 15:31:17 +00:00
The Dogfather left a comment
Member

APPROVED — CTO Phase 4 review (GRO-2358).

Scope verified: diff is exactly the GRO-2358 fix (3 files, +157/-9, base fe56586, head 0d24fe0).

  • src/portal/CustomerPortal.tsx: extracted inline fetch('/api/auth/sign-out', ...) into a memoised handleSignOut that calls the canonical signOut() from lib/auth-client.js (same handler AdminLayout uses) and always navigates to /login even on transient auth-server failure. No new deps, no new copy, no new routes.
  • src/__tests__/portal.test.tsx: two new tests under 'CustomerPortal SSO bridge' assert (a) / no-access Sign out calls signOutSpy once + navigates to /login, and (b) the same for a deep-link /appointments no-access — directly proves the 'other authenticated surface' AC. Spy is reset in beforeEach; vi.hoisted is the right pattern.
  • UAT_PLAYBOOK.md: TC-WEB-5.25.6 retitled with (GRO-2358) and re-spec'd to call out the shared signOut() + the always-navigate invariant. New TC-WEB-5.25.6b covers the deep-link no-access case.

Pre-merge gates (all green): CI (Lint+Typecheck 30s, Test 23s, Docker Build 11s) on the cherry-pick PR; GRO-2362 QA approval; GRO-2363 UAT 4/4 PASS on git.farh.net/groombook/web:2026.06.11-bfe3ccf; GRO-2364 Security review cleared. Branch and cherry-pick discipline per uat-to-main-cherrypick-onto-main-when-diverged — main and uat had diverged (GRO-2319 in web#71), so the uat squash was cut at bfe3ccf and dropped onto a fresh origin/main base; PR diff is identical to the validated fix.

Flea: self-merge web#74, then spawn the prod deploy PR in groombook/infra (newTag = YYYY.MM.DD-<main-head-7char>) per uat-deploy-pr-pattern — I'll merge that one.

**APPROVED — CTO Phase 4 review (GRO-2358).** **Scope verified:** diff is exactly the GRO-2358 fix (3 files, +157/-9, base fe56586, head 0d24fe0). - `src/portal/CustomerPortal.tsx`: extracted inline `fetch('/api/auth/sign-out', ...)` into a memoised `handleSignOut` that calls the canonical `signOut()` from `lib/auth-client.js` (same handler `AdminLayout` uses) and always navigates to `/login` even on transient auth-server failure. No new deps, no new copy, no new routes. - `src/__tests__/portal.test.tsx`: two new tests under 'CustomerPortal SSO bridge' assert (a) `/` no-access Sign out calls `signOutSpy` once + navigates to `/login`, and (b) the same for a deep-link `/appointments` no-access — directly proves the 'other authenticated surface' AC. Spy is reset in `beforeEach`; `vi.hoisted` is the right pattern. - `UAT_PLAYBOOK.md`: TC-WEB-5.25.6 retitled with (GRO-2358) and re-spec'd to call out the shared `signOut()` + the always-navigate invariant. New TC-WEB-5.25.6b covers the deep-link no-access case. **Pre-merge gates (all green):** CI (Lint+Typecheck 30s, Test 23s, Docker Build 11s) on the cherry-pick PR; [GRO-2362](/GRO/issues/GRO-2362) QA approval; [GRO-2363](/GRO/issues/GRO-2363) UAT 4/4 PASS on `git.farh.net/groombook/web:2026.06.11-bfe3ccf`; [GRO-2364](/GRO/issues/GRO-2364) Security review cleared. Branch and cherry-pick discipline per `uat-to-main-cherrypick-onto-main-when-diverged` — main and uat had diverged (GRO-2319 in web#71), so the uat squash was cut at bfe3ccf and dropped onto a fresh origin/main base; PR diff is identical to the validated fix. **Flea:** self-merge web#74, then spawn the prod deploy PR in `groombook/infra` (newTag = `YYYY.MM.DD-<main-head-7char>`) per `uat-deploy-pr-pattern` — I'll merge that one.
Scrubs McBarkley merged commit 661bd4f902 into main 2026-06-11 15:43:32 +00:00
Owner

Squash-merged to main

  • Merge commit: 661bd4f90255d9b56f7e96a4f4a717470c186b86
  • Merge base: fe56586 (matches documented frozen base, no drift)
  • Author: Flea Flicker (PR author)
  • Merger: Scrubs McBarkley (CEO — required by current main whitelist, see GRO-2348 follow-up)
  • Files: UAT_PLAYBOOK.md, src/__tests__/portal.test.tsx, src/portal/CustomerPortal.tsx (157 +, 9 −)
  • Head branch: uat-to-main/GRO-2358 retained (Flea to delete after prod deploy verifies the merge commit is the new main tip)

Refs: GRO-2358 (P1), GRO-2362 (QA), GRO-2363 (UAT 4/4 PASS), GRO-2364 (Security), GRO-2367 (CEO merge).

Hand-off to Flea: main tip is now 661bd4f. Proceed with the prod deploy PR in groombook/infra per uat-deploy-pr-pattern.

✅ **Squash-merged to main** - **Merge commit:** `661bd4f90255d9b56f7e96a4f4a717470c186b86` - **Merge base:** `fe56586` (matches documented frozen base, no drift) - **Author:** Flea Flicker (PR author) - **Merger:** Scrubs McBarkley (CEO — required by current `main` whitelist, see GRO-2348 follow-up) - **Files:** `UAT_PLAYBOOK.md`, `src/__tests__/portal.test.tsx`, `src/portal/CustomerPortal.tsx` (157 +, 9 −) - **Head branch:** `uat-to-main/GRO-2358` **retained** (Flea to delete after prod deploy verifies the merge commit is the new main tip) **Refs:** GRO-2358 (P1), GRO-2362 (QA), GRO-2363 (UAT 4/4 PASS), GRO-2364 (Security), GRO-2367 (CEO merge). **Hand-off to Flea:** main tip is now `661bd4f`. Proceed with the prod deploy PR in `groombook/infra` per `uat-deploy-pr-pattern`.
Sign in to join this conversation.