mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-07-27 22:45:03 +00:00
A contractor-org user (resolved via team_members → team → org, #408) now sees only their own slice of a project: work orders issued to their organisation, scoped KPI tiles, the workstreams they are assigned to, and a permission-driven "What you can do" panel. The scoping is enforced server-side, in one place. `workOrderOrganisationScope` (@/lib/projects/authz) is the single definition of whose orders a caller may see — null for internal/client (the whole programme), a contractor's own orgs otherwise, never another org's. The work-orders route handler resolves that scope and passes it to `loadWorkOrderPage`, which pushes it into SQL as an `AND pwc.organisation_id IN (…)`. Because it is a separate predicate, it composes with — and can never be widened by — the caller's own contractor filter: a contractor asking for another org's orders gets an empty page, not a leak. - Reuses the #419 admin table component and derivations verbatim; only the server-seeded page and (cosmetically) the filter options are scoped. - The contractor per-project view replaces the programme dashboard for that role, deriving KPIs from the same `summariseDashboard` fold over organisation-scoped groups so tiles and table reconcile. - Row action links to the work-order detail route (#422, built in parallel). - Internal/client callers are unaffected: their scope is null, so the query is unchanged from #419. Tests: route-handler-level and query-construction tests prove a contractor can never retrieve another org's orders (including when they filter by one); pure authz tests for scope resolution and capability summary; a Cypress contractor-login-sees-scoped-list spec. Typecheck, lint and the full unit suite (1180) are green. See ADR-0023. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| 1-getting-started | ||
| 2-advanced-examples | ||
| live-tracking | ||
| login | ||
| projects | ||