docs(api): consolidate v2 frontend backend guides

This commit is contained in:
zouantchaw
2026-03-12 14:09:05 +01:00
parent fe43ff23cf
commit b61babe3c6
9 changed files with 740 additions and 910 deletions

View File

@@ -0,0 +1,120 @@
# V2 Backend API Guide
This is the frontend-facing source of truth for the v2 backend.
If you are building against the new backend, start here.
## 1) Which service to use
| Use case | Service |
| --- | --- |
| File upload, signed URLs, model calls, rapid order helpers, verification flows | `core-api-v2` |
| Business writes and workflow actions | `command-api-v2` |
| Screen reads for the implemented v2 views | `query-api-v2` |
## 2) Live dev base URLs
- Core API: `https://krow-core-api-v2-e3g6witsvq-uc.a.run.app`
- Command API: `https://krow-command-api-v2-e3g6witsvq-uc.a.run.app`
- Query API: `https://krow-query-api-v2-e3g6witsvq-uc.a.run.app`
## 3) Auth and headers
All protected routes require:
```http
Authorization: Bearer <firebase-id-token>
```
All command routes also require:
```http
Idempotency-Key: <unique-per-user-action>
```
All services return the same error envelope:
```json
{
"code": "STRING_CODE",
"message": "Human readable message",
"details": {},
"requestId": "uuid"
}
```
## 4) What frontend can use now
### Ready now
- `core-api-v2`
- upload file
- create signed URL
- invoke model
- rapid order transcribe
- rapid order parse
- create verification
- get verification
- review verification
- retry verification
- `command-api-v2`
- create order
- update order
- cancel order
- assign staff to shift
- accept shift
- change shift status
- clock in
- clock out
- favorite and unfavorite staff
- create staff review
- `query-api-v2`
- order list
- order detail
- favorite staff list
- staff review summary
- assignment attendance detail
### Do not move yet
- reports
- payments and finance screens
- undocumented dashboard reads
- undocumented scheduling reads and writes
- any flow that assumes verification history is durable in SQL
## 5) Important caveat
`core-api-v2` is usable now, but verification job state is not yet persisted to `krow-sql-v2`.
What is durable today:
- uploaded files in Google Cloud Storage
- generated signed URLs
- model invocation itself
What is not yet durable:
- verification job history
- verification review history
- verification event history
That means frontend can integrate with verification routes now, but should not treat them as mission-critical durable state yet.
## 6) Recommended frontend environment variables
```env
CORE_API_V2_BASE_URL=https://krow-core-api-v2-e3g6witsvq-uc.a.run.app
COMMAND_API_V2_BASE_URL=https://krow-command-api-v2-e3g6witsvq-uc.a.run.app
QUERY_API_V2_BASE_URL=https://krow-query-api-v2-e3g6witsvq-uc.a.run.app
```
## 7) Service docs
- [Core API](./core-api.md)
- [Command API](./command-api.md)
- [Query API](./query-api.md)
## 8) Frontend integration rule
Do not point screens directly at database access just because a route does not exist yet.
If a screen is missing from the docs, the next step is to define the route contract and add it to `query-api-v2` or `command-api-v2`.

View File

