feat(api): complete M5 swap and dispatch backend slice

This commit is contained in:
zouantchaw
2026-03-18 10:40:04 +01:00
parent 32f6cd55c8
commit 26a853184f
18 changed files with 2170 additions and 109 deletions

View File

@@ -45,6 +45,9 @@ Full auth behavior, including staff phone flow and refresh rules, is documented
- `GET /client/coverage/core-team`
- `GET /client/coverage/incidents`
- `GET /client/coverage/blocked-staff`
- `GET /client/coverage/swap-requests`
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates`
- `GET /client/hubs`
- `GET /client/cost-centers`
- `GET /client/vendors`
@@ -80,6 +83,10 @@ Full auth behavior, including staff phone flow and refresh rules, is documented
- `POST /client/billing/invoices/:invoiceId/dispute`
- `POST /client/coverage/reviews`
- `POST /client/coverage/late-workers/:assignmentId/cancel`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
Coverage-review request payload may also send:
@@ -94,6 +101,45 @@ Coverage-review request payload may also send:
If `markAsBlocked` is `true`, backend adds that staff member to the business-level blocked list and future apply or assign attempts are rejected until a later review sends `markAsBlocked: false`.
Swap-review routes:
- `GET /client/coverage/swap-requests?status=OPEN`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
Resolve example:
```json
{
"applicationId": "uuid",
"note": "Dispatch selected the strongest replacement candidate"
}
```
Dispatch-team routes:
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates?shiftId=uuid&roleId=uuid`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
Dispatch-team membership example:
```json
{
"staffId": "uuid",
"hubId": "uuid",
"teamType": "CORE",
"notes": "Preferred lead barista for this location"
}
```
Dispatch priority order is:
1. `CORE`
2. `CERTIFIED_LOCATION`
3. `MARKETPLACE`
Shift-manager creation example:
```json
@@ -257,6 +303,9 @@ These are exposed as direct unified aliases even though they are backed by `core
- `GET /client/coverage/incidents` is the review feed for geofence breaches, missing-location batches, and clock-in overrides.
- `GET /client/coverage/blocked-staff` is the review feed for workers currently blocked by that business.
- `POST /client/coverage/late-workers/:assignmentId/cancel` is the client-side recovery action when lateness is confirmed by incident evidence or elapsed grace time.
- `GET /client/coverage/swap-requests` is the manager/ops review feed for swap requests, candidate applications, and status.
- `GET /client/coverage/dispatch-candidates` returns ranked candidates with the dispatch-team priority already applied.
- swap auto-cancellation is backend-driven. If a swap request expires without a replacement, backend cancels the original assignment, marks the swap request `AUTO_CANCELLED`, and alerts both the manager path and the original worker.
- Raw location stream payloads are stored in the private v2 bucket; SQL only stores the summary and incident index.
- Push delivery is backed by:
- SQL token registry in `device_push_tokens`