Review: ServiceRequest model + migration (re-review)
Verdict: APPROVED
Re-review of board item #1347. Previous review (
review-1347-2026-06-07) flagged three issues. All three have been addressed.Previous Findings -- Resolution
- [FIXED] user_id column ambiguity -- Changed to
crew_member_id(FK tocrew_members). Verified:crew_memberstable exists in committed schema with columns:name,keycloak_username,role,active. The Constraints section explicitly states "crew_member_id references crew_members table (clients are crew_members with role=client)". Clean resolution. - [FIXED] Status transition rules missing -- Explicit Status Transition Graph section added with six valid transitions:
requested->quoted,requested->declined,quoted->paid,quoted->declined,paid->scheduled,scheduled->completed. Terminal states documented (declined,completed). "No other transitions are valid" is stated. An agent can implement this unambiguously. - [FIXED] Feature Flag section missing -- Section added with value "None". Correct for an internal model change with no UI.
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- child of spike #121
- [x] Repo -- ldraney/landscaping-assistant
- [x] User Story
- [x] Context
- [x] File Targets -- 7 targets listed
- [x] Acceptance Criteria -- 5 criteria
- [x] Status Transition Graph -- NEW, addresses previous gap
- [x] Test Expectations
- [x] Constraints
- [x] Feature Flag -- "None" (addresses previous gap)
- [x] Checklist
- [x] Related
Traceability
- [x] story:auth label -- auth story
- [x] story note verified -- "auth" entry found in project-landscaping-assistant user-stories table
- [x] arch:rails-app label
- [ ] arch note MISSING -- [SCOPE] No
arch-rails-appnote exists in pal-e-docs. Carried forward from first review. Non-blocking for this ticket. - [x] Forgejo issue -- ldraney/landscaping-assistant#122, state: open
File Targets
- [x]
db/migrate/*_create_service_requests.rb(new) -- OK, no existing ServiceRequest migration. No ServiceRequest references anywhere in codebase. - [x]
db/migrate/*_add_monthly_price_to_services.rb(new) -- OK,servicestable exists in schema. Nomonthly_pricecolumn present. ERD in docs confirms this addition. - [x]
app/models/service_request.rb(new) -- OK, no existing model or references in codebase. - [x]
app/models/property.rb-- verified exists. Hashas_many :property_services,has_many :services,has_many :work_queue_items. Addinghas_many :service_requestsis straightforward. - [x]
app/models/crew_member.rb-- verified exists. Has validations for name, keycloak_username, role. Addinghas_many :service_requestsis straightforward.crew_memberstable confirmed in committed schema. - [x]
db/seeds.rb-- verified exists. Currently seeds 3 services (Edging & Trimming, Mowing, Weeding) without prices viafind_or_create_by!. Adding monthly_price will need idempotent update pattern. - [x]
spec/models/service_request_spec.rb(new) -- OK,spec/models/directory exists with 8 existing model specs. Pattern is consistent.
Repo Placement
OK. Issue filed on
ldraney/landscaping-assistant, all file targets in the same repo. Single-repo ticket.Dependencies
- #121 (parent spike) -- done (board item 1346 in done column). No blocker.
- crew_members table -- exists in committed schema (migration 20260607030548). CrewMember model confirmed with ROLES including "client". No blocker.
- Stripe --
stripe_payment_linkis a plain string column (URL). No Stripe gem dependency. Separate ticket #125 handles integration. No blocker. - Downstream -- #123 (Client request UI) and #124 (Admin request management) depend on this model. Both in backlog, not blocked.
- #176 (Property detail page: Projects section) -- explicitly says "depends on #122". In backlog. Correctly ordered.
Acceptance Criteria
- AC1 (ServiceRequest model with columns) -- testable. All columns clearly specified with types. crew_member_id FK is now unambiguous.
- AC2 (Service gains monthly_price) -- testable, clear.
- AC3 (Seeds updated with prices) -- testable, three service names match existing seeds.
- AC4 (Status transitions per graph) -- now fully specified with 6 valid transitions and 2 terminal states. Agent can implement deterministically.
- AC5 (Model specs) -- testable, clear.
Blast Radius
- Property model -- adding
has_many :service_requestsis low risk. No existing associations conflict. - CrewMember model -- adding
has_many :service_requestsis low risk. No existing associations on this model. - Service model -- adding
monthly_pricecolumn is low risk. No existing code reads a price from services. - Seeds -- uses
find_or_create_by!. Will need idempotent update for prices (e.g.,find_or_create_by!(name:).tap { |s| s.update!(monthly_price:) }). Ticket should note this but it is not blocking. - No downstream breakage risk -- new model with no UI. Existing tests unaffected.
Decomposition Assessment
7 file targets in 1 repo, 5 acceptance criteria. All files in one repo, work is cohesive (one model + one column addition + seeds + specs). Estimated agent work: under 5 minutes. No decomposition needed.
Recommendations
[SCOPE]Create architecture notearch-rails-appin pal-e-docs (carried forward, non-blocking).
No other action needed. All three previously flagged issues have been resolved. Ticket is ready for implementation.