Service Orders — backend foundation (Task #62)
- New `service_orders` table (status pending|claimed|delivered|received|cancelled) - New `orders:receive` permission + `order_receiver` role; admins implicitly allowed - Added `requirePermission(name)` and `userHasPermission(userId, name)` middleware helpers - New routes: - POST /api/orders place order (authenticated) - GET /api/orders/my list current user's orders - GET /api/orders/incoming receivers see pending+active visible orders - PATCH /api/orders/:id/status claim (atomic), deliver, cancel - PATCH /api/orders/:id/confirm-receipt requester confirms a delivered order - Atomic claim via UPDATE ... WHERE status='pending' AND assigned_to IS NULL (returns 409 already_claimed on race) - Realtime: emits `notification_created` to receivers/requester, `order_incoming_changed` to all receivers, `order_updated` to requester - Service shape in order responses limited to id/nameAr/nameEn/imageUrl (no description fields), per spec - OpenAPI updated with new paths and schemas; codegen run - Seed updated idempotently (permission, role, role_permissions) - New tests in artifacts/api-server/tests/service-orders.test.mjs (full lifecycle, atomic claim race, unauth rejection) — all 21 api tests pass No deviations from the planned scope. Tasks #63 (client UI) and #64 (receiver page + admin role toggle) remain blocked-by #62 and are next.
This commit is contained in:
+36
-10
@@ -37,31 +37,57 @@ async function main() {
|
||||
{ name: "services:manage", descriptionAr: "إدارة الخدمات", descriptionEn: "Manage Services" },
|
||||
{ name: "users:manage", descriptionAr: "إدارة المستخدمين", descriptionEn: "Manage Users" },
|
||||
{ name: "chat:access", descriptionAr: "الوصول للمحادثات", descriptionEn: "Access Chat" },
|
||||
{ name: "orders:receive", descriptionAr: "استقبال الطلبات", descriptionEn: "Receive Service Orders" },
|
||||
];
|
||||
|
||||
const insertedPerms = await db
|
||||
.insert(permissionsTable)
|
||||
.values(permissions)
|
||||
.onConflictDoNothing()
|
||||
.returning();
|
||||
await db.insert(permissionsTable).values(permissions).onConflictDoNothing();
|
||||
const allInsertedPerms = await db.select().from(permissionsTable);
|
||||
|
||||
console.log("Permissions created");
|
||||
|
||||
// Create order_receiver role
|
||||
const [orderReceiverRole] = await db
|
||||
.insert(rolesTable)
|
||||
.values({
|
||||
name: "order_receiver",
|
||||
descriptionAr: "مستقبل الطلبات",
|
||||
descriptionEn: "Service Order Receiver",
|
||||
})
|
||||
.onConflictDoNothing()
|
||||
.returning();
|
||||
|
||||
const allRoles = await db.select().from(rolesTable);
|
||||
const adminRoleResolved = adminRole ?? allRoles.find((r) => r.name === "admin");
|
||||
const userRoleResolved = userRole ?? allRoles.find((r) => r.name === "user");
|
||||
const orderReceiverResolved =
|
||||
orderReceiverRole ?? allRoles.find((r) => r.name === "order_receiver");
|
||||
|
||||
// Assign all permissions to admin role
|
||||
if (adminRole && insertedPerms.length > 0) {
|
||||
if (adminRoleResolved && allInsertedPerms.length > 0) {
|
||||
await db
|
||||
.insert(rolePermissionsTable)
|
||||
.values(insertedPerms.map((p) => ({ roleId: adminRole.id, permissionId: p.id })))
|
||||
.values(allInsertedPerms.map((p) => ({ roleId: adminRoleResolved.id, permissionId: p.id })))
|
||||
.onConflictDoNothing();
|
||||
}
|
||||
|
||||
// Assign chat permission to user role
|
||||
if (userRole && insertedPerms.length > 0) {
|
||||
const chatPerm = insertedPerms.find((p) => p.name === "chat:access");
|
||||
if (userRoleResolved && allInsertedPerms.length > 0) {
|
||||
const chatPerm = allInsertedPerms.find((p) => p.name === "chat:access");
|
||||
if (chatPerm) {
|
||||
await db
|
||||
.insert(rolePermissionsTable)
|
||||
.values({ roleId: userRole.id, permissionId: chatPerm.id })
|
||||
.values({ roleId: userRoleResolved.id, permissionId: chatPerm.id })
|
||||
.onConflictDoNothing();
|
||||
}
|
||||
}
|
||||
|
||||
// Assign orders:receive permission to order_receiver role
|
||||
if (orderReceiverResolved && allInsertedPerms.length > 0) {
|
||||
const ordersPerm = allInsertedPerms.find((p) => p.name === "orders:receive");
|
||||
if (ordersPerm) {
|
||||
await db
|
||||
.insert(rolePermissionsTable)
|
||||
.values({ roleId: orderReceiverResolved.id, permissionId: ordersPerm.id })
|
||||
.onConflictDoNothing();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user