Review: O1 — Marcus onboarding: browser-SSO + dashboard walkthrough (final ticket)

review-1074-2026-04-22 Review

review approved

Verdict: APPROVED

Final ticket in the story:reachable arc for westside-streamlit. Validates Marcus can independently see his four data surfaces (contracts, jerseys, monthly, tournaments) via browser SSO. Two informal review rounds already passed; this is the canonical backlog→todo gate review.

Template Completeness

Issue type: Feature (per ### Type header). Routed to template-issue-feature.
  • [x] Type — present
  • [x] Lineage — present (final ticket in chain, supersedes orphan note)
  • [x] Repo — present (forgejo_admin/westside-streamlit)
  • [x] User Story — present (Marcus, head coach, 4 data surfaces)
  • [x] Context — present (browser SSO, no Tailscale client, milestone framing)
  • [x] File Targets — present, explicitly "No repo files touched" with external state change scoped (Keycloak admin role)
  • [x] Acceptance Criteria — 7 items, mix of objective + observational
  • [x] Test Expectations — present (screenshot, video/screenshot, retro tracking)
  • [x] Constraints — present (no Tailscale client, no docs unless gap, no SQL training, scope-fenced)
  • [x] Checklist — present
  • [x] Related — present (project, story, sibling stories, feedback notes, blocked-by chain)

Traceability

  • [x] story:reachable label — Dashboard Reachable from Phone
  • [x] story note verified — story-westside-streamlit-reachable (id 1401) exists; entry present in project-westside-streamlit user-stories table (row "reachable" → Platform + Head Coach)
  • [x] arch:keycloak-oidc label — Keycloak OIDC component
  • [ ] arch note MISSING — arch-keycloak-oidc not found via search_notes. Architectural decisions ARE documented inline in project-westside-streamlit key-decisions (same-realm SSO, in-app integration via streamlit-keycloak, admin realm role gating, canonical hostname). [SCOPE] Create arch-keycloak-oidc note covering realm topology, client registration, role mapping, JWT claim contract — shared across westside-streamlit children #10/#11/#12 and this onboarding ticket. Non-blocking; previously flagged on reviews 938, 961, 962.
  • [x] Forgejo issue — westside-streamlit#16, open, body matches ticket title

File Targets

Explicitly zero repo files. External state change only:
  • [x] Keycloak realm westside-basketball — assign admin realm role to Marcus's user via Keycloak admin console (https://keycloak.tail5b443a.ts.net). Aligns with project arch key-decision: same-realm SSO + admin realm role gating.
  • [x] Files NOT to touch listed defensively (app.py, Dockerfile, requirements.txt, terraform, pal-e-deployments).

Repo Placement

OK. Filed on westside-streamlit even though the change is in Keycloak; this is correct because the ticket completes the project's story:reachable arc and validates the reachable user story's acceptance criteria. Keycloak realm/client provisioning is already covered separately by pal-e-services#61 (S2). No second issue required.

Dependencies

Cross-repo blocker chain explicitly enumerated in body:
  • Substrate: pal-e-services#60 (S1, Harbor + ArgoCD Application — open, backlog) and #61 (S2, Keycloak client tf — open, backlog)
  • CI/ingress: westside-streamlit#3 (Woodpecker pipeline — open, todo) and #6 (Tailscale funnel — open, backlog)
  • Content surfaces: westside-streamlit#14 Monthly (open, backlog) and #15 Tournament (open, backlog)
  • DB: basketball-api#510 migration 048 GRANT tournament tables (open, backlog)
All seven blockers verified open via Forgejo API. The body's claim "All four data surfaces must be live for this ticket to validate against its acceptance criteria" is accurate: contracts (already present in app), jerseys (already present), monthly (#14 + read-only role), tournaments (#15 + #510). Dependencies are appropriately documented; this ticket cannot move beyond todo until the chain clears.

Acceptance Criteria

Seven criteria, all verifiable:
  • Objective + tool-checkable: Keycloak role mapping (admin console screenshot), URL load on phone Safari (visual), Keycloak login first-attempt success (visual), 4 data surfaces render with correct enum coverage.
  • Observational: in-person sort/filter/copy-paste demo, 5 unassisted ops tasks over 1 week, retro backlog filing.
  • Test commands: explicitly "none (no code; verification is observational)" — appropriate for an onboarding ticket.
AC #6 (5 unassisted tasks in week 1) and AC #7 (week-1 retro tickets) are time-deferred — they only resolve after a one-week observation window. That's expected for a final-arc ticket; the ticket can move to done only after the retro is filed.

Blast Radius

Bounded:
  • Granting admin realm role to Marcus exposes the dashboard to him only — no spillover. Other parents/coaches in the realm continue to hit 403.
  • App-layer + auth-layer + DB-layer read-only enforcement (per project arch key-decisions: defense in depth) means Marcus cannot accidentally write data even with admin role.
  • No third-party comms, no email send, no PII export. Safe per feedback_funnel_requires_auth — funnel is Keycloak-gated.
  • Constraint "do not onboard other Westside staff" properly fences scope; future staff is a follow-up story.

Decomposition Assessment

5-minute rule: file targets = 0, repos touched = 0 (external state only), AC count = 7 but five are observation/retro flags rather than discrete work units. Active work = one Keycloak admin-console click (role assignment) + one in-person walkthrough + one date-tracking checklist update. Estimated agent + human time: well under 5 minutes for execution; week-long passive observation is not work-blocking. No decomposition needed.

Recommendation

  • [SCOPE] Create arch-keycloak-oidc architecture note (realm topology, client registration pattern, admin role mapping, streamlit-keycloak JWT claim contract). Non-blocking for this ticket — decisions already inlined on project-westside-streamlit. Previously flagged on reviews 938/961/962. File as a separate doc-fix backlog item; do not block O1 advancement on it.
  • [SCOPE] (informational, per caller context) The misframed user-stories table on project-westside-streamlit is a separate doc-fix item and is NOT a blocker for this ticket. Confirmed.
This ticket is APPROVED to advance from backlogtodo. It will remain todo until the upstream blocker chain (S1, S2, #3, #6, #14, #15, #510) clears. Both READY and APPROVED are passing verdicts per the check-board-advance hook.