# S06: Admin UI — Multi-Source Pipeline Management

**Goal:** Admin view for multi-source technique pages — list with source/version counts, expandable rows showing source videos and composition history, cross-links to pipeline admin.
**Demo:** After this: Admin view for multi-source page shows source dropdown, composition history, per-video chunking inspection.

## Tasks
- [x] **T01: Added paginated GET /admin/pipeline/technique-pages endpoint with source video counts, version counts, and multi-source/creator/sort filters** — Add a new admin endpoint that returns technique pages with aggregated source video counts, version counts, body_sections_format, and creator info. Supports filtering by multi_source_only (boolean) and creator (slug). This provides the data source for the admin technique pages UI.

The endpoint lives in `backend/routers/pipeline.py` alongside other admin endpoints. It queries TechniquePage with joins to Creator, counts from technique_page_videos and technique_page_versions, and returns a paginated response.

## Steps

1. Read `backend/routers/pipeline.py` to understand existing admin endpoint patterns (imports, auth, response style).
2. Read `backend/schemas.py` to see existing schema patterns.
3. Add a new Pydantic response schema `AdminTechniquePageItem` in `backend/schemas.py` with fields: id, title, slug, creator_name, creator_slug, topic_category, body_sections_format, source_video_count (int), version_count (int), created_at, updated_at. Add `AdminTechniquePageListResponse` with items list and total count.
4. Add `GET /admin/pipeline/technique-pages` endpoint in `backend/routers/pipeline.py`. Query uses: `select(TechniquePage)` with `selectinload(TechniquePage.creator)`, correlated subqueries for source_video_count (count from technique_page_videos where technique_page_id matches) and version_count (count from technique_page_versions). Support query params: `multi_source_only: bool = False` (filter source_video_count > 1), `creator: str | None` (filter by creator slug), `sort: str = 'recent'` (recent/alpha/creator), `offset: int = 0`, `limit: int = 50`.
5. Test endpoint manually via curl against the running API on ub01.

## Must-Haves

- [ ] Endpoint returns correct source_video_count and version_count per page
- [ ] multi_source_only=true filters to pages with >1 source video
- [ ] creator filter works by slug
- [ ] Response includes body_sections_format field
- [ ] Pagination works (offset/limit/total)

## Verification

- `ssh ub01 'cd /vmPool/r/repos/xpltdco/chrysopedia && PYTHONPATH=backend python -c "from schemas import AdminTechniquePageItem, AdminTechniquePageListResponse; print(AdminTechniquePageItem.model_fields.keys())"'` exits 0
- After deploying: `curl -s http://ub01:8096/api/v1/admin/pipeline/technique-pages | python3 -m json.tool | head -30` returns valid JSON with items array containing source_video_count and version_count fields
  - Estimate: 45m
  - Files: backend/routers/pipeline.py, backend/schemas.py
  - Verify: ssh ub01 'cd /vmPool/r/repos/xpltdco/chrysopedia && PYTHONPATH=backend python -c "from schemas import AdminTechniquePageItem; print(AdminTechniquePageItem.model_fields.keys())"' && curl -sf http://ub01:8096/api/v1/admin/pipeline/technique-pages | python3 -c 'import json,sys; d=json.load(sys.stdin); assert "items" in d; print(f"OK: {d["total"]} pages")'
- [x] **T02: Built AdminTechniquePages page at /admin/techniques with table, expandable source video rows, filters, format badges, and admin dropdown entry** — Create the frontend page for admin technique page management. Table showing technique pages with source video counts, version counts, format badges, and creator. Expandable rows show source videos list (from existing `/techniques/{slug}` detail endpoint) and link to version history. Filters for multi-source only and creator. Cross-links to pipeline admin and public technique pages.

Follows patterns from `AdminPipeline.tsx` (table layout, expandable rows, badges, fetch pattern).

## Steps

1. Read `frontend/src/pages/AdminPipeline.tsx` (first ~100 lines) for fetch patterns, state management, table structure.
2. Read `frontend/src/api/public-client.ts` for the `request<T>` pattern and existing type exports.
3. Add TypeScript types and fetch function to `frontend/src/api/public-client.ts`: `AdminTechniquePageItem` interface (id, title, slug, creator_name, creator_slug, topic_category, body_sections_format, source_video_count, version_count, created_at, updated_at) and `fetchAdminTechniquePages(params)` function calling `GET /admin/pipeline/technique-pages`.
4. Create `frontend/src/pages/AdminTechniquePages.tsx`:
   - State: items array, loading, error, filters (multiSourceOnly boolean, creatorFilter string), expandedSlug
   - Fetch on mount and filter change using the new client function
   - Table columns: Title (link to public page), Creator (link to creator detail), Category, Format (v1/v2 badge), Sources (count), Versions (count), Updated
   - Click row to expand → fetch technique detail via existing `fetchTechnique(slug)` → show source videos list with filenames and added_at dates, link to each video in pipeline admin via `/admin/pipeline?video={id}`
   - Filter bar: "Multi-source only" toggle checkbox, creator text filter
   - Use existing CSS patterns from AdminPipeline (admin-page class, table styles)
5. Add route in `frontend/src/App.tsx`: `<Route path="/admin/techniques" element={<AdminTechniquePages />} />`
6. Add "Techniques" link in `frontend/src/components/AdminDropdown.tsx` menu items.
7. Build frontend to verify no TypeScript errors.

## Must-Haves

- [ ] Table renders with all columns (title, creator, category, format, sources, versions, updated)
- [ ] Row expand shows source videos with filenames and dates
- [ ] Multi-source filter toggle works
- [ ] Cross-link to pipeline admin works (via video ID query param)
- [ ] Cross-link to public technique page works
- [ ] Route `/admin/techniques` works
- [ ] Admin dropdown includes Techniques entry

## Verification

- `cd frontend && npm run build` exits 0 (no TypeScript errors)
- After deploying: navigate to `http://ub01:8096/admin/techniques` in browser, page renders with technique data
- Admin dropdown shows three items: Reports, Pipeline, Techniques
  - Estimate: 1h30m
  - Files: frontend/src/api/public-client.ts, frontend/src/pages/AdminTechniquePages.tsx, frontend/src/App.tsx, frontend/src/components/AdminDropdown.tsx
  - Verify: cd frontend && npm run build 2>&1 | tail -5
