Roles & Module Permissions
Overview
Permissions follow a role → module → actions model: a lightweight RBAC where the action list is stored as a comma-separated string. A "module" here means one CMS feature — campaign, rich-menu, audiences and so on — and the module name in the database must match the PolicyModule enum on the API side exactly.
Access is granted in two stacked layers: system_role_module (what a role may do) and organization_module (which modules a given organization has switched on, effectively a per-customer feature flag). A user reaches a module only when both layers allow it.
Core Data Structure
system_module
The registry of every module in the system, holding name (must match the API side), actions such as 'readAll,read,create,update,delete', and status.
system_role
Role definitions, made up of name, type (UserType: onemoby or customer), total and status.
The seeded roles are:
| id | name | type | Notes |
|---|---|---|---|
| 1 | super-admin | onemoby | Highest platform privilege |
| 2 | admin | onemoby | |
| 3 | staff | onemoby | |
| 4 | admin | customer | Customer-side administrator |
| 5 | staff | customer | Added later; same rights as role 4 minus the user and line-oa modules |
system_role_module
The join table between roles and modules, carrying the actions a role is actually allowed to perform. It has FKs role_id to system_role.id and module_id to system_module.id. There is no deleted_date, so removals are hard deletes.
organization_module
Created via manual SQL and absent from Prisma, it holds (organization_id, module_id, actions) and is used to enable modules for individual customer-admin organizations.
An important caveat: any migration that introduces a new module must insert into both system_role_module and organization_module, otherwise the module never becomes visible to customers. The end of manual-sql/9.import_mapping.sql shows the pattern.
Users tie into this through user.role_id, which points at system_role.id.
Related Files
prisma/schema.prisma:241— modelSystemRoleprisma/schema.prisma:261— modelSystemModuleprisma/schema.prisma:278— modelSystemRoleModuleseed-data/01.system_module.sql— all 24 modules, with a comment noting they must stay in sync withpolicy.enum.tsseed-data/02.system_role.sqlandseed-data/03.system_role_module.sql— role and grant seedsprisma/migrations/20260727060000_add_customer_staff_role/migration.sql— adds the customer-sidestaffrolemanual-sql/9.import_mapping.sql— a worked example of registering a new module and granting it to roles 1-3 and every organizationschema-dumps/2026-07-24/schema.sql:2423—organization_module
Connections to Other Services
- cms-api-go — the
ModuleGatemiddleware reads these tables to allow or reject each route. - cms-web — uses the permission result returned by the API to hide or show menu items so the UI matches what the user can actually do.
- Connects to CMS Users & Authentication via
user.role_idand Organizations & Plans viaorganization_module.