---
id: S06
parent: M014
milestone: M014
provides:
  - GET /admin/pipeline/technique-pages endpoint with source/version counts and filters
  - AdminTechniquePages React page at /admin/techniques
  - Admin dropdown with three entries: Reports, Pipeline, Techniques
requires:
  []
affects:
  []
key_files:
  - backend/routers/pipeline.py
  - backend/schemas.py
  - frontend/src/pages/AdminTechniquePages.tsx
  - frontend/src/api/public-client.ts
  - frontend/src/App.tsx
  - frontend/src/components/AdminDropdown.tsx
key_decisions:
  - Used correlated scalar subqueries for source_video_count and version_count rather than joins with GROUP BY — cleaner filter composition when adding multi_source_only and creator filters
patterns_established:
  - Admin list endpoint pattern: correlated scalar subqueries for count aggregation + Pydantic response schema + offset/limit pagination + slug-based filtering
observability_surfaces:
  - none
drill_down_paths:
  - .gsd/milestones/M014/slices/S06/tasks/T01-SUMMARY.md
  - .gsd/milestones/M014/slices/S06/tasks/T02-SUMMARY.md
duration: ""
verification_result: passed
completed_at: 2026-04-03T02:01:20.602Z
blocker_discovered: false
---

# S06: Admin UI — Multi-Source Pipeline Management

**Added admin technique pages view with paginated API endpoint (source/version counts, filters, sort) and React table UI with expandable source video rows, format badges, and cross-links to pipeline admin and public pages.**

## What Happened

Two tasks delivered the admin multi-source management surface end to end.

T01 added `GET /admin/pipeline/technique-pages` to the pipeline router. The endpoint returns paginated technique pages with aggregated source_video_count and version_count computed via correlated scalar subqueries against the technique_page_videos and technique_page_versions tables. Supports three filters: `multi_source_only` (boolean, pages with >1 source video), `creator` (slug match), and `sort` (recent/alpha/creator). Response includes body_sections_format so admins can see which pages use the v2 nested format. Pydantic schemas AdminTechniquePageItem and AdminTechniquePageListResponse follow existing schema patterns.

T02 built the frontend AdminTechniquePages page. Table shows title (linked to public page), creator (linked to creator detail), category, format badge (v1/v2), source count, version count, and updated date. Clicking a row expands it to show source videos fetched from the existing technique detail endpoint, with links to pipeline admin via video ID query param. Filter bar has multi-source-only checkbox, creator text input, and sort dropdown. Route registered at /admin/techniques, entry added to AdminDropdown alongside Reports and Pipeline.

Both association tables (technique_page_videos, technique_page_versions) are currently empty, so counts show 0. The queries are correct and will return real counts once S04's compose logic populates the junction table during actual multi-source processing runs.

## Verification

1. Schema import: `docker exec chrysopedia-api python -c "from schemas import AdminTechniquePageItem, AdminTechniquePageListResponse; print('OK')"` — passes, both schemas importable.
2. Endpoint structure: `curl -sf http://ub01:8096/api/v1/admin/pipeline/technique-pages` returns JSON with items array (20 pages), total, offset, limit fields. Each item has source_video_count, version_count, body_sections_format.
3. Filters verified: multi_source_only=true returns 0 items (correct — no multi-source pages yet), creator=skope returns 2 items, sort=alpha returns alphabetically ordered titles.
4. Pagination: offset=5&limit=2 returns 2 items with total=20.
5. Frontend build: `cd frontend && npm run build` exits 0 with zero TypeScript errors.
6. Browser: /admin/techniques renders table with all columns, row expansion shows source videos section, admin dropdown shows Reports/Pipeline/Techniques.

## Requirements Advanced

None.

## Requirements Validated

None.

## New Requirements Surfaced

None.

## Requirements Invalidated or Re-scoped

None.

## Deviations

None. Both tasks delivered as planned.

## Known Limitations

Source video and version counts are all 0 because the technique_page_videos and technique_page_versions association tables are not yet populated by production pipeline runs. The queries and UI display correctly and will show real data when S04's compose logic writes to these tables during multi-source processing.

## Follow-ups

None.

## Files Created/Modified

- `backend/routers/pipeline.py` — Added GET /admin/pipeline/technique-pages endpoint with correlated subquery counts, multi_source_only/creator/sort filters, and pagination
- `backend/schemas.py` — Added AdminTechniquePageItem and AdminTechniquePageListResponse Pydantic schemas
- `frontend/src/pages/AdminTechniquePages.tsx` — New admin page with technique pages table, expandable source video rows, filter bar, format badges
- `frontend/src/api/public-client.ts` — Added AdminTechniquePageItem interface and fetchAdminTechniquePages function
- `frontend/src/App.tsx` — Added /admin/techniques route
- `frontend/src/components/AdminDropdown.tsx` — Added Techniques entry to admin dropdown menu
