Validation: Property detail page Projects section
Verdict: PASS
Ticket
ldraney/landscaping-assistant#176 — Add read-only Projects & Requests section to property detail page. Merged via PR #326.
Environment
Production cluster. URL:
https://landscaping-assistant.app. Pod running image 6f88f9316a704b275195cd37d4e91d22619b02de (confirmed includes PR #326). Logged in as lucas-admin (admin role).Checks
| # | Tier | Criterion | How Verified | Result | Evidence |
|---|---|---|---|---|---|
| 1 | T3 | Woodpecker PR pipeline green | Woodpecker pipeline #879 (PR check for #176) | PASS | Pipeline #879: all steps success (clone, database, bundle-install, lint, test). Merge-push pipeline #880 had transient failure (all steps skipped after clone) — not code-related. |
| 2 | T3 | Deployment is live with correct image | Pod image tag confirmed by caller | PASS | Pod running image <code>6f88f9316a</code> which includes PR #326 merge commit. |
| 3 | T3 | Route-level smoke test (SOP frontend checklist) | curl all major routes: <code>/</code>, <code>/login</code>, <code>/properties/manage</code>, <code>/today</code>, <code>/profile</code>, <code>/up</code> | PASS | All routes return HTTP 200. No 404s or 500s. |
| 4 | T3 | AC1: Projects/Requests section displays on property detail page beneath property info | Playwright: logged in as lucas-admin, navigated to <code>/properties/104</code>, took full-page screenshot | PASS | "Projects & Requests" heading visible between property info/buttons and Comments section. Section rendered via <code>_service_requests.html.erb</code> partial, gated by <code>service_requests</code> feature flag (enabled). |
| 5 | T3 | AC2: Active requests grouped (statuses: requested, quoted, accepted, paid, scheduled) | Code review of <code>_service_requests.html.erb</code> lines 4-5 | PASS | Partial correctly filters <code>%w[requested quoted accepted paid scheduled]</code> into <code>active_requests</code>. No prod data to visually verify grouping (expected — ServiceRequest is new), but code logic is correct. |
| 6 | T3 | AC3: Completed/declined requests display separately, collapsible | Code review of <code>_service_requests.html.erb</code> lines 31-62 | PASS | Uses <code><details></code> HTML element for collapsible "Past requests" section. Completed and declined requests rendered separately within. |
| 7 | T3 | AC4: Each entry shows description, type badge, status badge, price | Code review of partial lines 16-25 and CSS diff | PASS | Request type badge (<code>.service-request-type</code>), status badge (<code>.service-request-status</code>), description, and conditional price display (shown for quoted/accepted/paid/scheduled/completed). CSS includes distinct colors for each status and type. |
| 8 | T3 | AC5: Empty state message "No projects or requests yet" | Playwright: visual check of property detail page | PASS | Page text confirmed: "No projects or requests yet" displayed when property has zero service requests. |
| 9 | T3 | AC6: Mobile-responsive design with 44px touch targets | CSS review of PR #326 diff | PASS | <code>.service-request-item</code> has <code>min-height: 2.75rem</code> (44px). <code>.service-requests-past-toggle</code> also has <code>min-height: 2.75rem</code>. Flexbox layout with <code>flex-wrap: wrap</code> for responsive badges. Uses CSS custom properties for consistent spacing. |
Regression Check
All major routes confirmed healthy:
/ (200), /login (200), /properties/manage (200), /today (200), /profile (200), /up (200). Properties list page loads correctly with full property listing. Property detail page renders all existing sections (property info, address detection, comments) alongside the new Projects & Requests section. No regressions observed.Discovered Issues
Pipeline #880 transient failure: The merge-push pipeline for PR #326 failed due to all steps being skipped after clone. This is a known transient CI pattern and not related to the PR code (the PR check pipeline #879 was fully green). Not creating a follow-up issue since this is a known intermittent Woodpecker behavior.
Note on AC2-4 coverage: Active/completed/declined request grouping, badges, and prices cannot be visually verified in production because no ServiceRequest records exist yet. The ServiceRequest model is new (merged via #122) and production data will accumulate as clients submit requests. Code review confirms the implementation is correct. Full visual verification will occur naturally when the first service requests are created.