feat(api): complete unified v2 mobile surface

This commit is contained in:
zouantchaw
2026-03-13 17:02:24 +01:00
parent 817a39e305
commit b455455a49
39 changed files with 7726 additions and 506 deletions

View File

@@ -1,50 +1,168 @@
# Unified API V2
This service exists so frontend can use one base URL without forcing backend into one codebase.
Frontend should use this service as the single base URL:
## Base idea
- `https://krow-api-v2-933560802882.us-central1.run.app`
Frontend talks to one service:
The gateway keeps backend services separate internally, but frontend should treat it as one API.
- `krow-api-v2`
## 1) Auth routes
That gateway does two things:
1. exposes auth/session endpoints
2. forwards requests to the right internal v2 service
## Route groups
### Auth
### Client auth
- `POST /auth/client/sign-in`
- `POST /auth/client/sign-up`
- `POST /auth/sign-out`
- `POST /auth/client/sign-out`
### Staff auth
- `POST /auth/staff/phone/start`
- `POST /auth/staff/phone/verify`
- `POST /auth/staff/sign-out`
### Shared auth
- `GET /auth/session`
- `POST /auth/sign-out`
### Proxy passthrough
## 2) Client routes
- `/core/*` -> `core-api-v2`
- `/commands/*` -> `command-api-v2`
- `/query/*` -> `query-api-v2`
### Client reads
### Mobile read models
- `GET /client/session`
- `GET /client/dashboard`
- `GET /client/reorders`
- `GET /client/billing/accounts`
- `GET /client/billing/invoices/pending`
- `GET /client/billing/invoices/history`
- `GET /client/billing/current-bill`
- `GET /client/billing/savings`
- `GET /client/billing/spend-breakdown`
- `GET /client/coverage`
- `GET /client/coverage/stats`
- `GET /client/coverage/core-team`
- `GET /client/hubs`
- `GET /client/cost-centers`
- `GET /client/vendors`
- `GET /client/vendors/:vendorId/roles`
- `GET /client/hubs/:hubId/managers`
- `GET /client/team-members`
- `GET /client/orders/view`
- `GET /client/orders/:orderId/reorder-preview`
- `GET /client/reports/summary`
- `GET /client/reports/daily-ops`
- `GET /client/reports/spend`
- `GET /client/reports/coverage`
- `GET /client/reports/forecast`
- `GET /client/reports/performance`
- `GET /client/reports/no-show`
These are served by `query-api-v2` but frontend should still call them through the unified host:
### Client writes
- `/query/client/*`
- `/query/staff/*`
- `POST /client/orders/one-time`
- `POST /client/orders/recurring`
- `POST /client/orders/permanent`
- `POST /client/orders/:orderId/edit`
- `POST /client/orders/:orderId/cancel`
- `POST /client/hubs`
- `PUT /client/hubs/:hubId`
- `DELETE /client/hubs/:hubId`
- `POST /client/hubs/:hubId/assign-nfc`
- `POST /client/hubs/:hubId/managers`
- `POST /client/billing/invoices/:invoiceId/approve`
- `POST /client/billing/invoices/:invoiceId/dispute`
- `POST /client/coverage/reviews`
- `POST /client/coverage/late-workers/:assignmentId/cancel`
## Why this shape
## 3) Staff routes
- frontend gets one base URL
- backend keeps separate read, write, and service helpers
- we can scale or refactor internals later without breaking frontend paths
### Staff reads
## Current auth note
- `GET /staff/session`
- `GET /staff/dashboard`
- `GET /staff/profile-completion`
- `GET /staff/availability`
- `GET /staff/clock-in/shifts/today`
- `GET /staff/clock-in/status`
- `GET /staff/payments/summary`
- `GET /staff/payments/history`
- `GET /staff/payments/chart`
- `GET /staff/shifts/assigned`
- `GET /staff/shifts/open`
- `GET /staff/shifts/pending`
- `GET /staff/shifts/cancelled`
- `GET /staff/shifts/completed`
- `GET /staff/shifts/:shiftId`
- `GET /staff/profile/sections`
- `GET /staff/profile/personal-info`
- `GET /staff/profile/industries`
- `GET /staff/profile/skills`
- `GET /staff/profile/documents`
- `GET /staff/profile/attire`
- `GET /staff/profile/tax-forms`
- `GET /staff/profile/emergency-contacts`
- `GET /staff/profile/certificates`
- `GET /staff/profile/bank-accounts`
- `GET /staff/profile/benefits`
- `GET /staff/profile/time-card`
- `GET /staff/profile/privacy`
- `GET /staff/faqs`
- `GET /staff/faqs/search`
Client email/password auth is wrapped here.
### Staff writes
Staff phone OTP is not wrapped here yet. That still needs its own proper provider-backed implementation rather than a fake backend OTP flow.
- `POST /staff/profile/setup`
- `POST /staff/clock-in`
- `POST /staff/clock-out`
- `PUT /staff/availability`
- `POST /staff/availability/quick-set`
- `POST /staff/shifts/:shiftId/apply`
- `POST /staff/shifts/:shiftId/accept`
- `POST /staff/shifts/:shiftId/decline`
- `POST /staff/shifts/:shiftId/request-swap`
- `PUT /staff/profile/personal-info`
- `PUT /staff/profile/experience`
- `PUT /staff/profile/locations`
- `POST /staff/profile/emergency-contacts`
- `PUT /staff/profile/emergency-contacts/:contactId`
- `PUT /staff/profile/tax-forms/:formType`
- `POST /staff/profile/tax-forms/:formType/submit`
- `POST /staff/profile/bank-accounts`
- `PUT /staff/profile/privacy`
## 4) Upload and verification routes
These are exposed as direct unified aliases even though they are backed by `core-api-v2`.
### Generic core aliases
- `POST /upload-file`
- `POST /create-signed-url`
- `POST /invoke-llm`
- `POST /rapid-orders/transcribe`
- `POST /rapid-orders/parse`
- `POST /verifications`
- `GET /verifications/:verificationId`
- `POST /verifications/:verificationId/review`
- `POST /verifications/:verificationId/retry`
### Staff upload aliases
- `POST /staff/profile/photo`
- `POST /staff/profile/documents/:documentId/upload`
- `POST /staff/profile/attire/:documentId/upload`
- `POST /staff/profile/certificates`
- `DELETE /staff/profile/certificates/:certificateId`
## 5) Notes that matter for frontend
- `roleId` on `POST /staff/shifts/:shiftId/apply` is the concrete `shift_roles.id` for that shift, not the catalog role definition id.
- `accountType` on `POST /staff/profile/bank-accounts` accepts either lowercase or uppercase and is normalized by the backend.
- File upload routes return a storage path plus a signed URL. Frontend uploads the file directly to storage using that URL.
- Verification routes are durable in the v2 backend and were validated live through document, attire, and certificate upload flows.
## 6) Why this shape
- frontend gets one host
- backend keeps reads, writes, and service helpers separated
- routing can change internally later without forcing frontend rewrites