8.8 KiB
Mobile Frontend Implementation Spec
This is the shortest path for frontend to implement the v2 mobile clients against the unified backend.
Base URL:
https://krow-api-v2-933560802882.us-central1.run.app
Use this doc together with:
1) Global rules
- Use unified routes only.
- Send
Authorization: Bearer <firebase-id-token>on protected routes. - Send
Idempotency-Keyon all write routes. - Do not call
/query/*,/commands/*, or/core/*directly from frontend.
2) Core model frontend should assume
orderis the client-facing request for staffing.shiftis the concrete scheduled unit of work under an order.shiftRoleis the role slot inside a shift that staff apply to.assignmentis the worker-to-shift record once a worker is attached.
Important consequences:
GET /staff/shifts/openreturns open shift-role opportunities.POST /staff/shifts/:shiftId/applymust send theroleIdfrom that response.GET /client/orders/viewis the timeline/read model for the client app.POST /client/orders/:orderId/editandPOST /client/orders/:orderId/cancelonly affect future shifts.
3) Auth implementation
Client app
- sign in with
POST /auth/client/sign-in - sign up with
POST /auth/client/sign-up - hydrate session with
GET /auth/session - sign out with
POST /auth/client/sign-out
Staff app
- start phone auth with
POST /auth/staff/phone/start - complete phone auth with
POST /auth/staff/phone/verify - hydrate session with
GET /auth/session - sign out with
POST /auth/staff/sign-out
Token refresh:
- keep using Firebase client SDK refresh behavior
- there is no backend
/auth/refreshroute
4) Client app screen mapping
Home / dashboard
GET /client/sessionGET /client/dashboardGET /client/reorders
Billing / payments
GET /client/billing/accountsGET /client/billing/invoices/pendingGET /client/billing/invoices/historyGET /client/billing/current-billGET /client/billing/savingsGET /client/billing/spend-breakdownPOST /client/billing/invoices/:invoiceId/approvePOST /client/billing/invoices/:invoiceId/dispute
Coverage
GET /client/coverage?date=YYYY-MM-DDGET /client/coverage/stats?date=YYYY-MM-DDGET /client/coverage/core-team?date=YYYY-MM-DDGET /client/coverage/incidents?startDate=YYYY-MM-DD&endDate=YYYY-MM-DDGET /client/coverage/blocked-staffGET /client/coverage/swap-requests?status=OPENGET /client/coverage/dispatch-teamsGET /client/coverage/dispatch-candidates?shiftId=uuid&roleId=uuidPOST /client/coverage/reviewsPOST /client/coverage/late-workers/:assignmentId/cancelPOST /client/coverage/swap-requests/:swapRequestId/resolvePOST /client/coverage/swap-requests/:swapRequestId/cancelPOST /client/coverage/dispatch-teams/membershipsDELETE /client/coverage/dispatch-teams/memberships/:membershipId
Use POST /client/coverage/reviews when the business is rating a worker after coverage review.
Payload may include:
{
"assignmentId": "uuid",
"rating": 4,
"comment": "Strong performance on the shift",
"markAsBlocked": false
}
If markAsBlocked is true, backend blocks that worker for that business and rejects future apply or assign attempts until a later review sets markAsBlocked: false.
Swap-management rule:
- use
GET /client/coverage/swap-requestsas the client review feed - use
GET /client/coverage/dispatch-candidatesfor the ranked replacement list - use
POST /client/coverage/swap-requests/:swapRequestId/resolvewhen ops selects a replacement - use
POST /client/coverage/swap-requests/:swapRequestId/cancelwhen ops wants to close the swap request without replacement
Dispatch-priority rule:
CORECERTIFIED_LOCATIONMARKETPLACE
Orders
GET /client/orders/viewGET /client/orders/:orderId/reorder-previewPOST /client/orders/one-timePOST /client/orders/recurringPOST /client/orders/permanentPOST /client/orders/:orderId/editPOST /client/orders/:orderId/cancel
Rapid-order flow:
- use
POST /rapid-orders/processfor the single-call transcribe-and-parse flow
Hubs and managers
GET /client/hubsGET /client/cost-centersGET /client/hubs/:hubId/managersGET /client/team-membersPOST /client/shift-managersPOST /client/hubsPUT /client/hubs/:hubIdDELETE /client/hubs/:hubIdPOST /client/hubs/:hubId/assign-nfcPOST /client/hubs/:hubId/managers
POST /client/shift-managers is the fastest path to create an invited manager identity for a business. If hubId is provided, backend also links that manager to the hub.
Reports
GET /client/reports/summary?date=YYYY-MM-DDGET /client/reports/daily-ops?date=YYYY-MM-DDGET /client/reports/spend?date=YYYY-MM-DDGET /client/reports/coverage?date=YYYY-MM-DDGET /client/reports/forecast?date=YYYY-MM-DDGET /client/reports/performance?date=YYYY-MM-DDGET /client/reports/no-show?date=YYYY-MM-DD
5) Staff app screen mapping
Home / dashboard
GET /staff/sessionGET /staff/dashboardGET /staff/profile-completion
Availability
GET /staff/availabilityPUT /staff/availabilityPOST /staff/availability/quick-set
Find shifts
GET /staff/shifts/openPOST /staff/shifts/:shiftId/apply
Rule:
- send the
roleIdfrom the open-shifts response - this is the concrete
shift_roles.id
My shifts
GET /staff/shifts/pendingGET /staff/shifts/assignedGET /staff/shifts/cancelledGET /staff/shifts/completedGET /staff/shifts/:shiftIdPOST /staff/shifts/:shiftId/acceptPOST /staff/shifts/:shiftId/declinePOST /staff/shifts/:shiftId/request-swapPOST /staff/shifts/:shiftId/submit-for-approval
Current swap behavior:
- backend records the swap request
- assignment moves to
SWAP_REQUESTED - shift becomes visible in the replacement pool
- client/ops can review and resolve swap requests through the coverage endpoints
- if the swap request expires without coverage, backend auto-cancels it and alerts both the manager path and the original worker
Clock in / clock out
GET /staff/clock-in/shifts/todayGET /staff/clock-in/statusPOST /staff/clock-inPOST /staff/clock-outPOST /staff/location-streams
Frontend should respect:
clockInModeallowClockInOverridelatitudelongitudegeofenceRadiusMetersnfcTagId
Clock-in proof rules:
- use
nfcTagIdfor NFC clocking - use
latitude,longitude, andaccuracyMetersfor geolocation clocking - send
overrideReasononly when a geofence override is allowed - send
proofNonceandproofTimestampon attendance writes
Payments
GET /staff/payments/summaryGET /staff/payments/historyGET /staff/payments/chart
Profile
GET /staff/profile/sectionsGET /staff/profile/personal-infoGET /staff/profile/industriesGET /staff/profile/skillsGET /staff/profile/documentsGET /staff/profile/attireGET /staff/profile/tax-formsGET /staff/profile/emergency-contactsGET /staff/profile/certificatesGET /staff/profile/bank-accountsGET /staff/profile/benefitsGET /staff/profile/benefits/historyGET /staff/profile/time-cardGET /staff/profile/privacyPUT /staff/profile/personal-infoPUT /staff/profile/experiencePUT /staff/profile/locationsPOST /staff/profile/emergency-contactsPUT /staff/profile/emergency-contacts/:contactIdPUT /staff/profile/tax-forms/:formTypePOST /staff/profile/tax-forms/:formType/submitPOST /staff/profile/bank-accountsPUT /staff/profile/privacy
Document model rule:
GET /staff/profile/documentsreturns only documentsGET /staff/profile/attirereturns attire itemsGET /staff/profile/tax-formsreturns tax-form rowsGET /staff/profile/certificatesreturns certificates
FAQ
GET /staff/faqsGET /staff/faqs/search?q=...
6) Upload implementation
For documents, attire, and certificates:
POST /upload-filePOST /create-signed-url- upload file bytes to storage with the signed URL
POST /verifications- finalize with:
PUT /staff/profile/documents/:documentId/uploadPUT /staff/profile/attire/:documentId/uploadPOST /staff/profile/certificates
Use the verification-linked file as the source of truth.
7) What frontend should not assume
- do not assume order edit mutates past shifts
- do not assume swap resolution is complete beyond the request step
- do not assume raw
/query/*or/commands/*routes are stable for app integration - do not assume blocked workers can still apply to future shifts for that business
8) Demo reset
To reset dev demo data:
source ~/.nvm/nvm.sh
nvm use 23.5.0
cd backend/command-api
npm run seed:v2-demo