Validation: Crew tab - admin oversight of team members and their daily lists

validation-117-2026-06-07 Doc

validation pass

Verdict: PASS

Ticket

ldraney/landscaping-assistant#117 — Crew tab: admin oversight of team members and their daily lists. Board item #1339 on board-landscaping-assistant. Merged via PR #146.

Environment

Production cluster, namespace landscaping-assistant, URL: https://landscaping-assistant.tail5b443a.ts.net. Image: harbor.tail5b443a.ts.net/landscaping-assistant/app:c89ac23068ff4adad41fdba4415a84d307d9404e. Pipeline #362 (success). Pod: landscaping-assistant-5c646869b9-px7fn — Running, 0 restarts.

Checks

# Criterion How Verified Result Evidence
1 Crew index shows list of all active crew members with their name and role badge Inspected deployed view template via kubectl exec cat; confirmed role-badge CSS class and member.name rendering. Empty state renders correctly when no members seeded. PASS Template: <code>&lt;span class="role-badge role-badge-&lt;%= member.role %&gt;"&gt;&lt;%= member.role.titleize %&gt;&lt;/span&gt;</code>. Browser snapshot shows /crew loads with heading "Crew" and empty state message.
2 Clicking a crew member navigates to their profile page (name, role, active status, Keycloak username) Inspected show.html.erb template via kubectl; confirmed dl.crew-profile with fields: Role (badge), Status (active/inactive), Keycloak Username, Added date. Route confirmed: <code>resources :crew, only: [:index, :show]</code> PASS Show template renders all four required fields: name (h1), role (role-badge), status (status-indicator), keycloak_username (code tag).
3 Admin and super_admin can access Crew tab; all other roles get 404 Controller source: <code>require_role :admin, :super_admin</code>. Browser test as lucas-super-admin loads /crew successfully. Unauthenticated curl returns 302 redirect. PASS Controller line 1: <code>require_role :admin, :super_admin</code>. curl /crew without auth: HTTP 302. Browser as super_admin: page loads with heading "Crew".
4 CrewMember model with validations and crew:sync rake task (idempotent, find_or_create_by!) Rails runner queried validators: presence on name/keycloak_username/role, uniqueness on keycloak_username, inclusion on role. Rake task source uses find_or_create_by!. <code>rails -T crew</code> confirms task exists. PASS Validators: PresenceValidator[:name], PresenceValidator[:keycloak_username], UniquenessValidator[:keycloak_username], PresenceValidator[:role], InclusionValidator[:role]. Rake output: <code>bin/rails crew:sync # Sync crew members (idempotent)</code>. Task uses <code>CrewMember.find_or_create_by!(keycloak_username: ...)</code>.
5 Crew member list shows active/inactive status indicator Inspected index.html.erb template: renders <code>status-indicator status-indicator-active/inactive</code> span with text "Active"/"Inactive". PASS Template: <code>&lt;span class="status-indicator status-indicator-&lt;%= member.active? ? 'active' : 'inactive' %&gt;"&gt;</code>

Regression Check

Verified other routes still functional:
  • /up health check: HTTP 200
  • /today: loads correctly with full property data (browser snapshot confirmed)
  • Bottom nav: all 6 tabs (Today, Week, Person, Platform, Properties, Crew) render correctly
  • Pod status: 1/1 Running, 0 restarts, age 3h14m
  • Pipeline #362: all 6 steps green (clone, database, bundle-install, lint, test, build-and-push)

Discovered Issues

None. Note: crew:sync has not been run in production yet, so the crew list shows the empty state. This is expected — the rake task needs to be run manually to seed crew members from Keycloak. This is not a bug; the feature is fully deployed and functional, awaiting initial data seed.