Files
illusory-mapp/spec.mobile.md
2026-03-01 07:39:49 +02:00

2.8 KiB

Mobile Integration Spec (Stage 1)

Base URL

  • Processor endpoints are mounted under /api/v1/mobile.

Headers

  • Optional: x-flow-id for end-to-end trace correlation.
  • Required for ping/sync endpoints: x-device-id with a previously registered externalDeviceId.

Endpoints

Register Device

  • Method: POST
  • Path: /api/v1/mobile/register
  • Auth: none (trusted private network assumption)

Payload:

{
  "externalDeviceId": "android-1234",
  "name": "Pixel 8 Pro",
  "manufacturer": "Google",
  "model": "Pixel 8 Pro",
  "androidVersion": "15"
}

Ping Device

  • Method: PUT
  • Path: /api/v1/mobile/ping
  • Required header: x-device-id

Payload:

{
  "pingAt": "2026-03-01T10:15:00.000Z"
}

Sync SMS

  • Method: PUT
  • Path: /api/v1/mobile/sms/sync
  • Required header: x-device-id

Payload:

{
  "messages": [
    {
      "externalMessageId": "msg-1",
      "sender": "+358401111111",
      "recipient": "+358402222222",
      "body": "Hello from device",
      "sentAt": "2026-03-01T10:10:00.000Z",
      "receivedAt": "2026-03-01T10:10:01.000Z",
      "rawPayload": {
        "threadId": "7"
      }
    }
  ]
}

Sync Media Assets

  • Method: PUT
  • Path: /api/v1/mobile/media/sync
  • Required header: x-device-id

Payload:

{
  "assets": [
    {
      "externalMediaId": "media-1",
      "fileId": "01JNE3Q1S3KQX9Y7G2J8G7R0A8",
      "mimeType": "image/jpeg",
      "filename": "IMG_1234.jpg",
      "capturedAt": "2026-03-01T10:05:00.000Z",
      "sizeBytes": 1350021,
      "hash": "sha256-...",
      "metadata": {
        "width": 3024,
        "height": 4032
      }
    }
  ]
}

Response Contract

Success:

{
  "data": {},
  "error": null
}

Failure:

{
  "data": null,
  "error": {
    "flowId": "uuid",
    "code": "VALIDATION_ERROR",
    "message": "Human message",
    "description": "Actionable description",
    "detail": "Technical detail"
  }
}

Admin Query Contract

  • Pagination:
    • page: 1-based integer
    • pageSize: integer
  • Sorting:
    • sortBy: operation-specific
    • sortOrder: asc or desc
  • Paginated response payload:
    • data: rows
    • total: full row count
    • page, pageSize, totalPages

Dedup Rules

  • Device:
    • Upsert on unique externalDeviceId.
  • SMS:
    • Dedup key #1: (deviceId, externalMessageId) when provided.
    • Dedup key #2 fallback: (deviceId, dedupHash) where dedup hash is SHA-256 of (deviceId + sentAt + sender + body).
  • Media:
    • Dedup key: (deviceId, externalMediaId) when provided.
    • fileId in mobile_media_asset is unique.

Operator Checklist

  1. Register a device.
  2. Send ping with x-device-id and verify dashboard lastPingAt updates.
  3. Sync SMS and verify device detail SMS tab updates (polling every 5s).
  4. Sync media and verify device detail Media Assets tab displays rows.