RBAC Authorization

Role-Based Access Control system governing who can access and modify resources across Projects, Buildings, and Scenarios.

Architecture

LayerLocation
Ownership guardsbackend/src/lib/ownership-guards.ts
RBAC middlewarebackend/src/middleware/rbac.ts (hybrid model: internal users get global roles, external users get contextual per-resource roles)
Permission checksbackend/src/lib/permissions.ts (canAccessProject() etc., used by RBAC-aware list endpoints)
Department accessbackend/src/lib/department-access.ts
Permissions hookfrontend/src/hooks/usePermissions.ts
Auth store (RBAC helpers)frontend/src/store/auth.ts
Role constantsshared/constants.ts

Database Tables

TablePurpose
projectRolesContact-to-project role assignments
buildingRolesContact-to-building role assignments

Per the Human FK rule (contact as sole identity), both tables key role assignments on contactIdcontacts.id, not on users.id.

User Types and Roles

EnumValues
userTypeEnuminternal, external
internalRoleEnumadmin (full system access), employee (department-scoped)
externalRoleEnumcustomer, owner, contact_person, invoice_receiver, craftsman, partner, … (contextual, per project/building)

Access Verification Functions

Current (RBAC-aware) — defined in backend/src/lib/ownership-guards.ts:

FunctionChecks
verifyProjectAccess()User has role on the project
verifyBuildingAccess()User has role on the building (or its project)
verifyScenarioAccess()User has role on the scenario’s parent project
require* aliasesSame checks, throw on failure

Deprecated (bypass RBAC) — do NOT use:

  • verifyProjectOwnership() — checks ownership only, ignores roles
  • verifyBuildingOwnership() — same problem
  • verifyScenarioOwnership() — same problem

Frontend Permissions

frontend/src/hooks/usePermissions.ts provides reactive permission checks for conditional UI rendering (show/hide buttons, routes, menu items).

The Zustand auth store at frontend/src/store/auth.ts exposes helper methods:

  • isTeamAdmin() — full admin privileges
  • isTeamLead() — team lead within department
  • canCreateUsers() — user creation permission
  • canDeactivateUsers() — user deactivation permission

Department-Based Access

backend/src/lib/department-access.ts adds a department dimension to access control. Users in specific Departments can access resources assigned to their department, even without explicit project/building roles.

Middleware Integration

backend/src/middleware/rbac.ts integrates with the Middleware Stack to enforce authorization on every request. Applied after Authentication middleware but before route handlers.