Validation: Keycloak registration flow (register.ftl + Rails wiring)
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.