@@ -0,0 +1,229 @@
# V2 Command API
Use `command-api-v2` for write actions that change business state.
Base URL:
```text
https://krow-command-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) Required headers
```http
Authorization: Bearer <firebase-id-token>
Idempotency-Key: <unique-per-user-action>
Content-Type: application/json
```
## 2) Route summary
| Method | Route | Purpose |
| --- | --- | --- |
| `POST` | `/commands/orders/create` | Create order with shifts and roles |
| `POST` | `/commands/orders/:orderId/update` | Update mutable order fields |
| `POST` | `/commands/orders/:orderId/cancel` | Cancel order and related eligible records |
| `POST` | `/commands/shifts/:shiftId/assign-staff` | Assign workforce to shift role |
| `POST` | `/commands/shifts/:shiftId/accept` | Accept an assigned shift |
| `POST` | `/commands/shifts/:shiftId/change-status` | Move shift to a new valid status |
| `POST` | `/commands/attendance/clock-in` | Record clock-in event |
| `POST` | `/commands/attendance/clock-out` | Record clock-out event |
| `POST` | `/commands/businesses/:businessId/favorite-staff` | Add favorite staff |
| `DELETE` | `/commands/businesses/:businessId/favorite-staff/:staffId` | Remove favorite staff |
| `POST` | `/commands/assignments/:assignmentId/reviews` | Create or update staff review |
| `GET` | `/readyz` | Ready check |
## 3) Order create
```text
POST /commands/orders/create
```
Request body:
```json
{
"tenantId": "uuid",
"businessId": "uuid",
"vendorId": "uuid",
"orderNumber": "ORD-1001",
"title": "Cafe Event Staffing",
"serviceType": "EVENT",
"shifts": [
{
"shiftCode": "SHIFT-1",
"title": "Morning Shift",
"startsAt": "2026-03-12T08:00:00.000Z",
"endsAt": "2026-03-12T16:00:00.000Z",
"requiredWorkers": 2,
"roles": [
{
"roleCode": "BARISTA",
"roleName": "Barista",
"workersNeeded": 2
}
]
}
]
}
```
## 4) Order update
```text
POST /commands/orders/:orderId/update
```
Required body fields:
- `tenantId`
- at least one mutable field such as `title`, `description`, `vendorId`, `serviceType`, `startsAt`, `endsAt`, `locationName`, `locationAddress`, `latitude`, `longitude`, `notes`, `metadata`
You can also send `null` to clear nullable fields.
## 5) Order cancel
```text
POST /commands/orders/:orderId/cancel
```
Example request:
```json
{
"tenantId": "uuid",
"reason": "Client cancelled"
}
```
## 6) Shift assign staff
```text
POST /commands/shifts/:shiftId/assign-staff
```
Example request:
```json
{
"tenantId": "uuid",
"shiftRoleId": "uuid",
"workforceId": "uuid",
"applicationId": "uuid"
}
```
## 7) Shift accept
```text
POST /commands/shifts/:shiftId/accept
```
Example request:
```json
{
"shiftRoleId": "uuid",
"workforceId": "uuid"
}
```
## 8) Shift status change
```text
POST /commands/shifts/:shiftId/change-status
```
Example request:
```json
{
"tenantId": "uuid",
"status": "PENDING_CONFIRMATION",
"reason": "Waiting for worker confirmation"
}
```
Allowed status values:
- `DRAFT`
- `OPEN`
- `PENDING_CONFIRMATION`
- `ASSIGNED`
- `ACTIVE`
- `COMPLETED`
- `CANCELLED`
## 9) Attendance
### Clock in
```text
POST /commands/attendance/clock-in
```
### Clock out
```text
POST /commands/attendance/clock-out
```
Example request body for both:
```json
{
"assignmentId": "uuid",
"sourceType": "NFC",
"sourceReference": "iphone-15-pro-max",
"nfcTagUid": "NFC-DEMO-ANA-001",
"deviceId": "device-123",
"latitude": 37.422,
"longitude": -122.084,
"accuracyMeters": 8,
"capturedAt": "2026-03-11T17:15:00.000Z"
}
```
## 10) Favorite staff
### Add favorite
```text
POST /commands/businesses/:businessId/favorite-staff
```
### Remove favorite
```text
DELETE /commands/businesses/:businessId/favorite-staff/:staffId
```
Request body when adding:
```json
{
"tenantId": "uuid",
"staffId": "uuid"
}
```
## 11) Staff review
```text
POST /commands/assignments/:assignmentId/reviews
```
Example request:
```json
{
"tenantId": "uuid",
"businessId": "uuid",
"staffId": "uuid",
"rating": 5,
"reviewText": "Strong shift performance",
"tags": ["punctual", "professional"]
}
```
## 12) Live status
These routes were live-tested on `2026-03-11` against the deployed dev service and `krow-sql-v2`.

View File

@@ -0,0 +1,203 @@
# V2 Core API
Use `core-api-v2` for backend capabilities that should not live in the client.
Base URL:
```text
https://krow-core-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) Route summary
| Method | Route | Purpose |
| --- | --- | --- |
| `POST` | `/core/upload-file` | Upload file to Google Cloud Storage |
| `POST` | `/core/create-signed-url` | Generate a read URL for an uploaded file |
| `POST` | `/core/invoke-llm` | Run a model call |
| `POST` | `/core/rapid-orders/transcribe` | Turn uploaded audio into text |
| `POST` | `/core/rapid-orders/parse` | Turn order text into structured order data |
| `POST` | `/core/verifications` | Create a verification job |
| `GET` | `/core/verifications/:verificationId` | Fetch verification status |
| `POST` | `/core/verifications/:verificationId/review` | Apply manual review decision |
| `POST` | `/core/verifications/:verificationId/retry` | Retry a verification job |
| `GET` | `/health` | Health check |
## 2) Upload file
Route:
```text
POST /core/upload-file
```
Send multipart form data:
- `file`: required
- `category`: optional string
- `visibility`: `public` or `private`
Example response:
```json
{
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/file.pdf",
"contentType": "application/pdf",
"size": 12345,
"bucket": "krow-workforce-dev-private",
"path": "uploads/<uid>/file.pdf",
"requestId": "uuid"
}
```
## 3) Create signed URL
Route:
```text
POST /core/create-signed-url
```
Example request:
```json
{
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/file.pdf",
"expiresInSeconds": 300
}
```
Example response:
```json
{
"signedUrl": "https://...",
"expiresAt": "2026-03-11T18:30:00.000Z",
"requestId": "uuid"
}
```
## 4) Invoke model
Route:
```text
POST /core/invoke-llm
```
Example request:
```json
{
"prompt": "Summarize this staffing request",
"fileUrls": ["gs://krow-workforce-dev-private/uploads/<uid>/notes.pdf"],
"responseJsonSchema": {
"type": "object",
"properties": {
"summary": { "type": "string" }
},
"required": ["summary"]
}
}
```
Example response:
```json
{
"result": {
"summary": "..."
},
"model": "vertex model name",
"latencyMs": 1200,
"requestId": "uuid"
}
```
## 5) Rapid order helpers
### Transcribe
```text
POST /core/rapid-orders/transcribe
```
Example request:
```json
{
"audioFileUri": "gs://krow-workforce-dev-private/uploads/<uid>/note.m4a",
"locale": "en-US",
"promptHints": ["staffing order", "shift details"]
}
```
### Parse
```text
POST /core/rapid-orders/parse
```
Example request:
```json
{
"text": "Need two baristas tomorrow from 8am to 4pm at Google Mountain View Cafe",
"locale": "en-US",
"timezone": "America/Los_Angeles"
}
```
## 6) Verification routes
### Create verification
```text
POST /core/verifications
```
Example request:
```json
{
"type": "attire",
"subjectType": "staff",
"subjectId": "staff-uuid",
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/attire.jpg",
"rules": {
"label": "black shoes"
}
}
```
### Get verification
```text
GET /core/verifications/:verificationId
```
### Manual review
```text
POST /core/verifications/:verificationId/review
```
Example request:
```json
{
"decision": "APPROVED",
"note": "Manual review passed"
}
```
### Retry
```text
POST /core/verifications/:verificationId/retry
```
## 7) Caveat
Verification state is not yet stored in `krow-sql-v2`.
Use these routes now for frontend integration, but do not depend on verification history being durable until the persistence work lands.

