Review: CRM tab (admin): business pipeline with search and promotion (re-review)
Verdict: APPROVED
Re-review after body refinements. All five previously flagged [BODY] issues are resolved. Ticket scope is solid and implementable.
Template Completeness
- [x] Type — Feature
- [x] Lineage — replaces #14
- [x] Repo — ldraney/intelligentstaffingsystems
- [x] User Story — As the admin, I want a searchable pipeline with filtering and promotion
- [x] Context — modeled after landscaping-assistant "today tab"
- [x] Dependencies — #54 soft dependency documented with graceful handling
- [x] File Targets — 8 files listed (including Gemfile for PaperTrail) plus exclusions
- [x] Feature Flag — none (core admin functionality)
- [x] Acceptance Criteria — 13 items
- [x] Test Expectations — 10 items plus run command
- [x] Constraints — 8 constraints listed including realm-role-mapping specifics
- [x] Checklist — standard 3-item
- [x] Related — references project and related issues
Traceability
- [x] story:crm label — documented in repo docs/user-stories.md as Epic 7: CRM (Admin), covering US-7.1, US-7.2, US-7.3. Sprint roadmap maps #56 to Epic 7.
- [ ] story note on project page — [SCOPE] project-iss user-stories table uses key "admin" (Epic 6) but repo distinguishes Epic 6 (Account) from Epic 7 (CRM). Add "crm" row to project-iss user-stories table mapping to Epic 7.
- [ ] arch note MISSING — [SCOPE] No arch-rails note exists in pal-e-docs. Systemic gap (many board items use arch:rails). Create architecture note arch-rails.
- [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/ldraney/intelligentstaffingsystems/issues/56, state: open
File Targets
- [x]
app/controllers/crm_controller.rb— verified: EXISTS as stub with require_role :admin. Matches top-level tab controller convention (catalog, communications, messages). - [x]
app/views/crm/index.html.erb— verified: EXISTS as stub view (empty-state placeholder). - [x]
app/views/crm/_business_card.html.erb— to be created; correct path under existing crm/ view directory. - [x]
app/views/crm/show.html.erb— to be created; correct path. - [x]
app/assets/stylesheets/crm.css— to be created; matches existing convention (catalog.css, communications.css, dashboard.css, etc.). - [x]
app/services/keycloak_admin_service.rb— verified: EXISTS with get_user and update_user. Ticket specifies adding promote_to_client using realm-role-mapping API (POST /admin/realms/{realm}/users/{id}/role-mappings/realm). Needs POST method added to make_request. - [x]
config/routes.rb— verified: EXISTS with stub route at line 37 (get "/crm"). Needs show and promote action routes added. - [x]
Gemfile— verified: EXISTS. PaperTrail NOT present (correct — ticket says to add it).
Repo Placement
OK — issue filed on ldraney/intelligentstaffingsystems, all work targets that repo. Keycloak admin API calls go outbound to the Keycloak server, no cross-repo changes needed.
Dependencies
- #6 (Keycloak OIDC auth) — DONE. Provides KeycloakAdminService foundation and session role extraction.
- #51 (Projects tab) — DONE. ProjectRequest model exists for "project requests visible on business detail" AC.
- Messaging subsystem — DONE. Message model and threads exist for "message thread link" AC.
- #54 (Appointment scheduling) — NOT landed. Ticket explicitly handles this: "If #54 has not landed, show last activity from messages and project requests only; appointment data is additive, not blocking." AC #5 uses conditional "(+ last appointment if #54 has landed)". Graceful.
- Lead.search scope — does not exist yet. Will be created as part of this ticket.
- promoted_at column — EXISTS in schema (line 80). Role column EXISTS (line 82, default "lead").
- PaperTrail gem — NOT installed. Explicitly listed as Gemfile file target to add.
Acceptance Criteria
13 acceptance criteria. All are testable by an agent:
- AC #1-4 (access control, search, filter, card display) — standard controller/view testing with session stubbing per testing-strategy.md.
- AC #5 (last activity) — aggregates across messages and project_requests (both exist). Appointment is conditional. Clear and implementable.
- AC #6 (business detail) — show view with related data. Straightforward.
- AC #7-8 (promote button, confirmation) — UI elements, testable via view rendering.
- AC #9 (Keycloak role update) — NOW PRECISELY SPECIFIED: realm-role-mapping API, POST endpoint given. KeycloakAdminService can be extended cleanly.
- AC #10-11 (mirror to Lead.role, set promoted_at) — model update; columns already exist in schema.
- AC #12 (PaperTrail audit) — gem addition now in file targets. Standard Rails gem integration.
- AC #13 (project requests in detail) — ProjectRequest model exists, belongs_to :lead.
Blast Radius
- Tab bar helper (app/helpers/navigation_helper.rb) already references CRM path for admin — no route rename needed (stub route stays at /crm).
- KeycloakAdminService: adding promote_to_client method with POST support extends the service without modifying existing get_user/update_user methods. Safe.
- PaperTrail installation adds a versions table and initializer — standard Rails concern, isolated to new model integration.
- No search scope exists anywhere in the app — Lead.search will be the first. No conflicting patterns.
Decomposition Assessment
Per project convention ("Stop decomposing; write inclusive tickets, review them whole"), this 8-point inclusive ticket is accepted as-is. The 13 ACs form a cohesive feature (CRM pipeline) rather than unrelated concerns. An agent can implement search/filter, detail view, and promotion as a single coherent pass since they share the same controller, model scope, and view directory.
Previous Review Issues — Resolution Status
- File target namespace mismatch — FIXED. All paths now use top-level convention matching existing stub.
- PaperTrail not in Gemfile — FIXED. Explicitly listed in File Targets.
- Appointments model dependency — FIXED. Dependencies section added with graceful handling. ACs use conditional language.
- Keycloak promotion API — FIXED. Constraints and file targets now specify realm-role-mapping endpoint precisely.
- Decomposition suggested — NOT decomposing per project convention. Accepted.
Recommendation
[SCOPE]Add "crm" row to project-iss user-stories table: Key=crm, Backing=Epic 7 (US-7.1–7.3), Role=Admin, Success metric="Searchable pipeline; lead→client promotion with audit"[SCOPE]Create architecture note arch-rails (systemic gap — affects many board items, not just this ticket)
Neither [SCOPE] item blocks implementation. The ticket body is complete and actionable.