---
estimated_steps: 35
estimated_files: 3
skills_used: []
---

# T01: Add video detail and transcript API endpoints

Add two new endpoints to the existing videos router:

1. `GET /videos/{video_id}` — single video detail with eager-loaded creator (name, slug). Returns `SourceVideoDetail` schema (extends SourceVideoRead with creator_name, creator_slug fields).

2. `GET /videos/{video_id}/transcript` — returns all TranscriptSegments for a video, ordered by segment_index. Returns `TranscriptForPlayerResponse` with video_id and segments list.

Both return 404 for non-existent video IDs.

## Steps

1. Read `backend/schemas.py` to understand existing SourceVideoRead and TranscriptSegmentRead schemas.
2. Add new schemas to `backend/schemas.py`:
   - `SourceVideoDetail` — extends SourceVideoRead, adds `creator_name: str`, `creator_slug: str`, `video_url: str | None = None` (always None for now)
   - `TranscriptForPlayerResponse` — `video_id: uuid.UUID`, `segments: list[TranscriptSegmentRead]`, `total: int`
3. Read `backend/routers/videos.py` to understand the existing list endpoint pattern.
4. Add `GET /videos/{video_id}` endpoint to `backend/routers/videos.py`:
   - Query SourceVideo by ID with `selectinload(SourceVideo.creator)`
   - Return 404 if not found
   - Map to SourceVideoDetail with creator_name and creator_slug from the joined creator
5. Add `GET /videos/{video_id}/transcript` endpoint:
   - Query TranscriptSegments where source_video_id matches, ordered by segment_index
   - Return 404 if video doesn't exist
   - Return TranscriptForPlayerResponse
6. Write `backend/tests/test_video_detail.py` with tests:
   - test_get_video_detail_success — creates a video+creator, verifies response shape
   - test_get_video_detail_404 — random UUID returns 404
   - test_get_transcript_success — creates video + segments, verifies ordering and count
   - test_get_transcript_404 — random UUID returns 404
   - test_get_transcript_empty — video exists but has no segments, returns empty list
7. Run tests and fix any issues.

## Must-Haves

- [ ] GET /videos/{video_id} returns video detail with creator_name and creator_slug
- [ ] GET /videos/{video_id}/transcript returns segments ordered by segment_index
- [ ] Both endpoints return 404 for non-existent video IDs
- [ ] Tests pass

## Failure Modes

| Dependency | On error | On timeout | On malformed response |
|------------|----------|-----------|----------------------|
| PostgreSQL | 500 with logged traceback | FastAPI default timeout | N/A (ORM-mapped) |
| video_id UUID parse | FastAPI returns 422 automatically | N/A | N/A |

## Inputs

- ``backend/routers/videos.py` — existing videos router with list endpoint`
- ``backend/schemas.py` — existing SourceVideoRead and TranscriptSegmentRead schemas`
- ``backend/models.py` — SourceVideo, TranscriptSegment, Creator models`
- ``backend/database.py` — get_session dependency`

## Expected Output

- ``backend/routers/videos.py` — updated with GET /videos/{video_id} and GET /videos/{video_id}/transcript endpoints`
- ``backend/schemas.py` — updated with SourceVideoDetail and TranscriptForPlayerResponse schemas`
- ``backend/tests/test_video_detail.py` — 5 integration tests for the new endpoints`

## Verification

cd backend && python -m pytest tests/test_video_detail.py -v
