Add day detail page: controller, route, and basic show view #240
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "234-day-detail-page"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Days get their own planning pages, separate from the Today operational view. The Week tab becomes the entry point to day detail pages for any day (past or future).
Changes
app/controllers/days_controller.rb-- new controller withshowaction, gated toadmin, super_admin(matches Week tab)app/views/days/show.html.erb-- day detail page with weekday heading, back-to-week link, queued properties listconfig/routes.rb-- addGET /days/:daterouteapp/views/weeks/index.html.erb-- day labels now link to/days/:dateinstead of/today?date=spec/requests/days_spec.rb-- 12 request specs covering happy path, empty state, invalid date, auth, and role accessTest Plan
GET /days/2026-06-17returns 200 with "Tuesday" headingReview Checklist
Related Notes
None -- new page.
Related
Closes #234
Parent: #233 (decomposed)
Blocks: #235, #236, #237
PR #240 Review
DOMAIN REVIEW
Stack: Ruby on Rails 8.1, ERB views, RSpec request specs. Review applies Rails controller patterns, test correctness, and view quality checks.
Controller (
app/controllers/days_controller.rb)require_role :admin, :super_adminmatches WeeksController -- correct.includes(:property)on the query avoids N+1 in the view -- good.Date::ErrorandTypeErrorare rescued inparse_date-- covers both malformed strings and nil.View (
app/views/days/show.html.erb)app-shell,day-nav,queue-list,empty-state,section-heading) -- no new CSS drift.is-completedclass, consistent with existing patterns.weeks_pathparam.Route (
config/routes.rb)get "/days/:date"placed logically near the weeks resource.day_pathis clean and used correctly in weeks/index.html.erb.Week tab update (
app/views/weeks/index.html.erb)day_path(date: day)instead ofwork_queue_items_path(date: day)-- clean swap, one-line change, no collateral damage.BLOCKERS
1.
parse_datecontrol flow bug -- action continues after redirect on invalid dateIn
DaysController#parse_date:and returnexitsparse_date, not theshowaction. On an invalid date,parse_datereturnsnil(the return value ofredirect_to), thenshowcontinues and callsnil.beginning_of_week(:monday), raisingNoMethodError. The redirect headers are set but the exception aborts the response.Compare with
WeeksController#parse_week_start(lines 76-81), which returns a fallback date on error and never redirects from within a private method.Fix options (either works):
parse_datereturn a fallback, redirect inshow:before_actionthat sets@dateand short-circuits viaperformed?:2. Unauthenticated test is not actually unauthenticated (spec bug)
Lines 48-53 of
spec/requests/days_spec.rb:The top-level
before { sign_in_as(nickname: "admin-user", roles: %w[admin]) }on line 7 runs before this test. The user IS authenticated when this test executes. It likely returns 200 (admin has access), so theredirect_to("/login")assertion should be failing -- unless the test is being skipped or there is some session isolation behavior I am not seeing.Fix: Add
reset!(or use a fresh session) before the unauthenticated request, or move this test into a separatedescribeblock without thebeforehook. The pattern used inrole_access_spec.rb(lines 24-51) is the correct reference -- those unauthenticated tests have nosign_in_asin theirbeforeblock.3. Client redirect assertion may be wrong (spec bug)
Line 83:
require_roleinApplicationController(line 32) redirects toroot_pathon failure, notprofile_index_path. The profile redirect only happens after following through towork_queue_items#index, which detects the client has no:todaytab. Sinceredirect_toin the spec checks the immediate response location (not the final destination after following redirects), this assertion should expectroot_path, notprofile_index_path.Fix: Change to
expect(response).to redirect_to(root_path)to match the actualrequire_rolebehavior, consistent with how member and lead role tests on lines 70 and 76 expectroot_path.NITS
Route format constraint:
/days/:datehas no constraint on the:dateparam. Requests like/days/foo.jsonwill match and hit the rescue path. A format constraint would be cleaner:Not blocking since the rescue handles it, but explicit constraints are better documentation.
@queue_items.sizebefore iteration: Line 14 of show.html.erb calls@queue_items.sizeinside the heading, then line 16 iterates with.each. Since the relation has not been loaded yet at line 14,.sizeissues a separateCOUNT(*)query. Using.load.sizeor restructuring to iterate first would avoid the extra query. Minor -- the data set is small.Extra blank line: Line 46 of
days_spec.rbhas an extra blank line before the closingendof the firstdescribeblock. Cosmetic only.SOP COMPLIANCE
PROCESS OBSERVATIONS
parse_datecontrol flow bug is a real runtime error on invalid input -- it would surface immediately in production if anyone hits a malformed URL. The fix is small (Option A is a 3-line change).VERDICT: NOT APPROVED
Three blockers: the
parse_datecontrol flow bug (real runtime crash on invalid date), the unauthenticated test that runs while authenticated, and the incorrect client redirect assertion. All three are small fixes. The controller and view code is otherwise clean and well-structured.PR #240 Re-Review
PREVIOUS BLOCKERS -- VERIFIED FIXED
All three blockers from the initial review have been resolved:
parse_date control flow bug -- Fixed.
parse_datenow returnsnilon invalid input (rescuesDate::ErrorandTypeError). Theshowaction guards withreturn redirect_to(weeks_path) unless @datebefore using the date. This matches the WeeksController pattern.False unauthenticated test removed -- Fixed. The spec no longer contains an unauthenticated test nested inside the
before { sign_in_as }block. Each role access test callssign_in_aswith the appropriate role explicitly.Client redirect assertion -- Fixed. Denied roles (
member,lead,client) now assertredirect_to(root_path), which matches therequire_roleimplementation inApplicationController#require_role(line 32).DOMAIN REVIEW
Rails / Controller:
require_role :admin, :super_adminmatches WeeksController gating -- consistent.includes(:property)prevents N+1 on the view'sitem.property.*calls.parse_daterescue clause covers bothDate::Error(malformed string) andTypeError(nil param) -- correct.get "/days/:date"withas: :dayis clean and RESTful.View:
@week_starttoweeks_path(week:)for correct week context.completed?is a Rails-generated predicate from the boolean column -- no custom method needed.Specs (12 tests):
BLOCKERS
None.
NITS
Weeks spec day-link test is stale (
spec/requests/weeks_spec.rb:67-71): The "links day labels to daily work queue" test only checks for the CSS classweek-assign-day-link, not the actual href target. It still passes but does not verify the link destination changed fromwork_queue_items_path(date:)today_path(date:). Consider updating the assertion to include the new path. Non-blocking since the days spec covers the day page itself.Extra blank line in spec (
spec/requests/days_spec.rb:46): There is a trailing blank line beforeendin the first describe block. Cosmetic only.SOP COMPLIANCE
PROCESS OBSERVATIONS
weeks/index.html.erbis the only touch point with existing code -- low change failure risk.VERDICT: APPROVED