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

# T04: Wire ingest-to-pipeline trigger and add manual re-trigger endpoint

Connect the existing ingest endpoint to the pipeline by dispatching `run_pipeline.delay()` after successful commit, and add a manual re-trigger API endpoint for re-processing videos.

## Steps

1. Modify `backend/routers/ingest.py`:
   - After the `await db.commit()` and refresh calls (after the successful response is ready), dispatch the pipeline: `from pipeline.stages import run_pipeline; run_pipeline.delay(str(video.id))`
   - Wrap the dispatch in try/except to avoid failing the ingest response if Redis/Celery is down — log WARNING on dispatch failure
   - The dispatch must happen AFTER commit so the worker can find the data in PostgreSQL

2. Create `backend/routers/pipeline.py`:
   - Router with `prefix='/pipeline'`, tag `['pipeline']`
   - `POST /trigger/{video_id}`: Look up SourceVideo by id, verify it exists (404 if not), dispatch `run_pipeline.delay(str(video_id))`, return `{"status": "triggered", "video_id": str(video_id), "current_processing_status": video.processing_status.value}`
   - Uses `get_session` dependency for DB access

3. Mount the pipeline router in `backend/main.py` under `/api/v1`.

## Must-Haves

- [ ] Ingest endpoint dispatches run_pipeline.delay() after commit
- [ ] Pipeline dispatch failure does not fail the ingest response
- [ ] POST /api/v1/pipeline/trigger/{video_id} exists and returns status
- [ ] 404 returned for non-existent video_id
- [ ] Pipeline router mounted in main.py

## Verification

- `cd backend && python -c "from routers.pipeline import router; print([r.path for r in router.routes])"` shows `['/trigger/{video_id}']`
- `grep -q 'pipeline' backend/main.py` exits 0
- `grep -q 'run_pipeline' backend/routers/ingest.py` exits 0

## Inputs

- ``backend/routers/ingest.py` — existing ingest endpoint to add pipeline dispatch to`
- ``backend/main.py` — existing app to mount new router`
- ``backend/pipeline/stages.py` — run_pipeline task from T02`
- ``backend/models.py` — SourceVideo model for lookup`

## Expected Output

- ``backend/routers/ingest.py` — updated with run_pipeline.delay() dispatch after commit`
- ``backend/routers/pipeline.py` — new router with POST /trigger/{video_id} endpoint`
- ``backend/main.py` — updated with pipeline router mount`

## Verification

cd backend && python -c "from routers.pipeline import router; print([r.path for r in router.routes])" && grep -q 'pipeline' backend/main.py && grep -q 'run_pipeline' backend/routers/ingest.py
