Files
Krow-workspace/docs/BACKEND/API_GUIDES/V2

V2 Backend API Guide

This is the frontend-facing source of truth for the v2 backend.

1) Use one base URL

Frontend should call one public gateway:

API_V2_BASE_URL=https://krow-api-v2-e3g6witsvq-uc.a.run.app

Frontend should not call the internal core, command, or query Cloud Run services directly.

2) Current status

The unified v2 gateway is ready for frontend integration in dev.

What was validated live against the deployed stack:

  • client sign-in
  • staff auth bootstrap
  • client dashboard, billing, coverage, hubs, vendors, managers, team members, orders, and reports
  • client coverage incident feed for geofence and override review
  • client blocked-staff review and invited shift-manager creation
  • client hub, order, coverage review, device token, and late-worker cancellation flows
  • client swap-request review, dispatch-team management, and dispatch-candidate ranking
  • client invoice approve and dispute
  • staff dashboard, availability, payments, shifts, profile sections, documents, certificates, attire, bank accounts, benefits, and time card
  • staff benefit history read model
  • staff availability, profile, tax form, bank account, shift apply, shift accept, push token registration, clock-in, clock-out, location stream upload, swap request, and completed-shift submission
  • direct file upload helpers and verification job creation through the unified host
  • client and staff sign-out

The live validation command is:

export FIREBASE_WEB_API_KEY="$(gcloud secrets versions access latest --secret=firebase-web-api-key --project=krow-workforce-dev)"
source ~/.nvm/nvm.sh
nvm use 23.5.0
node backend/unified-api/scripts/live-smoke-v2-unified.mjs

The demo tenant can be reset with:

source ~/.nvm/nvm.sh
nvm use 23.5.0
cd backend/command-api
npm run seed:v2-demo

3) Auth and headers

Protected routes require:

Authorization: Bearer <firebase-id-token>

Write routes also require:

Idempotency-Key: <unique-per-user-action>

For now:

  • backend wraps sign-in and sign-out
  • frontend can keep using Firebase token refresh on the client
  • backend is the only thing frontend should call for session-oriented API flows

All routes return the same error envelope:

{
  "code": "STRING_CODE",
  "message": "Human readable message",
  "details": {},
  "requestId": "uuid"
}

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
  • clockInAt
  • clockOutAt
  • createdAt
  • updatedAt

Helper fields like date, startTime, and endTime are display helpers and should not replace the raw timestamp fields.

4) Attendance policy and monitoring

V2 now supports an explicit attendance proof policy:

  • NFC_REQUIRED
  • GEO_REQUIRED
  • EITHER

The effective policy is resolved as:

  1. shift override if present
  2. hub default if present
  3. fallback to EITHER

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:

  • outside-geofence clock-ins can be accepted only when override is enabled and a written reason is provided
  • NFC mismatches are rejected and are not overrideable
  • attendance proof logs are durable in SQL and raw object storage
  • device push tokens are durable in SQL and can be registered separately for client and staff apps
  • background location streams are stored as raw batch payloads in the private v2 bucket and summarized in SQL for query speed
  • incident review lives on GET /client/coverage/incidents
  • confirmed late-worker recovery is exposed on POST /client/coverage/late-workers/:assignmentId/cancel
  • client swap review is exposed on:
    • GET /client/coverage/swap-requests
    • POST /client/coverage/swap-requests/:swapRequestId/resolve
    • POST /client/coverage/swap-requests/:swapRequestId/cancel
  • dispatch-team management is exposed on:
    • GET /client/coverage/dispatch-teams
    • GET /client/coverage/dispatch-candidates
    • POST /client/coverage/dispatch-teams/memberships
    • DELETE /client/coverage/dispatch-teams/memberships/:membershipId
  • dispatch ranking order is:
    1. CORE
    2. CERTIFIED_LOCATION
    3. MARKETPLACE
  • expired swap requests are auto-cancelled by the notification worker and emit manager plus staff alerts
  • queued alerts are written to notification_outbox, dispatched by the private Cloud Run worker service krow-notification-worker-v2, and recorded in notification_deliveries

5) Route model

Frontend sees one base URL and one route shape:

  • /auth/*
  • /client/*
  • /staff/*
  • direct upload aliases like /upload-file and /staff/profile/*

Internally, the gateway still forwards to:

Frontend use case Internal service
auth/session wrapper krow-api-v2
uploads, signed URLs, model calls, verification workflows core-api-v2
writes and workflow actions command-api-v2
reads and mobile read models query-api-v2

6) Frontend integration rule

Use the unified routes first.

Do not build new frontend work on:

  • /query/tenants/*
  • /commands/*
  • /core/*

Those routes still exist for backend/internal compatibility, but mobile/frontend migration should target the unified surface documented in Unified API.

7) Docs