---
id: S02
parent: M006
milestone: M006
provides:
  - Pipeline events endpoint supports order=asc|desc query parameter
  - EventLog component has Head/Tail view mode toggle
requires:
  []
affects:
  []
key_files:
  - backend/routers/pipeline.py
  - frontend/src/api/public-client.ts
  - frontend/src/pages/AdminPipeline.tsx
  - frontend/src/App.css
key_decisions:
  - Used explicit string validation with 400 response for order param rather than FastAPI Literal/Enum, consistent with existing endpoint param style
  - Placed segmented toggle between event count and refresh button in the header row for natural scan order
patterns_established:
  - (none)
observability_surfaces:
  - none
drill_down_paths:
  - .gsd/milestones/M006/slices/S02/tasks/T01-SUMMARY.md
  - .gsd/milestones/M006/slices/S02/tasks/T02-SUMMARY.md
duration: ""
verification_result: passed
completed_at: 2026-03-30T11:16:39.374Z
blocker_discovered: false
---

# S02: Pipeline Page: Head/Tail Log View + Token Count

**Added Head/Tail toggle to pipeline event log — Head shows oldest events first (asc), Tail shows newest (desc) — with backend `order` query parameter, segmented toggle UI, and preserved token count display.**

## What Happened

Two-task slice adding chronological viewing to the pipeline event log.

**T01 (Backend):** Added `order` query parameter (asc/desc, default desc) to `GET /admin/pipeline/events/{video_id}`. Explicit string validation returns 400 for invalid values. Default remains desc for backward compatibility. Deployed and verified against live API on ub01.

**T02 (Frontend):** Added `viewMode` state (head/tail) to the EventLog component with a segmented toggle button UI. Head passes `order=asc`, Tail passes `order=desc`. Switching mode resets pagination offset to 0. API client updated to pass the `order` param. Segmented button CSS uses existing CSS custom properties. Token counts per-event and per-video remain visible and unchanged.

The slice is intentionally minimal — two files touched on the backend, three on the frontend. No schema changes, no new models, no new dependencies.

## Verification

All slice-level verification checks passed:

1. **order=asc** — `curl 'http://ub01:8096/api/v1/admin/pipeline/events/{vid}?order=asc&limit=3'` returns events with ascending timestamps (earliest: 2026-03-30T09:39:36, stage2_segmentation start)
2. **order=desc** — Same endpoint with `order=desc` returns most recent events first (latest: 2026-03-30T10:34:31, stage5_synthesis complete)
3. **order=invalid** — Returns HTTP 400
4. **No order param** — Defaults to desc (backward compatible)
5. **Frontend build** — `npm run build` exits 0, zero TypeScript errors, 786ms build time
6. **Token counts** — API response includes prompt_tokens, completion_tokens, total_tokens on llm_call events (confirmed in asc/desc responses)

## Requirements Advanced

None.

## Requirements Validated

None.

## New Requirements Surfaced

None.

## Requirements Invalidated or Re-scoped

None.

## Deviations

None.

## Known Limitations

None.

## Follow-ups

None.

## Files Created/Modified

- `backend/routers/pipeline.py` — Added order query parameter (asc/desc, default desc) to list_pipeline_events with validation and dynamic ordering
- `frontend/src/api/public-client.ts` — Added order param to fetchPipelineEvents params type and URL builder
- `frontend/src/pages/AdminPipeline.tsx` — Added viewMode state, Head/Tail segmented toggle, order param wiring, and pagination reset on mode switch
- `frontend/src/App.css` — Added segmented toggle button CSS (.pipeline-events__view-toggle, .pipeline-events__view-btn)
