Org RBAC Surface Behavior
Purpose
This document maps the current org access model to the routes that are live today.
It is intentionally grounded to the current implementation, not to the fuller future permission model.
Core UI Rules
- client-work routes must always respect the viewer's client scope
- owners see all client accounts in the active organization
- non-owners only see clients linked by active
clientAccessAssignments - billing must stay hidden or blocked when the viewer lacks billing capabilities
- do not show actions that the current backend would reject
Current Route Behavior
org/(dashboard)/overview
Base access:
- any active org member
Current behavior:
- this page is still the earlier org account/subscription surface
- it does not yet implement the scoped client-work dashboard behavior described in older docs
org/(dashboard)/customers
Base access:
- any active org member
Current behavior:
- page data is filtered by client scope
- owners see all org client accounts
- non-owners see only assigned client accounts
- create and edit affordances are shown only when the viewer is not
staff - client assignment controls are shown only to
owner
Not yet true here:
- first-class contacts management
- portal-user management inside the customer workspace
- dedicated customer detail sections
org/(dashboard)/projects
Base access:
- any active org member
Current behavior:
- project list is filtered by visible client scope
- project creation is available only when the viewer is not
staff
Not yet true here:
- project detail gating
- project update draft/publish workflow
org/(dashboard)/time
Base access:
- any active org member
Current behavior:
- time-entry list is filtered by visible client scope
- any active org member can create their own draft time entries inside that scope
Not yet true here:
- separate own-versus-team views
- approval-only sections
- fine-grained time edit permissions
org/(dashboard)/billing
Base access:
- viewer must have billing capabilities from the current org capability system
Current behavior:
- customer billing, invoice, and subscription data is filtered by visible client scope
- Stripe customer provisioning plus invoice/subscription write operations are limited to users with billing write capabilities
- users without billing access do not get the live billing workspace
This is the most complete route today for capability-based gating.
org/(dashboard)/documents
Base access:
- any active org member
Current behavior:
- document list is filtered by visible client scope
- any active org member can upload documents into that scope
- document registration captures client-visible versus internal visibility
Not yet true here:
- richer metadata-management gating
- file-request flows
- separate document-management permissions
Missing Detail Routes
The following route-level behavior is still missing because the routes do not exist yet:
customers/[clientId]projects/[projectId]billing/[clientId]
Do not write product docs as if those route-specific section gates are already enforced in the app.
Navigation Rule
Document the current navigation behavior conservatively:
- billing should stay hidden or denied when the viewer lacks billing access
- client-work pages should not imply visibility outside the viewer's current client scope
- do not promise capability-specific tabs and sections that the current route tree does not yet render
Implementation Bias
For the current slice, the repo favors:
- shared client-scope enforcement
- capability-based enforcement for org settings, billing, and client-work authorization paths
- role checks only where ownership semantics must stay explicit (owner transfer, owner deletion protection, role-transition guards)
The remaining gap is not role-vs-capability enforcement. The remaining gap is richer client-work permission grammar and UX surfacing on top of the existing capability model.