Validation: Property detail page Projects section

validation-176-2026-07-26 Doc

validation pass

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 &amp; 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>&lt;details&gt;</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.