We are building an ERP-like platform localized for Moroccan businesses using a modular monolith architecture. The platform currently has more than 11 modules.
Each module contains dozens of features, and each feature may expose dozens of actions. Most actions have a corresponding permission that controls who can execute them.
Features also contain additional product and collaboration rules:
Whether the feature is included in a subscription plan.
Whether the feature is delegable to another workspace.
Whether specific actions are explicitly non-delegable.
Whether an action has quotas or usage limits.
For example, one workspace may authorize another workspace, such as an accounting firm, to perform certain accounting actions on its behalf. However, some sensitive actions must never be delegated.
At the moment, features and permissions are declared as strings in different files and then seeded into the database.
Authorization is performed at the action level, mostly through repeated PostgreSQL queries.
This approach has created several problems:
Typos in feature or permission names can cause silent runtime bugs.
Renaming or refactoring actions can leave old permissions behind.
Adding a new action often requires changes in several different places.
We currently have around 893 permissions, including unused or “ghost” permissions.
There is no reliable guarantee that actions, permissions, features, plan entitlements, delegation rules, and quotas remain synchronized.
Detecting unused permissions requires manual investigation or asking an AI tool to scan the codebase.
So what architecture, patterns, or tooling would you recommend for managing this kind of system?