Let admins create and edit roles from the dashboard (Task #82)
What changed:
- Added an `is_system` column to the `roles` table (default 0). The
built-in roles (admin, user, order_receiver) are flagged as system roles
in the seed and via a one-off UPDATE on the existing dev DB.
- Created a new `/api/roles` route module with admin-guarded endpoints:
- POST /api/roles – create a role (validates name format, rejects duplicates).
- PATCH /api/roles/:id – update bilingual descriptions; name is immutable.
- DELETE /api/roles/:id – returns 400 for system roles (also defended
by name allowlist), 409 with userCount/groupCount when in use, 204 on
success. Cleans up role_permissions in a transaction.
GET /api/roles was moved out of groups.ts into the new module.
- OpenAPI updated with createRole / updateRole / deleteRole operations,
isSystem on the Role schema, and CreateRoleBody / UpdateRoleBody /
RoleDeletionConflict schemas. Regenerated api-zod and api-client-react.
- Added a "Roles" item under the User Management nav group in the admin
dashboard, plus a new RolesPanel with search, create dialog, edit dialog
(description-only), and delete dialog with conflict messaging.
- Bilingual translations added in en.json and ar.json (admin.nav.roles +
admin.roles.*).
Notes / deviations:
- Also marked `order_receiver` as a system role since it is seeded by the
system and required by the orders feature, even though the task brief
only called out admin and user.
- Verified end-to-end via the testing skill: list, create, edit, delete,
duplicate-name validation, and protection of system roles all work.
Replit-Task-Id: b1187555-be09-4687-a9ae-83b123d908bd
This commit is contained in:
+3
-2
@@ -23,13 +23,13 @@ async function main() {
|
||||
// Create roles
|
||||
const [adminRole] = await db
|
||||
.insert(rolesTable)
|
||||
.values({ name: "admin", descriptionAr: "مدير النظام", descriptionEn: "System Administrator" })
|
||||
.values({ name: "admin", descriptionAr: "مدير النظام", descriptionEn: "System Administrator", isSystem: 1 })
|
||||
.onConflictDoNothing()
|
||||
.returning();
|
||||
|
||||
const [userRole] = await db
|
||||
.insert(rolesTable)
|
||||
.values({ name: "user", descriptionAr: "مستخدم عادي", descriptionEn: "Regular User" })
|
||||
.values({ name: "user", descriptionAr: "مستخدم عادي", descriptionEn: "Regular User", isSystem: 1 })
|
||||
.onConflictDoNothing()
|
||||
.returning();
|
||||
|
||||
@@ -56,6 +56,7 @@ async function main() {
|
||||
name: "order_receiver",
|
||||
descriptionAr: "مستلم الطلبات",
|
||||
descriptionEn: "Order Receiver",
|
||||
isSystem: 1,
|
||||
})
|
||||
.onConflictDoNothing()
|
||||
.returning();
|
||||
|
||||
Reference in New Issue
Block a user