Validation: Keycloak registration flow (register.ftl + Rails wiring)

validation-59-2026-07-26 Doc

validation pass

Verdict: PASS

Ticket

#59 (board item #1831) — Keycloak registration flow: register.ftl template deployed to Keycloak with ISS branding, phone field in registration form, Rails sessions controller wired for Keycloak callback with three-path Lead resolution and phone sync.
Merged PR: #72 — feat: in-app registration with Keycloak phone field and Lead sync (commit dfe3b8d)

Environment

Production cluster, namespace intelligentstaffingsystems, URL: https://intelligentstaffingsystems.ai. Keycloak at https://keycloak.tail5b443a.ts.net, realm iss.

Tiers Executed

Tier 1 (CI tests) + Tier 3 (production). Labels: type:feature,arch:auth,story:registration,sprint:A.

Checks

# Criterion How Verified Result Evidence
1 register.ftl deployed to Keycloak theme <code>kubectl exec -n keycloak deploy/keycloak -- ls /opt/keycloak/themes/iss/login/register.ftl</code> PASS File exists as symlink (configmap mount). Content verified: FreeMarker template with firstName, lastName, email, phone fields.
2 register.css deployed alongside register.ftl <code>kubectl exec -n keycloak deploy/keycloak -- ls /opt/keycloak/themes/iss/login/resources/css/</code> PASS Both <code>login.css</code> and <code>register.css</code> present in theme resources.
3 Keycloak registration endpoint responds curl to <code>/realms/iss/protocol/openid-connect/registrations</code> with correct client_id and redirect_uri PASS Returns 302 with PKCE error (expected -- PKCE is required and curl does not send code_challenge). Endpoint is live, not 404/500.
4 Rails registration form at /leads/new <code>curl -s https://intelligentstaffingsystems.ai/leads/new</code> PASS HTTP 200. Form contains all expected fields: first_name, last_name, email, phone, business_name, business_description, project_description.
5 Sessions controller: Keycloak callback wiring Code review of <code>app/controllers/sessions_controller.rb</code> PASS Three-path Lead resolution (by sub, email claim, walk-in create). Phone extraction from Keycloak token. Phone sync on login. Role sync from token.
6 Lead model phone validation Code review of <code>app/models/lead.rb</code> PASS <code>PHONE_FORMAT</code> regex validates phone presence and format.
7 CI tests pass (Tier 1) Woodpecker pipeline #188 (latest main push) PASS 481 runs, 1314 assertions, 0 failures, 0 errors, 0 skips. Includes 20+ sessions_controller tests covering: role extraction, lead resolution by sub, email claim with email_verified, walk-in create, phone sync, phone array handling, invalid phone rejection, post-registration redirect, role sync, logout, auth failure.
8 Pod running with correct image <code>kubectl get pods -n intelligentstaffingsystems</code> PASS Pod <code>intelligentstaffingsystems-69c4f699d6-vp89s</code>: Running, 0 restarts, 9h uptime. Image tag <code>b46c433</code> (latest main commit, verified ancestor of PR #72 commit dfe3b8d).
9 ArgoCD sync and health <code>kubectl get application intelligentstaffingsystems -n argocd</code> PASS Sync: Synced, Health: Healthy.

Regression Check

All key routes verified healthy in production:
  • / — 200 (landing page, references registration correctly)
  • /about — 200
  • /leads/new — 200 (registration form)
  • /login — 302 (redirects to App Store, expected)
  • /catalog — 302 (requires auth, expected)
  • /dashboard — 302 (requires auth, expected)
Keycloak pod healthy (Running, 7d11h uptime). No unexpected behavior observed.

Discovered Issues

None. All checks passed. No regressions detected.