Storyboards

A storyboard is a card of visual tiles the Creature Console can tap to do things. The server is a dumb persistence layer — it stamps id and timestamps, stores the document, broadcasts a cache-invalidation, and does not interpret tiles[].action. The client owns the action type vocabulary and the server preserves unknown shapes verbatim so old and new clients can interoperate as the vocabulary grows.

GET /api/v1/storyboard — List all storyboards (newest first by updated_at). Returns {count, items: [...]}.

GET /api/v1/storyboard/{id} — Fetch one storyboard by its UUID.

POST /api/v1/storyboard — Create a new storyboard. Server generates the UUID and stamps created_at / updated_at. Any id / created_at / updated_at the client sends in the body is silently ignored.

{
  "title": "Halloween Front Porch",
  "notes": "Beaky greets; Mango heckles.",
  "tiles": [
    {
      "id": "uuid",
      "x": 0.06, "y": 0.08, "width": 0.26, "height": 0.20,
      "label": "Greet",
      "sf_symbol": "hand.wave.fill",
      "tint_color_hex": "#34C759",
      "action": { "type": "ad_hoc_speech", "creature_id": "uuid", "resume_playlist": true }
    }
  ]
}

PUT /api/v1/storyboard/{id} — Replace an existing storyboard. created_at is preserved; updated_at bumps to now. 404 if no storyboard exists at that id.

DELETE /api/v1/storyboard/{id} — Delete a storyboard.

Caps: title ≤ 256 chars, notes ≤ 16384 chars, ≤ 200 tiles, tile label ≤ 256 chars, tile id must be UUID-shaped. Tile action (when present) must be a JSON object — the server checks that and nothing else inside, on purpose.