mitbringsl/docs/API.md
Tronax a00db14cba
Phase F: NetworkMonitor, offline banner, README & architecture docs
- NetworkMonitor: ConnectivityState Flow using ConnectivityManager.NetworkCallback
- ListsScreen & ViewModel: live offline indicator banner when disconnected
- Documentation:
  - docs/ARCHITECTURE.md: system design & tech stack overview
  - docs/SYNC.md: HLC timestamping, op_log outbox & LWW projection specification
  - docs/API.md: REST API endpoint specification
  - README.md: quickstart guide for backend, docker compose & Android app
- Verification: backend & android test suites 100% green 
2026-08-05 20:14:04 +02:00

3.3 KiB
Raw Blame History

Mitbringsl REST API Specification

Base URL: / Authentication: Bearer Token via Authorization: Bearer <session_token> header or session cookie.


Health & Diagnostics

GET /healthz

Liveness probe. Returns HTTP 200 OK.

GET /readyz

Readiness probe. Checks PostgreSQL connection pool health.

  • 200 OK: Database reachable.
  • 503 Service Unavailable: Database error.

Authentication (/auth)

POST /auth/register

Create a new email/password account.

  • Request:
    { "email": "user@example.com", "password": "secretpassword", "display_name": "Max" }
    
  • Response (201 Created):
    {
      "token": "<opaque_session_token>",
      "expires_at": "2026-09-04T20:00:00Z",
      "user": { "id": "<uuid>", "email": "user@example.com", "display_name": "Max" }
    }
    

POST /auth/login

Authenticate with email/password.

  • Request:
    { "email": "user@example.com", "password": "secretpassword" }
    
  • Response (200 OK): Same shape as register.

POST /auth/oidc

Authenticate via Google or custom OpenID Connect provider.

  • Request:
    { "provider": "google", "id_token": "<jwt>" }
    
  • Response (200 OK): Same shape as login.

POST /auth/logout

Revoke active session token. Returns 204 No Content.


Lists (/api/lists)

GET /api/lists

Fetch all active (non-deleted) lists owned by the authenticated user.

  • Response (200 OK):
    {
      "lists": [
        { "id": "<uuid>", "name": "Wocheneinkauf", "updated_at": "2026-08-05T19:00:00Z", "hlc_ts": 177000000000000 }
      ]
    }
    

POST /api/lists

Create a new list.

  • Request: { "name": "Supermarkt" }
  • Response (201 Created): { "id": "<uuid>", "name": "Supermarkt", ... }

GET /api/lists/{id}

Fetch list detail including items.

  • Response (200 OK):
    {
      "id": "<uuid>",
      "name": "Wocheneinkauf",
      "updated_at": "...",
      "hlc_ts": 177000000000000,
      "items": [
        { "id": "<uuid>", "name": "Milch", "quantity": "1L", "checked": false, "hlc_ts": 177000000000001 }
      ]
    }
    

Sync & Ops (/api/lists/{id}/ops)

POST /api/lists/{id}/ops

Push a batch of client operations (max 100).

  • Request:
    {
      "client_id": "<client_uuid>",
      "ops": [
        {
          "client_seq": 1,
          "op_type": "item_add",
          "target_id": "<item_uuid>",
          "hlc_ts": 177000000000000,
          "payload": { "name": "Brot", "quantity": "1 Stück" }
        }
      ]
    }
    
  • Response (200 OK):
    {
      "results": [
        { "client_seq": 1, "seq": 42, "hlc_ts": 177000000000001 }
      ]
    }
    

GET /api/lists/{id}/ops?since={seq}

Pull operations since server sequence since.

  • Response (200 OK):
    {
      "ops": [
        {
          "seq": 42,
          "client_id": "<client_uuid>",
          "op_type": "item_add",
          "target_id": "<item_uuid>",
          "payload": { "name": "Brot" },
          "client_seq": 1,
          "hlc_ts": 177000000000001,
          "created_at": "2026-08-05T20:00:00Z"
        }
      ],
      "has_more": false
    }
    

Suggestions (/api/suggestions)

GET /api/suggestions?q={query}

Fuzzy autocomplete search for item names (pg_trgm).

  • Response (200 OK):
    { "suggestions": ["milch", "mineralwasser", "müsli"] }