HTTP API: read transcript, summary, and processing status #25

Open
opened 2026-07-27 13:54:25 +00:00 by mathias · 0 comments
Owner

Problem

Submission (#24) is useless without a way to read the result back. A caller needs to poll to a terminal state and then pull the transcript or summary.

Depends on #23, #24.

Scope

GET /api/v1/videos/{video_id} — status envelope:

{ "video_id": "...", "title": "...", "status": "queued|transcribing|summarizing|ready|no_transcript|rate_limited|failed", "updated_at": "..." }

GET /api/v1/videos/{video_id}/transcript — transcript text plus source provenance.

GET /api/v1/videos/{video_id}/summary — summary text, highlights, takeaways, and AI provenance.

Status contract, honest per ADR-010 (degrade-never-error):

  • no_transcript is a terminal success, not an error. GET /transcript returns 200 with empty text and source: "none", so a caller stops polling instead of retrying forever.
  • rate_limited is non-terminal — a per-user retry state (ADR-014), never a shared terminal one. Include a retry_after hint.
  • GET /summary before ready409 with the current status in the body, so the caller knows to keep polling rather than treating it as missing.

All reads are user-scoped through RLS. A caller must never read another user's video.

Non-goals

  • Webhooks / push. Polling only for now; revisit if the poll loop proves painful in practice.
  • Re-analysis with a different model (the shared transcript table already makes this cheap — separate issue when there's a caller for it).

Acceptance

  • caveman: me return this user's transcript, not another user's transcript
  • Red-first tests per endpoint and per status value
  • no_transcript returns 200, not 404 — explicit test
  • rate_limited is never persisted as terminal — explicit test
  • RLS test: token for user A cannot read user B's video, and gets 404 rather than 403 (no existence leak)
  • A submit-then-poll-to-terminal round trip covered end to end in test/acceptance

Handoff

Branch from main, one file per commit, squash-merge PR back to main, human review gate.

## Problem Submission (#24) is useless without a way to read the result back. A caller needs to poll to a terminal state and then pull the transcript or summary. Depends on #23, #24. ## Scope `GET /api/v1/videos/{video_id}` — status envelope: ```json { "video_id": "...", "title": "...", "status": "queued|transcribing|summarizing|ready|no_transcript|rate_limited|failed", "updated_at": "..." } ``` `GET /api/v1/videos/{video_id}/transcript` — transcript text plus source provenance. `GET /api/v1/videos/{video_id}/summary` — summary text, highlights, takeaways, and AI provenance. Status contract, honest per ADR-010 (degrade-never-error): - `no_transcript` is a **terminal success**, not an error. `GET /transcript` returns `200` with empty text and `source: "none"`, so a caller stops polling instead of retrying forever. - `rate_limited` is **non-terminal** — a per-user retry state (ADR-014), never a shared terminal one. Include a `retry_after` hint. - `GET /summary` before `ready` → `409` with the current status in the body, so the caller knows to keep polling rather than treating it as missing. All reads are user-scoped through RLS. A caller must never read another user's video. ## Non-goals - Webhooks / push. Polling only for now; revisit if the poll loop proves painful in practice. - Re-analysis with a different model (the shared transcript table already makes this cheap — separate issue when there's a caller for it). ## Acceptance - [ ] `caveman: me return this user's transcript, not another user's transcript` - [ ] Red-first tests per endpoint and per status value - [ ] `no_transcript` returns 200, not 404 — explicit test - [ ] `rate_limited` is never persisted as terminal — explicit test - [ ] RLS test: token for user A cannot read user B's video, and gets 404 rather than 403 (no existence leak) - [ ] A submit-then-poll-to-terminal round trip covered end to end in `test/acceptance` ## Handoff Branch from `main`, one file per commit, squash-merge PR back to `main`, human review gate.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/tapir#25