View File

@@ -0,0 +1,151 @@
# V2 Query API
Use `query-api-v2` for implemented read screens in the v2 clients.
Base URL:
```text
https://krow-query-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) Required header
```http
Authorization: Bearer <firebase-id-token>
```
## 2) Route summary
| Method | Route | Purpose |
| --- | --- | --- |
| `GET` | `/query/tenants/:tenantId/orders` | Order list |
| `GET` | `/query/tenants/:tenantId/orders/:orderId` | Order detail with shifts and roles |
| `GET` | `/query/tenants/:tenantId/businesses/:businessId/favorite-staff` | Favorite staff list |
| `GET` | `/query/tenants/:tenantId/staff/:staffId/review-summary` | Staff rating summary and recent reviews |
| `GET` | `/query/tenants/:tenantId/assignments/:assignmentId/attendance` | Attendance session and event detail |
| `GET` | `/readyz` | Ready check |
## 3) Order list
```text
GET /query/tenants/:tenantId/orders
```
Optional query params:
- `businessId`
- `status`
- `limit`
- `offset`
Response shape:
```json
{
"items": [
{
"id": "uuid",
"orderNumber": "ORD-1001",
"title": "Cafe Event Staffing",
"status": "OPEN",
"serviceType": "EVENT",
"startsAt": "2026-03-12T08:00:00.000Z",
"endsAt": "2026-03-12T16:00:00.000Z",
"businessId": "uuid",
"businessName": "Google Mountain View Cafes",
"vendorId": "uuid",
"vendorName": "Legendary Staffing Pool A",
"shiftCount": 1,
"requiredWorkers": 2,
"assignedWorkers": 1
}
],
"requestId": "uuid"
}
```
## 4) Order detail
```text
GET /query/tenants/:tenantId/orders/:orderId
```
Response shape:
```json
{
"id": "uuid",
"orderNumber": "ORD-1001",
"title": "Cafe Event Staffing",
"status": "OPEN",
"businessId": "uuid",
"businessName": "Google Mountain View Cafes",
"vendorId": "uuid",
"vendorName": "Legendary Staffing Pool A",
"shifts": [
{
"id": "uuid",
"shiftCode": "SHIFT-1",
"title": "Morning Shift",
"status": "OPEN",
"startsAt": "2026-03-12T08:00:00.000Z",
"endsAt": "2026-03-12T16:00:00.000Z",
"requiredWorkers": 2,
"assignedWorkers": 1,
"roles": [
{
"id": "uuid",
"roleCode": "BARISTA",
"roleName": "Barista",
"workersNeeded": 2,
"assignedCount": 1
}
]
}
],
"requestId": "uuid"
}
```
## 5) Favorite staff list
```text
GET /query/tenants/:tenantId/businesses/:businessId/favorite-staff
```
Optional query params:
- `limit`
- `offset`
## 6) Staff review summary
```text
GET /query/tenants/:tenantId/staff/:staffId/review-summary
```
Optional query params:
- `limit`
Response includes:
- staff identity
- average rating
- rating count
- recent reviews
## 7) Assignment attendance detail
```text
GET /query/tenants/:tenantId/assignments/:assignmentId/attendance
```
Response includes:
- assignment status
- shift info
- attendance session
- ordered attendance events
- NFC and geofence validation fields
## 8) Current boundary
Frontend should use only these documented reads on `query-api-v2`.
Do not point dashboard, reports, finance, or other undocumented list/detail views here yet.