Review: Admin user management and promotion
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