feat(api): add staff order detail and compliance eligibility
This commit is contained in:
@@ -120,6 +120,7 @@ For geofence-heavy staff flows, frontend should read the policy from:
|
||||
|
||||
- `GET /staff/clock-in/shifts/today`
|
||||
- `GET /staff/shifts/:shiftId`
|
||||
- `GET /staff/orders/:orderId`
|
||||
- `GET /client/hubs`
|
||||
|
||||
Important operational rules:
|
||||
|
||||
@@ -23,7 +23,7 @@ Supporting docs:
|
||||
- Send `Idempotency-Key` on every write route.
|
||||
- Treat `order`, `shift`, `shiftRole`, and `assignment` as different objects.
|
||||
- For staff shift applications, `roleId` must come from the response of `GET /staff/shifts/open`.
|
||||
- For staff order booking, `roleId` must come from the response of `GET /staff/orders/available`.
|
||||
- For staff order booking, `roleId` must come from the response of `GET /staff/orders/:orderId`.
|
||||
- Treat API timestamp fields as UTC and convert them to local time in the app.
|
||||
|
||||
## 2) What is implemented now
|
||||
@@ -235,14 +235,17 @@ Important:
|
||||
### Find shifts
|
||||
|
||||
- `GET /staff/orders/available`
|
||||
- `GET /staff/orders/:orderId`
|
||||
- `POST /staff/orders/:orderId/book`
|
||||
- `GET /staff/shifts/open`
|
||||
- `POST /staff/shifts/:shiftId/apply`
|
||||
|
||||
Rule:
|
||||
|
||||
- use `roleId` from the order-available response when booking an order
|
||||
- use `GET /staff/orders/:orderId` as the source of truth for the order details page
|
||||
- use `roleId` from the order-detail response when booking an order
|
||||
- that `roleId` is the role catalog id for the grouped order booking flow
|
||||
- if order booking returns `422`, render `details.blockers` and keep the worker on the order details page
|
||||
- use `roleId` from the open-shifts response only for shift-level apply
|
||||
- that `roleId` is the concrete `shift_roles.id`
|
||||
|
||||
@@ -260,6 +263,7 @@ Rule:
|
||||
|
||||
Staff shift detail and list rules:
|
||||
|
||||
- `GET /staff/orders/:orderId` returns the worker booking detail contract with `schedule`, `location`, `pay`, `staffing`, `managers`, and `eligibility`
|
||||
- assigned shifts include `clientName`, `hourlyRate`, `totalRate`, `startTime`, `endTime`
|
||||
- shift detail includes `clientName`, `latitude`, `longitude`, `hourlyRate`, `totalRate`
|
||||
- completed shifts include `date`, `clientName`, `startTime`, `endTime`, `hourlyRate`, `totalRate`
|
||||
|
||||
@@ -32,6 +32,7 @@ Important consequences:
|
||||
- `POST /staff/shifts/:shiftId/apply` must send the `roleId` from that response.
|
||||
- `GET /staff/orders/available` returns grouped order opportunities for atomic booking.
|
||||
- `POST /staff/orders/:orderId/book` must send the `roleId` from that response.
|
||||
- if order booking returns `422`, use `details.blockers` to explain why the worker is not eligible
|
||||
- `GET /client/shifts/scheduled` is the canonical timeline/read model for the client app.
|
||||
- `GET /client/orders/view` is a deprecated compatibility alias.
|
||||
- `POST /client/orders/:orderId/edit` and `POST /client/orders/:orderId/cancel` only affect future shifts.
|
||||
@@ -180,14 +181,17 @@ Rapid-order flow:
|
||||
### Find shifts
|
||||
|
||||
- `GET /staff/orders/available`
|
||||
- `GET /staff/orders/:orderId`
|
||||
- `POST /staff/orders/:orderId/book`
|
||||
- `GET /staff/shifts/open`
|
||||
- `POST /staff/shifts/:shiftId/apply`
|
||||
|
||||
Rule:
|
||||
|
||||
- send the `roleId` from the order-available response when booking an order
|
||||
- use `GET /staff/orders/:orderId` as the source of truth for the order details page
|
||||
- send the `roleId` from the order-detail response when booking an order
|
||||
- this `roleId` is the role catalog id for grouped order booking
|
||||
- if booking fails with `422`, render `details.blockers` and keep the worker on the review screen
|
||||
- send the `roleId` from the open-shifts response only when applying to one shift
|
||||
- that route still uses the concrete `shift_roles.id`
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Base URL:
|
||||
## Read routes
|
||||
|
||||
- `GET /staff/orders/available`
|
||||
- `GET /staff/orders/:orderId`
|
||||
- `GET /staff/shifts/assigned`
|
||||
- `GET /staff/shifts/open`
|
||||
- `GET /staff/shifts/pending`
|
||||
@@ -80,6 +81,7 @@ Example response:
|
||||
- booking is atomic across the future shifts in that order for the selected role
|
||||
- backend returns `PENDING` when the booking is reserved but not instant-booked
|
||||
- backend returns `CONFIRMED` when every future shift in that booking path is instant-booked
|
||||
- backend returns `422 UNPROCESSABLE_ENTITY` when the worker is not eligible to book that order
|
||||
|
||||
Example request:
|
||||
|
||||
@@ -91,8 +93,44 @@ Example request:
|
||||
|
||||
Important:
|
||||
|
||||
- `roleId` for the order-booking flow is the role catalog id returned by `GET /staff/orders/available`
|
||||
- `GET /staff/orders/:orderId` is now the source of truth for the order detail screen before booking
|
||||
- `roleId` for the order-booking flow is the role catalog id returned by `GET /staff/orders/:orderId`
|
||||
- it is not the same thing as the per-shift `shift_roles.id`
|
||||
- when booking is rejected, use `details.blockers` from the error response to explain why
|
||||
|
||||
### Order detail
|
||||
|
||||
`GET /staff/orders/:orderId`
|
||||
|
||||
Use this as the source of truth for the worker order-review page before calling `POST /staff/orders/:orderId/book`.
|
||||
|
||||
Response shape includes:
|
||||
|
||||
- `orderId`
|
||||
- `orderType`
|
||||
- `roleId`
|
||||
- `roleCode`
|
||||
- `roleName`
|
||||
- `clientName`
|
||||
- `businessId`
|
||||
- `instantBook`
|
||||
- `dispatchTeam`
|
||||
- `dispatchPriority`
|
||||
- `jobDescription`
|
||||
- `instructions`
|
||||
- `status`
|
||||
- `schedule`
|
||||
- `location`
|
||||
- `pay`
|
||||
- `staffing`
|
||||
- `managers`
|
||||
- `eligibility`
|
||||
|
||||
Frontend rules:
|
||||
|
||||
- call this endpoint after a worker taps an order card from `GET /staff/orders/available`
|
||||
- use the returned `roleId` when calling `POST /staff/orders/:orderId/book`
|
||||
- if `eligibility.isEligible` is `false`, show the blocker messages and disable booking
|
||||
|
||||
### Find shifts
|
||||
|
||||
|
||||
@@ -184,6 +184,7 @@ The manager is created as an invited business membership. If `hubId` is present,
|
||||
- `GET /staff/payments/history`
|
||||
- `GET /staff/payments/chart`
|
||||
- `GET /staff/orders/available`
|
||||
- `GET /staff/orders/:orderId`
|
||||
- `GET /staff/shifts/assigned`
|
||||
- `GET /staff/shifts/open`
|
||||
- `GET /staff/shifts/pending`
|
||||
@@ -250,9 +251,12 @@ Example `GET /staff/profile/stats` response:
|
||||
Order booking route notes:
|
||||
|
||||
- `GET /staff/orders/available` is the canonical order-level marketplace feed for recurring and grouped work
|
||||
- `GET /staff/orders/:orderId` is the canonical staff order-detail route before booking
|
||||
- `GET /staff/shifts/open` remains available for shift-level opportunities and swap coverage
|
||||
- `POST /staff/orders/:orderId/book` books the future shifts of an order atomically for one role
|
||||
- the `roleId` returned by `GET /staff/orders/available` is the role catalog id for the order booking flow
|
||||
- if booking is rejected for eligibility reasons, backend returns `422 UNPROCESSABLE_ENTITY` with `details.blockers`
|
||||
- use the `roleId` returned by `GET /staff/orders/:orderId` when booking
|
||||
- that `roleId` is the role catalog id for the order booking flow
|
||||
- the `roleId` returned by `GET /staff/shifts/open` is still the concrete `shift_roles.id` for shift-level apply
|
||||
|
||||
### Staff writes
|
||||
|
||||
Reference in New Issue
Block a user