Files
CapaKraken/docs/route-access-matrix.md
T

9.6 KiB

Route Access Matrix

Date: 2026-03-29 Purpose: Explicit interim audience model for sensitive API read routes while the broader least-privilege refactor is still in progress.

Decision Rules

  • protectedProcedure: only for clearly personal or low-sensitivity reads.
  • controllerProcedure: planning, financial, staffing, or portfolio-wide analytics that should only be visible to CONTROLLER, MANAGER, or ADMIN.
  • Ownership checks: self-service routes stay user-accessible, but only for the caller's own linked resource unless elevated staff access applies.

Applied In This Pass

Dashboard

All routes in dashboard.ts are treated as portfolio analytics and now require controllerProcedure.

Route Classification Reason
getOverview controllerProcedure exposes global resource/project counts and budget context
getPeakTimes controllerProcedure exposes portfolio-wide demand/utilization peaks
getTopValueResources controllerProcedure exposes ranked value/cost-related resource data
getDemand controllerProcedure exposes staffing demand by project/person/chapter
getDetail controllerProcedure aggregates the above into assistant-facing strategic detail
getChargeabilityOverview controllerProcedure already correctly scoped
getBudgetForecast controllerProcedure exposes budget burn and exhaustion projections
getSkillGaps controllerProcedure exposes org-wide capability shortfalls
getSkillGapSummary controllerProcedure summary variant of strategic skill analytics
getProjectHealth controllerProcedure exposes portfolio-level delivery risk indicators

Vacation

Routes in vacation.ts now distinguish between self-service and staff oversight.

Route Classification Reason
previewRequest self-service personal validation before request creation
create self-service with ownership check users may request only for their own resource
cancel self-service with ownership check users may cancel only their own requests
list self-service scoped to own resource, or full staff view for manager/admin broad vacation visibility is sensitive absence data
getById self-service scoped to own vacation, or full staff view for manager/admin direct object lookup should not bypass ownership
getForResource self-service scoped to own resource, or full staff view for manager/admin calculator support should not expose foreign absence data
getTeamOverlap self-service scoped to own resource, or full staff view for manager/admin overlap warnings are valid, but only for the caller's team context
getPendingApprovals manager/admin approval queue is supervisory data

Resource

Routes in resource.ts remain partially deferred, but the clearest sensitive reads are now explicitly scoped.

Route Classification Reason
directory authenticated safe directory dedicated low-sensitivity directory for generic pickers, filters, calendars, and lookups; returns only id, eid, displayName, chapter, and isActive, limits search to name/EID, and preserves anonymization behavior
getMyResource self-service explicit route for the caller's linked resource
getChargeabilitySummary self-service scoped to own resource, or staff with VIEW_ALL_RESOURCES exposes detailed capacity, holiday, assignment, and target data for an individual resource
getValueScores explicit permission gate VIEW_SCORES ranked score output should not depend on ad hoc session-role strings
getById self-service scoped to own resource, or staff with VIEW_ALL_RESOURCES full resource detail page includes person-level operational and cost context
getByEid self-service scoped to own resource, or staff with VIEW_ALL_RESOURCES direct identifier lookup should not bypass ownership
getHoverCard self-service scoped to own resource, or staff with VIEW_ALL_RESOURCES hover card exposes rates, role, skills, and staffing targets
getByIdentifier exact self lookup for regular users; broad lookup for staff with VIEW_ALL_RESOURCES lightweight identifier read returns only identity-safe fields (id, eid, displayName, chapter, isActive)
getByIdentifierDetail exact self lookup for regular users; broad lookup for staff with VIEW_ALL_RESOURCES explicit detail route for assistant and UI flows that truly need rates, targets, org placement, and skill/count context
resolveByIdentifier exact self lookup for regular users; broad lookup for staff with VIEW_ALL_RESOURCES minimal identity resolver used by tool chains to convert free-form names/EIDs into canonical IDs without leaking cost or location detail
listSummaries staff with VIEW_ALL_RESOURCES staff-only org search that returns non-financial summary cards for discovery and candidate selection
listSummariesDetail staff with VIEW_ALL_RESOURCES explicit richer search variant for assistant/staff workflows that need FTE, LCR, and chargeability context
listStaff staff with VIEW_ALL_RESOURCES explicit staff-only list for cost-aware, role-aware, and estimate/planning workflows; supports email search, rates, roles, and dynamic field filters

Resource Directory Split

This pass introduces an explicit audience split in resource.ts:

  • resource.directory is the default route for generic UI selectors and org-directory style lookups.
  • resource.listStaff is the explicit staff-only route for estimate, staffing, and scenario-planning screens that need cost-sensitive resource data.

The following web consumers now use resource.directory:

  • generic resource comboboxes and assignment pickers
  • vacation filters and team calendar selectors
  • timeline quick filters, toolbar lookup, and project panel add-member search
  • project responsible-person picker
  • computation graph resource selector
  • batch skill import resource matching

Project

Routes in project.ts now distinguish between lightweight project discovery and planning/commercial detail.

Route Classification Reason
resolveByIdentifier authenticated safe resolver minimal project identity lookup for names/codes/IDs without commercial detail
searchSummaries authenticated safe summary search lightweight project discovery returns only code, name, status, dates, and client
searchSummariesDetail controllerProcedure exposes budget, win probability, and staffing/estimate counts
getByIdentifier authenticated safe identifier read exact/fuzzy lookup returns only identity-safe project fields
getByIdentifierDetail controllerProcedure exposes commercial and staffing detail, including budget, responsible person, category, and top allocations
list controllerProcedure broad project listing can expose commercial/custom-field planning context
getById controllerProcedure full project read model includes allocations, demands, and assignments
getShoringRatio controllerProcedure derived staffing geography analytics should not be generally user-visible

Timeline

Routes in timeline.ts now split personal self-service reads from broad planning views.

Route Classification Reason
getEntries controllerProcedure returns broad staffing allocations across projects/resources for a time window
getEntriesView controllerProcedure exposes the full timeline read model, including demands and assignments
getHolidayOverlays controllerProcedure org-wide absence overlays reveal staffing availability context
getMyEntriesView self-service scoped to own linked resource personal timeline view for USER/VIEWER; ignores foreign resource scoping and never broadens beyond the caller's linked resource
getMyHolidayOverlays self-service scoped to own linked resource personal holiday overlays for the caller's own timeline window without org-wide absence visibility
getEntriesDetail controllerProcedure assistant-facing planning detail aggregates allocations, demands, assignments, and holiday summaries
getHolidayOverlayDetail controllerProcedure detailed overlay summaries are planning-sensitive absence context
getProjectContext controllerProcedure project-side planning context includes all allocations and cross-resource context
getProjectContextDetail controllerProcedure detailed project timeline context exposes conflict and overlap analysis
previewShift controllerProcedure shift preview computes operational and budget impacts before mutation
getShiftPreviewDetail controllerProcedure detail variant includes project metadata plus cost/conflict preview
getBudgetStatus controllerProcedure budget burn/remaining exposure is commercial data

Review Standard

  • Any new sensitive read route must document one of:
    • personal self-service ownership
    • explicit role gate
    • explicit permission gate
  • Any route returning portfolio-wide financial, staffing, scheduling, or HR absence data should not default to plain protectedProcedure.