Files
Krow-workspace/docs/MILESTONES/M4/planning/m4-api-catalog.md

6.4 KiB

M4 API Catalog (Implementation Contract)

Status: Active (Planning + Route Inventory)
Date: 2026-02-24
Owner: Technical Lead
Environment: dev

Frontend source of truth

For frontend implementation, use:

  • docs/MILESTONES/M4/planning/m4-core-api-frontend-guide.md

Reason:

  • this catalog is the broader M4 planning contract
  • the frontend guide is the exact deployed request/response contract

1) Scope and purpose

This file defines the backend endpoint contract for the M4 foundation build.

2) Global API rules

  1. Canonical route groups:
  • /core/* for foundational integration routes
  • /commands/* for business-critical writes
  1. Foundation phase security model:
  • authenticated user required
  • role map enforcement deferred
  • policy hook required in handler design
  1. Standard error envelope:
{
  "code": "STRING_CODE",
  "message": "Human readable message",
  "details": {},
  "requestId": "optional-request-id"
}
  1. Required request headers:
  • Authorization: Bearer <firebase-token>
  • X-Request-Id: <uuid> (optional but recommended)
  1. Required response headers:
  • X-Request-Id
  1. Validation:
  • all input validated server-side
  • reject unknown/invalid fields
  1. Logging:
  • route
  • requestId
  • actorId
  • latencyMs
  • outcome
  1. Timeouts and retries:
  • command writes must be retry-safe
  • use idempotency keys for command write routes
  1. Idempotency storage:
  • store in Cloud SQL table
  • key scope: userId + route + idempotencyKey
  • key retention: 24 hours
  • repeated key returns original response payload

3) Compatibility aliases (transition)

  1. POST /uploadFile -> POST /core/upload-file
  2. POST /createSignedUrl -> POST /core/create-signed-url
  3. POST /invokeLLM -> POST /core/invoke-llm

4) Rate-limit baseline (initial)

  1. /core/invoke-llm: 60 requests per minute per user
  2. /core/upload-file: 30 requests per minute per user
  3. /core/create-signed-url: 120 requests per minute per user
  4. /commands/*: 60 requests per minute per user

4.1 Timeout baseline (initial)

  1. /core/invoke-llm: 20-second hard timeout
  2. other /core/* routes: 10-second timeout
  3. /commands/* routes: 15-second timeout

5) Core routes

5.1 Upload file

  1. Method and route: POST /core/upload-file
  2. Auth: required
  3. Idempotency key: optional
  4. Request: multipart form data
  • file (required)
  • category (optional)
  • visibility (optional: public or private)
  1. Success 200:
{
  "fileUri": "gs://bucket/path/file.ext",
  "contentType": "application/pdf",
  "size": 12345,
  "bucket": "krow-uploads-private",
  "path": "documents/staff/..."
}
  1. Errors:
  • UNAUTHENTICATED
  • INVALID_FILE_TYPE
  • FILE_TOO_LARGE
  • UPLOAD_FAILED

5.2 Create signed URL

  1. Method and route: POST /core/create-signed-url
  2. Auth: required
  3. Idempotency key: optional
  4. Request:
{
  "fileUri": "gs://bucket/path/file.ext",
  "expiresInSeconds": 300
}
  1. Success 200:
{
  "signedUrl": "https://...",
  "expiresAt": "2026-02-24T15:00:00Z"
}
  1. Errors:
  • UNAUTHENTICATED
  • FORBIDDEN_FILE_ACCESS
  • INVALID_EXPIRES_IN
  • SIGN_URL_FAILED

5.3 Invoke model

  1. Method and route: POST /core/invoke-llm
  2. Auth: required
  3. Idempotency key: optional
  4. Request:
{
  "prompt": "...",
  "responseJsonSchema": {},
  "fileUrls": []
}
  1. Success 200:
{
  "result": {},
  "model": "provider/model-name",
  "latencyMs": 980
}
  1. Errors:
  • UNAUTHENTICATED
  • INVALID_SCHEMA
  • MODEL_TIMEOUT
  • MODEL_FAILED
  1. Provider default:
  • Vertex AI Gemini

5.4 Health check

  1. Method and route: GET /healthz
  2. Auth: optional (internal policy)
  3. Success 200:
{
  "ok": true,
  "service": "krow-backend",
  "version": "commit-or-tag"
}

5.5 Storage bucket policy defaults (dev)

  1. Public bucket: krow-workforce-dev-public
  2. Private bucket: krow-workforce-dev-private
  3. Private objects are never returned directly; only signed URLs are returned.

6) Command routes (wave 1)

6.1 Create order

  1. Method and route: POST /commands/orders/create
  2. Auth: required
  3. Idempotency key: required
  4. Purpose: create order + shifts + roles atomically
  5. Replaces:
  • apps/web/src/features/operations/orders/components/CreateOrderDialog.tsx
  • apps/mobile/packages/features/client/home/lib/src/presentation/widgets/shift_order_form_sheet.dart
  • apps/mobile/packages/features/client/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart

6.2 Update order

  1. Method and route: POST /commands/orders/{orderId}/update
  2. Auth: required
  3. Idempotency key: required
  4. Purpose: policy-safe multi-entity order update
  5. Replaces:
  • apps/web/src/features/operations/orders/EditOrder.tsx
  • apps/mobile/packages/features/client/view_orders/lib/src/presentation/widgets/view_order_card.dart

6.3 Cancel order

  1. Method and route: POST /commands/orders/{orderId}/cancel
  2. Auth: required
  3. Idempotency key: required
  4. Purpose: enforce cancellation policy and return explicit conflict code
  5. Replaces:
  • apps/web/src/features/operations/orders/OrderDetail.tsx

6.4 Change shift status

  1. Method and route: POST /commands/shifts/{shiftId}/change-status
  2. Auth: required
  3. Idempotency key: required
  4. Purpose: enforce state transitions server-side
  5. Replaces:
  • apps/web/src/features/operations/tasks/TaskBoard.tsx

6.5 Assign staff

  1. Method and route: POST /commands/shifts/{shiftId}/assign-staff
  2. Auth: required
  3. Idempotency key: required
  4. Purpose: assign + count update + conflict checks atomically
  5. Replaces:
  • apps/web/src/features/operations/orders/components/AssignStaffModal.tsx

6.6 Accept shift

  1. Method and route: POST /commands/shifts/{shiftId}/accept
  2. Auth: required
  3. Idempotency key: required
  4. Purpose: application + counters + rollback-safe behavior in one command
  5. Replaces:
  • apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart

7) Locked defaults before coding starts

  1. Idempotency keys are stored in Cloud SQL with 24-hour retention.
  2. Request validation library is zod.
  3. Validation schema location is backend/<service>/src/contracts/.
  4. Storage buckets are:
  • krow-workforce-dev-public
  • krow-workforce-dev-private
  1. Model provider is Vertex AI Gemini with a 20-second timeout for /core/invoke-llm.

8) Target response-time objectives (p95)

  1. /healthz under 200ms
  2. /core/create-signed-url under 500ms
  3. /commands/* under 1500ms
  4. /core/invoke-llm under 15000ms