Review: Appointment booking and calendar

review-1795-2026-07-06-r2 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type
  • [x] Lineage
  • [x] Repo
  • [x] User Story
  • [x] Context
  • [x] File Targets
  • [x] Feature Flag
  • [x] Acceptance Criteria
  • [x] Test Expectations
  • [x] Constraints
  • [x] Checklist
  • [x] Related
All required sections for the Feature template are present.

Traceability

  • [x] story:registration label — Epic 1 (US-1.2–1.4), Role: Visitor/Lead
  • [x] story note verified — found in project-iss user-stories section (row: "registration", backing "Epic 1 (US-1.2–1.4)")
  • [x] arch:rails label — Rails application component
  • [ ] arch note MISSING — [SCOPE] Create architecture note arch-rails for the Rails component in pal-e-docs
  • [x] Forgejo issue — ldraney/intelligentstaffingsystems#15, open

File Targets

  • [x] app/models/appointment.rb — verified: does not exist, to be created. Architecture.md confirms Appointment entity (uuid id, uuid lead_id FK, datetime scheduled_at, string status, text notes)
  • [x] db/migrate/xxx_create_appointments.rb — verified: no appointments table in schema.rb, migration needed
  • [x] app/controllers/appointments_controller.rb — verified: does not exist, to be created. security.md already documents this controller as skipping auth
  • [x] app/views/appointments/new.html.erb — verified: appointments view directory does not exist, to be created
  • [x] app/views/appointments/create.html.erb — verified: to be created
  • [x] app/assets/stylesheets/appointments.css — verified: does not exist, to be created
  • [x] config/routes.rb — verified: exists, has placeholder booking route at line 7 (get "booking", to: "leads#booking") that must be replaced
  • [x] test/models/appointment_test.rb — verified: does not exist, to be created
  • [x] test/controllers/appointments_controller_test.rb — verified: does not exist, to be created
  • [x] docs/user-stories.md — verified: exists, Open Questions #1 (line 315) documents "Calendly embed vs custom booking" — needs update to record the custom scheduling decision
  • [ ] app/models/lead.rb — MISSING from file targets. Lead model currently has has_many :messages but no has_many :appointments association. AC says "Appointment linked to Lead record" — this file must be modified.
  • [ ] app/controllers/leads_controller.rb — MISSING from file targets. Currently redirects to booking_path (line 16) and has a placeholder booking action (lines 22-24). Both must be updated: redirect target changes to the new appointment route, placeholder action removed.
  • [ ] app/views/leads/booking.html.erb — MISSING from file targets. Existing placeholder booking view ("Appointment booking is coming soon") must be removed when the real appointments flow lands.

Repo Placement

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

Dependencies

  • Depends on #8 (Lead model, migration, registration form) — board item #1788 is in validation column. Dependency satisfied.
  • Email deferred to #16 (Postmark integration) — documented in Constraints and Context. No blocking issue.
  • #42 (Turbo Streams) is in todo — unrelated, no dependency.
  • No undocumented blockers found on the board.

Acceptance Criteria

9 ACs — all are clear and testable by an agent. Two gaps:
  • Lead ID flow unspecified — AC says "Appointment record created with lead_id" and "Appointment linked to Lead record", but the issue does not specify how lead_id flows from registration to the booking form. The current redirect (redirect_to booking_path) does not pass a lead reference. Options: session storage, URL param (new_appointment_path(lead_id: @lead.id)), or nested route. The agent needs this decision made.
  • Placeholder cleanup not covered — no AC addresses removal of the existing placeholder booking route, controller action, and view.

Blast Radius

  • docs/security.md already documents AppointmentsController as skipping auth (lines 50, 108, 183) — good alignment, no update needed unless implementation diverges.
  • docs/testing-strategy.md already has a #15 row (line 181) — good alignment.
  • Landing page CTAs link to #book anchor (not a route) — no change needed.
  • Dashboard view has an "Appointments" heading (line 65 of dashboard/show.html.erb) — currently a placeholder, may need wiring to show upcoming appointments in a future ticket.
  • docs/security.md line 195 flags rate limiting as an open concern for unauthenticated writes (registration + booking). Not blocking, but worth noting for a follow-up.

Decomposition Assessment

10 file targets in 1 repo — single-repo threshold not hit. 9 ACs — exceeds the >5 AC threshold. Estimated agent work: ~4 minutes (standard Rails model + controller + views + tests scaffolding). The work is a cohesive single-feature CRUD flow; decomposition would fragment a natural unit. Recommend keeping as a single ticket if the body issues below are fixed, but flagging the >5 AC threshold for awareness.

Recommendations

  • [BODY] Add app/models/lead.rb to File Targets — needs has_many :appointments, dependent: :destroy association
  • [BODY] Add app/controllers/leads_controller.rb to File Targets — update redirect from booking_path to new appointment path, remove placeholder booking action
  • [BODY] Add app/views/leads/booking.html.erb to File Targets as a file to remove
  • [BODY] Specify in Context or Constraints how lead_id flows from registration to appointment creation (session, URL param, or nested route)
  • [SCOPE] Create architecture note arch-rails for the Rails component in pal-e-docs