Aller au contenu principal

Permissions

RBAC matrix with 143 granular permissions across 7 roles.

Contents

Overview

HeartCo uses a role-based access control (RBAC) system defined in a single file that acts as the source of truth.

File: src/lib/permissions/matrix.ts

Role hierarchy

ADMIN (0) ─── Full access
  │
DIRECTION (1) ─── Extended read access, approval
  │
MANAGER (2) ─── Operational management
  │
HR (3) / ACCOUNTANT (3) ─── Specialized functions
  │
COLLABORATOR (4) ─── Limited access (own data)
  │
CLIENT (99) ─── Portal only (0 permissions)

HR and ACCOUNTANT share the same hierarchy level but have different permission sets.

Full matrix by category

Invoicing (9 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
facturation:read
facturation:read_own
facturation:create
facturation:edit
facturation:delete
facturation:send
facturation:mark_paid
facturation:export
facturation:void

Quotes (6 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
devis:read
devis:create
devis:edit
devis:delete
devis:send
devis:convert_to_invoice

Accounting (3 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
comptabilite:read
comptabilite:export_fec
comptabilite:reconcile

Clients (5 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
clients:read
clients:create
clients:edit
clients:delete
clients:export

CRM (5 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
crm:read
crm:create
crm:edit
crm:delete
crm:assign

Expense reports (6 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
notes_frais:read_own
notes_frais:read_all
notes_frais:create
notes_frais:edit_own
notes_frais:approve
notes_frais:export

Projects (4 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
project:read
project:create
project:edit
project:delete

Work orders (4 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
workorder:read
workorder:create
workorder:edit
workorder:delete

Field reports (6 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
rapports:read_own
rapports:read_all
rapports:create
rapports:edit_own
rapports:finalize
rapports:sign

HR (6 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
rh:read_own
rh:read_all
rh:manage_leaves
rh:manage_payslips
rh:manage_profiles
rh:export_dsn

Members (4 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
membres:read
membres:invite
membres:edit_roles
membres:deactivate

Timesheets (4 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
timesheets:read_own
timesheets:read_all
timesheets:create
timesheets:approve

Settings (6 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
settings:read
settings:edit_org
settings:edit_billing
settings:manage_webhooks
settings:view_audit_log
settings:manage_permissions

Marketing (3 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
marketing:read
marketing:create
marketing:send_campaigns

E-invoicing (2 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
e_invoicing:read
e_invoicing:submit

AI & Copilot (3 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
ia:use_basic
ia:use_advanced
ia:view_insights

Automations (2 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
automation:read
automation:manage

Inventory (3 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
stock:read
stock:write
stock:export

Analytics (2 permissions)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
analytics:read_own
analytics:read_org

Superadmin (1 permission)

PermissionADMINDIRECTIONMANAGERHRACCOUNTANTCOLLAB
superadmin:access

superadmin:access is not granted to any role by default. It is reserved for platform administration.

Summary by role

RoleNumber of permissions
ADMIN~60+ (everything except superadmin)
DIRECTION~26 (extended read access + approval)
MANAGER~36 (operational CRUD)
HR~14 (HR, time, leave)
ACCOUNTANT~13 (accounting, exports)
COLLABORATOR~12 (their own data)
CLIENT0 (portal only)

Utility functions

import {
  hasPermission,
  hasAnyPermission,
  hasAllPermissions,
  getRolePermissions,
  isRoleAtLeast,
  canManageRole,
} from "~/lib/permissions/matrix";
 
// Check a permission
hasPermission("MANAGER", "facturation:create"); // true
hasPermission("COLLABORATOR", "facturation:create"); // false
 
// Check for at least one permission among several
hasAnyPermission("MANAGER", ["facturation:read", "devis:read"]); // true
 
// Check the hierarchy
isRoleAtLeast("MANAGER", "COLLABORATOR"); // true (2 ≤ 4)
isRoleAtLeast("COLLABORATOR", "MANAGER"); // false (4 > 2)
 
// Check whether a role can manage another
canManageRole("ADMIN", "MANAGER"); // true
canManageRole("MANAGER", "ADMIN"); // false

Usage in tRPC routers

Single permission

export const facturationRouter = createTRPCRouter({
  create: requirePermission("facturation:create")
    .input(schema)
    .mutation(async ({ ctx, input }) => {
      // Only ADMIN and MANAGER reach this point
    }),
});

Multiple permissions (at least one)

export const analyticsRouter = createTRPCRouter({
  overview: requireAnyPermission(["analytics:read_own", "analytics:read_org"])
    .query(async ({ ctx }) => {
      // ADMIN, DIRECTION, MANAGER or COLLABORATOR
    }),
});

Adding a new permission

1. Define the permission

In src/lib/permissions/matrix.ts, add the string to the Permission type and to each role's matrix:

// Permission type — add the new entry
type Permission = ... | "my_module:read" | "my_module:create" | "my_module:edit" | "my_module:delete";
 
// ADMIN matrix — add the permissions
ADMIN: [..., "my_module:read", "my_module:create", "my_module:edit", "my_module:delete"],
MANAGER: [..., "my_module:read", "my_module:create", "my_module:edit"],
// etc.

2. Use it in the router

requirePermission("my_module:create")

3. (Optional) Check on the client

const { data: session } = useSession();
const canCreate = hasPermission(session?.user.role, "my_module:create");

◀ Modules · Contents · Payments ▶