RBAC & Users¶
Backend domains:
- app/graphql/rbac/ — role-based access control
- app/graphql/users/ — user accounts, sessions, signatures
- app/graphql/billing/ — subscription / plan / seat billing
RBAC¶
RBAC is path-based. Every protected mutation/query checks a Path enum against the calling user's permissions:
- Paths — one per domain (
INVOICES,RECEIPTS,PAYMENTS,PAYROLL,FIXED_ASSETS,BANK_RECONCILIATIONS,AUDIT_LOG,PERIOD_CLOSE,RECURRING_*, …). New domains must declare a path. - Resources — finer-grained operations under a path (
CREATE,READ,UPDATE,DELETE, plus domain-specific likePOST,VOID,REVERSE). - Roles — named bundles of (path, resource) grants (e.g.
Owner,Accountant,Salesperson,Warehouse). - User → Role assignment governs effective permissions.
Two layers of mutation:
updatePathPermissions— grant/revoke at the path level (turn the menu on/off).updateRolePermissions— fine-grained per-resource grants inside a path.
Key queries: pathPermissions, roleResourcePermissions, getUserRoleResourcePermissions.
Combinations of paths are precomputed in combinations.py for fast menu rendering on the frontend.
Users¶
User identity is federated via FusionAuth + WorkOS, but a local User row captures profile, avatar, signature image, and tenant-scoped settings.
Key mutations: createUser, updateUser, archiveUser, deleteUser, uploadSignature.
Key queries: getUserInfo, userSearch, getUserById, sessionInfo.
Session rows track logged-in sessions per user — useful for audit and remote-logout. OTC (one-time-code) settings under otc/ govern 2FA / OTP if enabled.
Billing¶
app/graphql/billing/ tracks the tenant's plan, seat count, and invoice line items for the SaaS bill itself (distinct from the customer invoices the tenant issues). Most PYME-facing pricing logic lives here.
Frontend notes¶
- Menu visibility is driven entirely by
pathPermissions. - Resource-level checks should be done on each mutation button (e.g. a Salesperson sees the invoice but cannot click "Void").
- Show a friendly "Hablá con tu admin" error rather than a raw 403 — RBAC errors carry a structured code from the backend.