Allow reordering services even when not all are provided

Modify the service reorder endpoint to handle cases where the client sends a partial list of service IDs, ensuring that unprovided services are appended to the end of the list without causing validation errors.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 4a518c00-92a6-443c-95de-44f6faa44d35
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/qrzw3bH
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
riyadhafraa
2026-05-20 18:47:58 +00:00
parent 674924f974
commit ea8ee1af51
+24 -10
View File
@@ -87,34 +87,48 @@ router.patch("/services/reorder", requireAdmin, async (req, res): Promise<void>
}
const { orderedIds } = parsed.data;
// Validate the provided ids are unique and all reference real
// services. We intentionally do NOT require the client to send
// every service id — the iPad UI may filter or hide rows, and
// forcing a full snapshot caused false 400s ("orderedIds must
// contain every service id exactly once"). Any services that
// weren't included are pushed to the end of the list so they
// remain visible without colliding on sortOrder.
const existing = await db
.select({ id: servicesTable.id })
.from(servicesTable);
const existingIds = new Set(existing.map((s) => s.id));
if (orderedIds.length !== existingIds.size) {
res.status(400).json({
error: "orderedIds must contain every service id exactly once",
});
return;
}
const seen = new Set<number>();
for (const id of orderedIds) {
if (!existingIds.has(id) || seen.has(id)) {
res.status(400).json({
error: "orderedIds must contain every service id exactly once",
error: "orderedIds contains a duplicate or unknown service id",
});
return;
}
seen.add(id);
}
const trailingIds = existing
.map((s) => s.id)
.filter((id) => !seen.has(id));
await db.transaction(async (tx) => {
for (let i = 0; i < orderedIds.length; i++) {
let index = 0;
for (const id of orderedIds) {
await tx
.update(servicesTable)
.set({ sortOrder: i })
.where(eq(servicesTable.id, orderedIds[i]));
.set({ sortOrder: index })
.where(eq(servicesTable.id, id));
index += 1;
}
for (const id of trailingIds) {
await tx
.update(servicesTable)
.set({ sortOrder: index })
.where(eq(servicesTable.id, id));
index += 1;
}
});