docs(m4): add frontend api guide and remove agent tracking files

This commit is contained in:
zouantchaw
2026-02-24 10:25:59 -05:00
parent 52c3fbad40
commit d5e49ca148
5 changed files with 200 additions and 270 deletions

View File

@@ -1,10 +1,18 @@
# M4 API Catalog (Implementation Contract)
Status: Draft
Date: 2026-02-24
Owner: Technical Lead
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.

View File

@@ -0,0 +1,188 @@
# M4 Core API Frontend Guide (Dev)
Status: Active
Last updated: 2026-02-24
Audience: Web and mobile frontend developers
## 1) Base URLs (dev)
1. Core API: `https://krow-core-api-e3g6witsvq-uc.a.run.app`
2. Command API: `https://krow-command-api-e3g6witsvq-uc.a.run.app`
## 2) Auth requirements
1. Send Firebase ID token on protected routes:
```http
Authorization: Bearer <firebase-id-token>
```
2. Health route is public:
- `GET /health`
3. All other routes require Firebase token.
## 3) Standard error envelope
```json
{
"code": "STRING_CODE",
"message": "Human readable message",
"details": {},
"requestId": "uuid"
}
```
## 4) Core API endpoints
## 4.1 Upload file
1. Route: `POST /core/upload-file`
2. Alias: `POST /uploadFile`
3. Content type: `multipart/form-data`
4. Form fields:
- `file` (required)
- `visibility` (optional: `public` or `private`, default `private`)
- `category` (optional)
5. Accepted file types:
- `application/pdf`
- `image/jpeg`
- `image/jpg`
- `image/png`
6. Max upload size: `10 MB` (default)
7. Current behavior: real upload to Cloud Storage (not mock)
8. Success `200` example:
```json
{
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/173...",
"contentType": "application/pdf",
"size": 12345,
"bucket": "krow-workforce-dev-private",
"path": "uploads/<uid>/173..._file.pdf",
"requestId": "uuid"
}
```
## 4.2 Create signed URL
1. Route: `POST /core/create-signed-url`
2. Alias: `POST /createSignedUrl`
3. Request body:
```json
{
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/file.pdf",
"expiresInSeconds": 300
}
```
4. Security checks:
- bucket must be allowed (`krow-workforce-dev-public` or `krow-workforce-dev-private`)
- path must be owned by caller (`uploads/<caller_uid>/...`)
- object must exist
- `expiresInSeconds` must be `<= 900`
5. Success `200` example:
```json
{
"signedUrl": "https://storage.googleapis.com/...",
"expiresAt": "2026-02-24T15:22:28.105Z",
"requestId": "uuid"
}
```
6. Typical errors:
- `400 VALIDATION_ERROR` (bad payload or expiry too high)
- `403 FORBIDDEN` (path not owned by caller)
- `404 NOT_FOUND` (object does not exist)
## 4.3 Invoke model
1. Route: `POST /core/invoke-llm`
2. Alias: `POST /invokeLLM`
3. Request body:
```json
{
"prompt": "Return JSON with keys summary and risk.",
"responseJsonSchema": {
"type": "object",
"properties": {
"summary": { "type": "string" },
"risk": { "type": "string" }
},
"required": ["summary", "risk"]
},
"fileUrls": []
}
```
4. Current behavior: real Vertex model call (not mock)
- model: `gemini-2.0-flash-001`
- timeout: `20 seconds`
5. Rate limit:
- per-user `20 requests/minute` (default)
- on limit: `429 RATE_LIMITED`
- includes `Retry-After` header
6. Success `200` example:
```json
{
"result": { "summary": "text", "risk": "Low" },
"model": "gemini-2.0-flash-001",
"latencyMs": 367,
"requestId": "uuid"
}
```
## 5) Command API endpoint currently ready for consumption
## 5.1 Create order command (scaffold)
1. Route: `POST /commands/orders/create`
2. Required headers:
- `Authorization: Bearer <firebase-id-token>`
- `Idempotency-Key: <unique-client-key>`
3. Current behavior:
- validates auth + idempotency
- returns accepted scaffold response
- duplicate key returns the original response payload
4. Success `200` example:
```json
{
"accepted": true,
"route": "/commands/orders/create",
"commandId": "/commands/orders/create:173...",
"idempotencyKey": "client-key-123",
"requestId": "uuid"
}
```
## 6) Frontend fetch examples (web)
## 6.1 Signed URL request
```ts
const token = await firebaseAuth.currentUser?.getIdToken();
const res = await fetch('https://krow-core-api-e3g6witsvq-uc.a.run.app/core/create-signed-url', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
fileUri: 'gs://krow-workforce-dev-private/uploads/<uid>/file.pdf',
expiresInSeconds: 300,
}),
});
const data = await res.json();
```
## 6.2 Model request
```ts
const token = await firebaseAuth.currentUser?.getIdToken();
const res = await fetch('https://krow-core-api-e3g6witsvq-uc.a.run.app/core/invoke-llm', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt: 'Return JSON with status.',
responseJsonSchema: {
type: 'object',
properties: { status: { type: 'string' } },
required: ['status'],
},
}),
});
const data = await res.json();
```
## 7) Notes for frontend team
1. Use canonical `/core/*` routes for new work.
2. Aliases exist only for migration compatibility.
3. `requestId` in responses should be logged client-side for debugging.
4. For 429 on model route, retry with exponential backoff and respect `Retry-After`.