Review: Admin user management and promotion

review-1794-2026-07-06b Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — Present (depends on #6, #8, #13)
  • [x] Repo — ldraney/intelligentstaffingsystems
  • [x] User Story — Present (admin pipeline management)
  • [x] Context — Present, references US-6.1, US-6.2, related docs
  • [x] File Targets — Present (9 files listed)
  • [x] Feature Flag — Present ("none")
  • [x] Acceptance Criteria — Present (11 items)
  • [x] Test Expectations — Present (four-case matrix, model tests)
  • [x] Constraints — Present (KeycloakAdminService, PaperTrail, docs-in-PR)
  • [x] Checklist — Present
  • [x] Related — Present (project, blockers, user stories)

Traceability

  • [x] story:admin label — Epic 6 (US-6.1–6.2): "Pipeline list; lead-to-client promotion with audit"
  • [x] story note verified — found in project-iss user-stories section (admin row, Epic 6)
  • [ ] arch:rails note MISSING — [SCOPE] Create architecture note arch-rails for the Rails component in pal-e-docs
  • [x] Forgejo issue — ldraney/intelligentstaffingsystems#14, open

File Targets

  • [x] Gemfile — verified: exists, paper_trail gem not yet present (expected)
  • [x] app/controllers/admin/users_controller.rb — NEW: admin/ dir exists with catalog_controller.rb as pattern
  • [x] app/views/admin/users/index.html.erb — NEW: admin/views dir exists (catalog/ present)
  • [x] app/views/admin/users/show.html.erb — NEW
  • [x] app/assets/stylesheets/admin.css — NEW: stylesheets/ dir exists with 8 existing files
  • [x] db/migrate/xxx_create_versions.rb — NEW: migration, timestamp generated at create time
  • [x] app/models/lead.rb — verified: has role enum (lead/client/admin), promoted_at column in schema
  • [x] config/routes.rb — verified: admin namespace already exists (line 37-39)
  • [x] test/controllers/admin/users_controller_test.rb — NEW: test/controllers/admin/ dir exists
  • [ ] app/services/keycloak_admin_service.rb — MISSING from file targets. Service currently only has get_user and update_user. Keycloak realm role assignment requires the role-mappings endpoint. A new assign_realm_role method is needed. [BODY]

Repo Placement

OK — issue filed on ldraney/intelligentstaffingsystems, all file targets are in the same repo.

Dependencies

  • #6 (Keycloak OIDC auth) — in validation column; auth infrastructure is in the codebase
  • #8 (Lead model, migration, registration form) — in validation column; Lead model exists with role enum and promoted_at
  • #13 (Profile view, edit, and logout) — in validation column; introduced KeycloakAdminService with get_user/update_user
  • All three blockers have delivered code to main. Dependencies are satisfied at the code level, though all are still in validation.

Acceptance Criteria

  • 11 AC items — exceeds the >5 threshold for decomposition
  • AC #5 "Sortable/filterable by role" is underspecified — no mechanism stated (server-side query params vs client-side Stimulus/JS)
  • AC #7 "Promotion updates Keycloak role AND Lead.role" — requires KeycloakAdminService extension not listed in file targets
  • AC #8 "Confirmation dialog before promotion" — mechanism unspecified (JS confirm(), Turbo modal, or separate confirmation page)
  • Test expectations are testable: four-case role matrix pattern is well-established in the codebase

Blast Radius

  • Navigation tab: navigation_helper.rb currently points the Admin tab to /admin/catalog. After adding admin users, the admin section may need sub-navigation or the tab target may need updating. Not addressed in the ticket.
  • Session role snapshot: SessionsController syncs Lead.role from Keycloak token at login. A promoted user's session will not reflect the new role until re-login. The security.md reference ("roles are a login-time snapshot") covers the design, but no AC addresses informing the admin of this behavior.
  • No cross-repo impact: All changes contained within this repo.

Decomposition Assessment

  • 9 file targets in 1 repo — passes the >3 across >2 repos check
  • 11 acceptance criteria — FAILS the >5 threshold
  • Estimated agent work: 6 new files + 3 modifications + KeycloakAdminService extension = likely >5 minutes
  • NEEDS DECOMPOSITION — route to skill-decompose-ticket
Suggested decomposition:
  • PaperTrail setup + KeycloakAdminService role-mapping method (AC 1, 2, partial 7)
  • Admin users list view with role filtering and auth gating (AC 3, 4, 5, 10)
  • User detail page + promotion flow + docs update (AC 6, 7, 8, 9, 11)

Recommendation

  • [BODY] Add app/services/keycloak_admin_service.rb to File Targets — promote action requires a new assign_realm_role method for the Keycloak role-mappings API endpoint
  • [BODY] Clarify AC #5 "Sortable/filterable by role" — specify mechanism (server-side query param filtering vs client-side JS/Stimulus)
  • [BODY] Clarify AC #8 "Confirmation dialog" — specify mechanism (JS confirm(), Turbo modal, or Rails confirmation page)
  • [SCOPE] Create architecture note arch-rails for the Rails component in pal-e-docs
  • [DECOMPOSE] 11 AC across 9+ files, estimated >5 min agent work. Route to skill-decompose-ticket