fix(api): close M5 frontend contract gaps
This commit is contained in:
@@ -81,6 +81,29 @@ All routes return the same error envelope:
|
||||
}
|
||||
```
|
||||
|
||||
## 3.1) Time handling
|
||||
|
||||
V2 stores operational timestamps in UTC using PostgreSQL `TIMESTAMPTZ`.
|
||||
|
||||
Rules:
|
||||
|
||||
- frontend sends UTC timestamps to backend
|
||||
- backend returns ISO 8601 UTC timestamps for source-of-truth fields
|
||||
- frontend converts those timestamps to local time for display
|
||||
|
||||
Source-of-truth timestamp fields include:
|
||||
|
||||
- `startsAt`
|
||||
- `endsAt`
|
||||
- `startTime`
|
||||
- `endTime`
|
||||
- `clockInAt`
|
||||
- `clockOutAt`
|
||||
- `createdAt`
|
||||
- `updatedAt`
|
||||
|
||||
Helper fields like `date` are UTC-derived helpers and should not replace the raw timestamp fields.
|
||||
|
||||
## 4) Attendance policy and monitoring
|
||||
|
||||
V2 now supports an explicit attendance proof policy:
|
||||
|
||||
@@ -23,6 +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`.
|
||||
- Treat API timestamp fields as UTC and convert them to local time in the app.
|
||||
|
||||
## 2) What is implemented now
|
||||
|
||||
@@ -145,6 +146,8 @@ Rules:
|
||||
- worker rating happens through `POST /client/coverage/reviews`
|
||||
- the same endpoint also supports `markAsFavorite` to add or remove a worker from business favorites
|
||||
- blocking a worker is done through the same endpoint using `markAsBlocked`
|
||||
- coverage shift items now include `locationName` and `locationAddress`
|
||||
- assigned worker items now include `hasReview`
|
||||
- dispatch ranking order is:
|
||||
1. `CORE`
|
||||
2. `CERTIFIED_LOCATION`
|
||||
@@ -216,6 +219,7 @@ Important:
|
||||
|
||||
- `GET /staff/session`
|
||||
- `GET /staff/dashboard`
|
||||
- `GET /staff/profile/stats`
|
||||
- `GET /staff/profile-completion`
|
||||
|
||||
### Availability
|
||||
@@ -250,6 +254,7 @@ Staff shift detail and list rules:
|
||||
- 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`
|
||||
- `GET /staff/profile/stats` returns `totalShifts`, `averageRating`, `ratingCount`, `onTimeRate`, `noShowCount`, `cancellationCount`, `reliabilityScore`
|
||||
|
||||
### Clock in / clock out
|
||||
|
||||
@@ -266,6 +271,7 @@ Clock-in payload rules:
|
||||
- send `overrideReason` only when geo override is allowed
|
||||
- send `proofNonce` and `proofTimestamp` on attendance writes
|
||||
- send `attestationProvider` and `attestationToken` only if the device has them
|
||||
- if backend returns `ALREADY_CLOCKED_IN`, treat it as a valid retry-state signal and refresh attendance/session state
|
||||
|
||||
Clock-in read rules:
|
||||
|
||||
|
||||
@@ -104,6 +104,11 @@ Coverage-review request payload may also send:
|
||||
|
||||
If `markAsFavorite` is `true`, backend adds that worker to the business favorites list. If `markAsFavorite` is `false`, backend removes them from that list. 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`.
|
||||
|
||||
`GET /client/coverage` response notes:
|
||||
|
||||
- each shift item includes `locationName` and `locationAddress`
|
||||
- each assigned worker item includes `hasReview`
|
||||
|
||||
Swap-review routes:
|
||||
|
||||
- `GET /client/coverage/swap-requests?status=OPEN`
|
||||
@@ -163,6 +168,7 @@ The manager is created as an invited business membership. If `hubId` is present,
|
||||
|
||||
- `GET /staff/session`
|
||||
- `GET /staff/dashboard`
|
||||
- `GET /staff/profile/stats`
|
||||
- `GET /staff/profile-completion`
|
||||
- `GET /staff/availability`
|
||||
- `GET /staff/clock-in/shifts/today`
|
||||
@@ -218,6 +224,21 @@ Example `GET /staff/clock-in/shifts/today` item:
|
||||
}
|
||||
```
|
||||
|
||||
Example `GET /staff/profile/stats` response:
|
||||
|
||||
```json
|
||||
{
|
||||
"staffId": "uuid",
|
||||
"totalShifts": 12,
|
||||
"averageRating": 4.8,
|
||||
"ratingCount": 7,
|
||||
"onTimeRate": 91.7,
|
||||
"noShowCount": 1,
|
||||
"cancellationCount": 0,
|
||||
"reliabilityScore": 92.3
|
||||
}
|
||||
```
|
||||
|
||||
### Staff writes
|
||||
|
||||
- `POST /staff/profile/setup`
|
||||
@@ -296,12 +317,14 @@ These are exposed as direct unified aliases even though they are backed by `core
|
||||
- `NFC_REQUIRED`
|
||||
- `GEO_REQUIRED`
|
||||
- `EITHER`
|
||||
- all source-of-truth timestamps are UTC ISO 8601 values. Frontend should convert them to local time for display.
|
||||
- For `POST /staff/clock-in` and `POST /staff/clock-out`:
|
||||
- send `nfcTagId` when clocking with NFC
|
||||
- send `latitude`, `longitude`, and `accuracyMeters` when clocking with geolocation
|
||||
- send `proofNonce` and `proofTimestamp` for attendance-proof logging; these are most important on NFC paths
|
||||
- send `attestationProvider` and `attestationToken` only when the device has a real attestation result to forward
|
||||
- send `overrideReason` only when the worker is bypassing a geofence failure and the shift/hub allows overrides
|
||||
- if the worker is already clocked in, backend returns `409` with code `ALREADY_CLOCKED_IN`
|
||||
- `POST /staff/location-streams` is for the background tracking loop after a worker is already clocked in.
|
||||
- `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.
|
||||
|
||||
Reference in New Issue
Block a user