feat(roles): add admin store roles page, permission i18n, and menu integration
Some checks failed
Some checks failed
- Add admin store roles page with merchant→store cascading for superadmin and store-only selection for platform admin - Add permission catalog API with translated labels/descriptions (en/fr/de/lb) - Add permission translations to all 15 module locale files (60 files total) - Add info icon tooltips for permission descriptions in role editor - Add store roles menu item and admin menu item in module definition - Fix store-selector.js URL construction bug when apiEndpoint has query params - Add admin store roles API (CRUD + platform scoping) - Add integration tests for admin store roles and permission catalog Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -699,4 +699,146 @@ Marketing (7 permissions, specialized)
|
||||
|
||||
---
|
||||
|
||||
## Custom Role Management
|
||||
|
||||
### Overview
|
||||
|
||||
Store owners can create, edit, and delete custom roles with granular permission selection. Preset roles (manager, staff, support, viewer, marketing) cannot be deleted but can be edited.
|
||||
|
||||
### Store Role CRUD API
|
||||
|
||||
All endpoints require **store owner** authentication.
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/api/v1/store/team/roles` | List all roles (creates defaults if none exist) |
|
||||
| `POST` | `/api/v1/store/team/roles` | Create a custom role |
|
||||
| `PUT` | `/api/v1/store/team/roles/{id}` | Update a role's name/permissions |
|
||||
| `DELETE` | `/api/v1/store/team/roles/{id}` | Delete a custom role |
|
||||
|
||||
**Validation rules:**
|
||||
- Cannot create/rename a role to a preset name (manager, staff, etc.)
|
||||
- Cannot delete preset roles
|
||||
- Cannot delete a role with assigned team members
|
||||
- All permission IDs are validated against the module-discovered permission catalog
|
||||
|
||||
### Permission Catalog API
|
||||
|
||||
Returns all available permissions grouped by category, with human-readable labels and descriptions.
|
||||
|
||||
```
|
||||
GET /api/v1/store/team/permissions/catalog
|
||||
```
|
||||
|
||||
**Required Permission:** `team.view`
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"id": "team",
|
||||
"label": "tenancy.permissions.category.team",
|
||||
"permissions": [
|
||||
{
|
||||
"id": "team.view",
|
||||
"label": "tenancy.permissions.team_view",
|
||||
"description": "tenancy.permissions.team_view_desc",
|
||||
"is_owner_only": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Permissions are discovered from all module `definition.py` files via `PermissionDiscoveryService.get_permissions_by_category()`.
|
||||
|
||||
### Role Editor UI
|
||||
|
||||
The role editor page at `/store/{store_code}/team/roles`:
|
||||
- Lists all roles (preset + custom) with permission counts
|
||||
- Modal for creating/editing roles with a permission matrix
|
||||
- Permissions displayed with labels, IDs, and hover descriptions
|
||||
- Category-level "Select All / Deselect All" toggles
|
||||
- Owner-only permissions marked with an "Owner" badge
|
||||
|
||||
**Alpine.js component:** `storeRoles()` in `app/modules/tenancy/static/store/js/roles.js`
|
||||
|
||||
**Menu location:** Account section > Roles (requires `team.view` permission)
|
||||
|
||||
---
|
||||
|
||||
## Admin Store Roles Management
|
||||
|
||||
### Overview
|
||||
|
||||
Super admins and platform admins can manage roles for any store via the admin panel. Platform admins are scoped to stores within their assigned platforms.
|
||||
|
||||
### Admin Role CRUD API
|
||||
|
||||
All endpoints require **admin authentication** (`get_current_admin_api`).
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/api/v1/admin/store-roles?store_id=X` | List roles for a store |
|
||||
| `GET` | `/api/v1/admin/store-roles/permissions/catalog` | Permission catalog |
|
||||
| `POST` | `/api/v1/admin/store-roles?store_id=X` | Create a role |
|
||||
| `PUT` | `/api/v1/admin/store-roles/{id}?store_id=X` | Update a role |
|
||||
| `DELETE` | `/api/v1/admin/store-roles/{id}?store_id=X` | Delete a role |
|
||||
|
||||
### Platform Admin Scoping
|
||||
|
||||
Platform admins can only access stores that belong to one of their assigned platforms:
|
||||
|
||||
```python
|
||||
# In StoreTeamService.validate_admin_store_access():
|
||||
# 1. Super admin (accessible_platform_ids is None) → access all stores
|
||||
# 2. Platform admin → store must exist in StorePlatform where
|
||||
# platform_id is in the admin's accessible_platform_ids
|
||||
```
|
||||
|
||||
The scoping is enforced at the service layer via `validate_admin_store_access()`, called by every admin endpoint before performing operations.
|
||||
|
||||
### Admin UI
|
||||
|
||||
Page at `/admin/store-roles`:
|
||||
- Tom Select store search/selector (shared `initStoreSelector()` component)
|
||||
- Platform admins see only stores in their assigned platforms
|
||||
- Same role CRUD and permission matrix as the store-side UI
|
||||
- Located in the "User Management" admin menu section
|
||||
|
||||
**Alpine.js component:** `adminStoreRoles()` in `app/modules/tenancy/static/admin/js/store-roles.js`
|
||||
|
||||
### Audit Trail
|
||||
|
||||
All role operations are logged via `AuditAggregatorService`:
|
||||
|
||||
| Action | Description |
|
||||
|--------|-------------|
|
||||
| `role.create` | Custom role created |
|
||||
| `role.update` | Role name or permissions modified |
|
||||
| `role.delete` | Custom role deleted |
|
||||
| `member.role_change` | Team member assigned a different role |
|
||||
| `member.invite` | Team member invited |
|
||||
| `member.remove` | Team member removed |
|
||||
|
||||
---
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `app/modules/tenancy/services/store_team_service.py` | Role CRUD, platform scoping, audit trail |
|
||||
| `app/modules/tenancy/services/permission_discovery_service.py` | Permission catalog, role presets |
|
||||
| `app/modules/tenancy/routes/api/store_team.py` | Store team & role API endpoints |
|
||||
| `app/modules/tenancy/routes/api/admin_store_roles.py` | Admin store role API endpoints |
|
||||
| `app/modules/tenancy/schemas/team.py` | Request/response schemas |
|
||||
| `app/modules/tenancy/static/store/js/roles.js` | Store role editor Alpine.js component |
|
||||
| `app/modules/tenancy/static/admin/js/store-roles.js` | Admin role editor Alpine.js component |
|
||||
| `app/modules/tenancy/templates/tenancy/store/roles.html` | Store role editor template |
|
||||
| `app/modules/tenancy/templates/tenancy/admin/store-roles.html` | Admin role editor template |
|
||||
|
||||
---
|
||||
|
||||
This RBAC system provides flexible, secure access control for store dashboards with clear separation between owners and team members.
|
||||
|
||||
Reference in New Issue
Block a user