---
estimated_steps: 20
estimated_files: 1
skills_used: []
---

# T02: Wire source_videos into technique detail endpoint

Update the technique detail endpoint to eagerly load source_video_links and build the source_videos list on the response. Verify end-to-end with an API call.

## Steps

1. Update `backend/routers/techniques.py` `get_technique()` function:
   - Add `selectinload(TechniquePage.source_video_links).selectinload(TechniquePageVideo.source_video)` to the query options
   - After building existing response fields, build `source_videos` list from `page.source_video_links`
   - Each item: `SourceVideoSummary(id=link.source_video.id, filename=link.source_video.filename, content_type=link.source_video.content_type.value, added_at=link.added_at)`
   - Add the import for `TechniquePageVideo` and `SourceVideoSummary` at the top of the file
   - Pass `source_videos=source_videos` to the `TechniquePageDetail(...)` constructor

2. Verify the endpoint returns the new fields:
   - Existing pages should return `body_sections_format: "v1"` (inherited from schema default + model default)
   - Existing pages should return `source_videos: []` (no rows in association table yet)

## Must-Haves

- [ ] `selectinload` for source_video_links chained to source_video
- [ ] `source_videos` list built from association table rows
- [ ] Existing pages return empty `source_videos` list (not null, not omitted)
- [ ] `body_sections_format` appears in response

## Verification

- Pick any existing technique slug from the DB
- `curl -s http://ub01:8096/techniques/{slug} | python3 -m json.tool | grep -E 'body_sections_format|source_videos'` shows both fields
- Or if testing locally: verify the router code by reading the constructed response and confirming both fields are passed

## Inputs

- ``backend/models.py` — TechniquePageVideo model and source_video_links relationship (from T01)`
- ``backend/schemas.py` — SourceVideoSummary and updated TechniquePageDetail (from T01)`
- ``backend/routers/techniques.py` — existing get_technique endpoint`

## Expected Output

- ``backend/routers/techniques.py` — updated with source_videos loading and response construction`

## Verification

ssh ub01 'docker exec chrysopedia-api alembic upgrade head' && ssh ub01 'curl -s http://localhost:8000/techniques/$(docker exec chrysopedia-db psql -U chrysopedia -tAc "SELECT slug FROM technique_pages LIMIT 1") | python3 -m json.tool | grep -E "body_sections_format|source_videos"'
