Skip to content

Customizable tenant dashboard layouts — Production Readiness Audit ​

FieldValue
Date2026-10-21
StatusGo for production — Pest 14/14 dashboard widget + layout; headed Playwright 1/1 (one login session)
ScopePer-user show/hide + reorder of entitled dashboard widgets; platform templates; server-persisted users.dashboard_layout
CatalogNo bump (platform shell feature)
CompanionTenant application user guide · Tenant dashboard API · CHANGELOG

Executive summary ​

Workspace users with dashboard.view can open Customize on the tenant Dashboard, apply a job template (Balanced, Sales rep, Sales manager, Service desk, Project ops, Finance ops, CRM lite), show/hide widgets, drag-reorder them, and save. Preferences are stored per user. Module entitlement + Spatie permission always win — layouts never grant access. Newly entitled widgets stay hidden until the user opts in (new_widget_ids).

Go / No-Go: Go. Migrate-only (users.dashboard_layout). Deploy Backend and Frontend together; hard-refresh SPA.

GateResult
Platform freezePass — AppLayout + existing widget registry; no parallel shell
Eligibility still filters widgetsPass (Pest)
Default (no preference) shows all eligible widgetsPass (Pest)
Custom items persist show/hide + orderPass (Pest)
Template apply only includes eligible idsPass (Pest)
Unknown template_id → 422Pass (Pest + headed API check)
Missing dashboard.view → 403Pass (Pest)
Headed one session: invalid template 422, Sales rep template, hide High Priority, Show all restorePass (npm run test:e2e:tenant-dashboard:customize:headed)

Security summary ​

ControlStatus
Layout update requires dashboard.viewPass
Widget ids outside the customizable catalog are droppedPass
Ineligible module/permission widgets never appear even if pinnedPass
Preference JSON stores layout only (no payload data)Pass
Chrome widgets (activity_feed, notifications, quick_actions) are not user-layoutedPass

Findings disposition ​

IDSeverityItemDisposition
F1MediumExisting tenant dashboard e2e expected removed Pipeline activity section after layout unificationFixed — assertions use Workspace insights + Customize button; demo layout reset before load
F2Medium.env.e2e.local did not override .env.e2e (dotenv default) so Windows DNS workarounds never appliedFixed — playwright.config.ts loads .env.e2e.local with override: true
F3MediumBrowser could not resolve Herd elosync-backend.test (offline banner) while Node APIRequestContext could use 127.0.0.1 + HostFixed — e2e/helpers/herd-dns-bypass.ts routes browser traffic + prefers same-origin Vite /api proxy; document local E2E_API_URL / E2E_API_HOST
I1InfoSonner success toast can dismiss before Playwright asserts textAccepted — headed test waits for PUT /dashboard/layout response + sheet close

Headed browser coverage ​

npm run test:e2e:tenant-dashboard:customize:headed on 2026-10-21. Result: 1 passed (one serial session).

One demo-tenant login, one page session:

  1. Reset layout to all-visible via API (stable baseline on shared demo user)
  2. PUT unknown template_id → 422 validation error
  3. Open Dashboard → Customize → Cancel (no change)
  4. Apply Sales rep template → Save → template_id=sales_rep; lead_sources not visible
  5. Hide High priority deals → Save → heading gone; template_id cleared
  6. Show all → Save → High Priority returns
  7. Restore full-visible layout in finally

Also: npm run test:e2e:tenant-dashboard (widget chrome + sidebar) after layout reset.


Upgrade ​

  1. php artisan migrate --force (adds nullable users.dashboard_layout). Do not db:seed.
  2. Deploy Backend, then Frontend production build; hard-refresh SPA.
  3. Smoke: open Dashboard → Customize → apply Sales rep → Save → confirm widgets change → Show all → Save.

Local e2e notes (Windows + Herd) ​

When Node/Chrome cannot resolve .test DNS:

env
# .env.e2e.local
E2E_BASE_URL=http://localhost:5173
E2E_API_URL=http://127.0.0.1
E2E_API_HOST=elosync-backend.test
E2E_SKIP_WEBSERVER=1

Serve the SPA with same-origin API so Vite’s /api proxy applies:

bash
VITE_API_URL=http://localhost:5173 npm run dev -- --port 5173 --strictPort

Official documentation for the EloSync SaaS Platform.