Roles (Admin)
Executive summary
Section titled “Executive summary”Roles define admin_roles.modules JSON exposed on JWT as modules: string[] | null. This page is the canonical explanation of null = full access vs array = keyed features (e.g. item for catalog).
Goals and non-goals
Section titled “Goals and non-goals”| Goals | Non-goals |
|---|---|
| Align SPA behavior with backend guards | Edit Laravel DB by hand from this doc |
| Help debug 403 vs “sidebar still visible” | List every guard class |
Current platform behavior
Section titled “Current platform behavior”modules === null: backend full module access (Master-style).- Array: each string is a module key; missing keys → 403 on APIs (Admin overview).
Sequence: happy path
Section titled “Sequence: happy path”- Open Roles list → create or edit role.
- Set
modulestonullor explicit keys → save. - Assign managers to role → JWT reflects on next login/me.
Security and operations
Section titled “Security and operations”- Least privilege: prefer explicit keys over
nullexcept true superusers. - Changing keys is a release coordination step with backend
ADMIN_PANEL_MODULE_*constants.
Test scenarios (UAT / QA)
Section titled “Test scenarios (UAT / QA)”| ID | Scenario | Expected |
|---|---|---|
| R1 | Role with item | Catalog APIs succeed |
| R2 | Role without item | Catalog 403 |
| R3 | modules: null | Broad access per backend rules |
Routes
Section titled “Routes”/dashboard/roles,/dashboard/roles/new,/dashboard/roles/:id,/dashboard/roles/:id/edit
/dashboard/roles/:id is now the detail page with:
- Subscribed customers = admin users assigned to that role.
- Plan details = permission modules and total permission count.
Admin role API endpoints
Section titled “Admin role API endpoints”GET /admin/rolesGET /admin/roles/:idGET /admin/roles/:id/detail— role detail withsubscribedCustomersandplanDetails.permissionModulesPOST /admin/rolesPATCH /admin/roles/:idDELETE /admin/roles/:id
Modules (admin_roles.modules)
Section titled “Modules (admin_roles.modules)”- Stored as JSON on the role in the legacy Laravel schema; exposed on JWT login/me as
modules: string[] | null(AdminLoginResponse/AdminMeResponseinapps/admin-web/src/types/admin-auth.types.ts). modules === null: backend treats this as full module access (Master Admin style). Guards such asAdminItemModuleGuardallow any module whenmodules === null.modulesas an array: each string is a feature key (e.g. catalog is oftenitemfor products — see backendADMIN_PANEL_MODULE_ITEM/ product APIs). Restricted admins receive 403 when calling APIs for modules not in their list.
Master vs restricted
Section titled “Master vs restricted”- Master admin (e.g.
role_id1 in Laravel parity — seeadmin-auth.controllerAPI docs) typically hasmodules: null. - Custom roles use an explicit module list; assign the minimum keys needed for each job function.
Sidebar vs module keys (practical map)
Section titled “Sidebar vs module keys (practical map)”The admin sidebar does not read modules to hide links; enforcement is on the API. Known backend constant:
| Module key | Used for (example) |
|---|---|
item | Catalog / products (ADMIN_PANEL_MODULE_ITEM in apps/backend/src/modules/admin/admin.constants.ts; guarded by AdminItemModuleGuard). |
Other areas (orders, stores, vendors, optional Zones registry) rely on service-level checks per controller — extend this table when new ADMIN_PANEL_MODULE_* constants and guards are added.
Optional follow-up
Section titled “Optional follow-up”- Screenshot walkthrough of creating a role in
/dashboard/roles.
Related
Section titled “Related”- Admin panel overview —
moduleson the session. - Authentication — JWT and refresh.