TotalApp Docs

Roles & Add-On Access

An end-to-end overview of TotalApp's Role-Based Access Control (RBAC), add-on package entitlement, and screen-guarding (ModuleGuard) architecture.

1. Conceptual Model

The system is built on a four-layer hierarchy: Tenant → Purchased Packages (Entitlement) → Domain Capabilities → Roles → Employee assignedRoles ("hat").

ConceptWhat it is
DomainAn add-on's RBAC tag (LEGAL, HEALTHCARE, MOM…). Every role and capability belongs to a domain.
CapabilityAn atomic permission written as domain:resource:action (legal:contract:approve).
RoleA named bundle of capabilities (Senior Partner, Plant Manager). It is domain-tagged.
assignedRole (hat)A role assigned to a person. One person can hold roles in multiple domains ("multi-hat"). Assigning a role copies its capabilities onto the person (auto-grant).
Entitlement (package)The add-on packages a tenant has activated.

Capability ≠ Skill

A capability decides what a person can do in the platform (a system permission). A skill (Python, Laparoscopy, Contract Law) is a personal competency managed by HR — it does not affect access. A role binds capabilities; assigning a "Paralegal" role to someone instantly grants all of that role's capabilities.

2. Decentralized Role Management

Every add-on has its own Roles screen, but all roles live in a single tenant store. Each role is tagged with its domain in the background — you never fill in a "type" field; the tag comes from the screen you're on (implicit tagging).

Add-on Scoping

An add-on screen shows only GLOBAL + its own domain's roles and capabilities. A Legal manager cannot see Healthcare capabilities — a security boundary.

HR Master Matrix

HR → Organization → Roles & Permissions shows every domain's roles in one matrix, offers a domain filter, and provides final override over add-on roles.

Out-of-the-Box Roles

When an add-on package is active, the first time its Roles screen is opened the system seeds default roles automatically. A customer can add staff without defining a single role by hand.

3. Package Entitlement

Which add-ons each tenant has activated is stored per tenant (activePackages). The application side reads its own entitlement; the admin side (cross-tenant) can write any tenant's — the same file. So what an admin activates is exactly what ModuleGuard reads (one SSoT).

4. ModuleGuard — Two-Level Screen Protection

Every add-on screen is wrapped in <ModuleGuard> and rendered inside the app layout — a blocked screen shows a friendly Upsell/403 panel instead of a blank page or a 500 error.

Level 1 — Entitlement (Paywall)

Has the tenant purchased this add-on package? If not → an Upsell/Upgrade screen: "The [Module] module is not included in your subscription. Upgrade your plan or contact your administrator."

Level 2 — RBAC (Governance / Operational)

System/Governance data (Roles, Staff-Master) is admin-only; Operational data (Jobsites, Zones, Work Centers, Fields…) is open to any user holding a role in that domain. Otherwise → 403 Access Denied.

UserGovernanceOperational
Administrator (or local/demo)AllowedAllowed
User holding a domain role403 DeniedAllowed
User without a domain role403 Denied403 Denied
Package not activePaywallPaywall

5. UI Visibility — Hiding Governance Cards

A 403 isn't enough; an unauthorized user should never even see governance cards. The sidebar and My Apps don't render these cards for non-admins. Each add-on's setup screens are split into two titled groups: OPERATIONAL SETUP (open to operational staff) and ADMINISTRATION & ACCESS (Roles + Staff-Master; admins only).

6. Staff Assignment — Auto-Grant & Multi-Hat

  1. Auto-grant: selecting a role attaches the role's capabilities to the person automatically; no separate trip to HR to grant permissions.
  2. Multi-hat (+ Add Existing Employee): an existing employee is added to another add-on without creating a duplicate record. For example, one person can hold both LEGAL: Senior Partner and HEALTHCARE: Advisor hats.
  3. Detach: removing a person from a team revokes that domain's hats (the employee record and HR history are never deleted).

7. Path & Title Standard

The URL is generic and domain-prefixed (/{domain}/roles, /{domain}/staff); the title is domain-specific (/legal/staff → "Legal Team", /mom/staff → "Plant Workers").

Frequently Asked Questions

Why can I open every screen locally without assigning any roles?
Local/skipped/no-JWT sessions are treated as admin — with no tenant RBAC context yet, the app stays fully usable. For a real tenant user, RBAC applies normally.
Why doesn't a regular employee see the Roles screen at all?
Roles is a governance screen; those cards aren't rendered for non-admins, and navigating there directly returns a 403.
Is what the admin activates the same as what the app enforces?
Yes — both read and write the same entitlement file. There is no separate central store.