# V2 Command API

Use `command-api-v2` for write actions that change business state.

Base URL:

```text
https://krow-command-api-v2-e3g6witsvq-uc.a.run.app
```

## 1) Required headers

```http
Authorization: Bearer <firebase-id-token>
Idempotency-Key: <unique-per-user-action>
Content-Type: application/json
```

## 2) Route summary

| Method | Route | Purpose |
| --- | --- | --- |
| `POST` | `/commands/orders/create` | Create order with shifts and roles |
| `POST` | `/commands/orders/:orderId/update` | Update mutable order fields |
| `POST` | `/commands/orders/:orderId/cancel` | Cancel order and related eligible records |
| `POST` | `/commands/shifts/:shiftId/assign-staff` | Assign workforce to shift role |
| `POST` | `/commands/shifts/:shiftId/accept` | Accept an assigned shift |
| `POST` | `/commands/shifts/:shiftId/change-status` | Move shift to a new valid status |
| `POST` | `/commands/attendance/clock-in` | Record clock-in event |
| `POST` | `/commands/attendance/clock-out` | Record clock-out event |
| `POST` | `/commands/businesses/:businessId/favorite-staff` | Add favorite staff |
| `DELETE` | `/commands/businesses/:businessId/favorite-staff/:staffId` | Remove favorite staff |
| `POST` | `/commands/assignments/:assignmentId/reviews` | Create or update staff review |
| `GET` | `/readyz` | Ready check |

## 3) Order create

```text
POST /commands/orders/create
```

Request body:

```json
{
  "tenantId": "uuid",
  "businessId": "uuid",
  "vendorId": "uuid",
  "orderNumber": "ORD-1001",
  "title": "Cafe Event Staffing",
  "serviceType": "EVENT",
  "shifts": [
    {
      "shiftCode": "SHIFT-1",
      "title": "Morning Shift",
      "startsAt": "2026-03-12T08:00:00.000Z",
      "endsAt": "2026-03-12T16:00:00.000Z",
      "requiredWorkers": 2,
      "roles": [
        {
          "roleCode": "BARISTA",
          "roleName": "Barista",
          "workersNeeded": 2
        }
      ]
    }
  ]
}
```

## 4) Order update

```text
POST /commands/orders/:orderId/update
```

Required body fields:
- `tenantId`
- at least one mutable field such as `title`, `description`, `vendorId`, `serviceType`, `startsAt`, `endsAt`, `locationName`, `locationAddress`, `latitude`, `longitude`, `notes`, `metadata`

You can also send `null` to clear nullable fields.

## 5) Order cancel

```text
POST /commands/orders/:orderId/cancel
```

Example request:

```json
{
  "tenantId": "uuid",
  "reason": "Client cancelled"
}
```

## 6) Shift assign staff

```text
POST /commands/shifts/:shiftId/assign-staff
```

Example request:

```json
{
  "tenantId": "uuid",
  "shiftRoleId": "uuid",
  "workforceId": "uuid",
  "applicationId": "uuid"
}
```

## 7) Shift accept

```text
POST /commands/shifts/:shiftId/accept
```

Example request:

```json
{
  "shiftRoleId": "uuid",
  "workforceId": "uuid"
}
```

## 8) Shift status change

```text
POST /commands/shifts/:shiftId/change-status
```

Example request:

```json
{
  "tenantId": "uuid",
  "status": "PENDING_CONFIRMATION",
  "reason": "Waiting for worker confirmation"
}
```

Allowed status values:
- `DRAFT`
- `OPEN`
- `PENDING_CONFIRMATION`
- `ASSIGNED`
- `ACTIVE`
- `COMPLETED`
- `CANCELLED`

## 9) Attendance

### Clock in

```text
POST /commands/attendance/clock-in
```

### Clock out

```text
POST /commands/attendance/clock-out
```

Example request body for both:

```json
{
  "assignmentId": "uuid",
  "sourceType": "NFC",
  "sourceReference": "iphone-15-pro-max",
  "nfcTagUid": "NFC-DEMO-ANA-001",
  "deviceId": "device-123",
  "latitude": 37.422,
  "longitude": -122.084,
  "accuracyMeters": 8,
  "capturedAt": "2026-03-11T17:15:00.000Z"
}
```

## 10) Favorite staff

### Add favorite

```text
POST /commands/businesses/:businessId/favorite-staff
```

### Remove favorite

```text
DELETE /commands/businesses/:businessId/favorite-staff/:staffId
```

Request body when adding:

```json
{
  "tenantId": "uuid",
  "staffId": "uuid"
}
```

## 11) Staff review

```text
POST /commands/assignments/:assignmentId/reviews
```

Example request:

```json
{
  "tenantId": "uuid",
  "businessId": "uuid",
  "staffId": "uuid",
  "rating": 5,
  "reviewText": "Strong shift performance",
  "tags": ["punctual", "professional"]
}
```

## 12) Live status

These routes were live-tested on `2026-03-11` against the deployed dev service and `krow-sql-v2`.
