Current State
Snapshot
The backend is a FastAPI application with SQLite persistence and inline execution for all workflows. It provides 11 API route modules covering health, assets, episodes, conversions, configs, jobs, outputs, tags, dashboard, and visualization.
All primary workflows are functional end-to-end.
API Surface
Health
GET /health
Assets
| Method | Route | Description |
|---|---|---|
| POST | /assets/register | Register asset by file path |
| POST | /assets/upload | Upload raw file |
| POST | /assets/register-dialog | Native file dialog registration |
| POST | /assets/scan-directory | Scan directory for supported files |
| POST | /assets/{asset_id}/index | Trigger indexing via hephaes.Profiler |
| POST | /assets/reindex-all | Bulk reindex all assets |
| GET | /assets | List with filters (search, tag, file type, status, duration, start-time) |
| GET | /assets/{asset_id} | Asset detail with indexed metadata |
| GET | /assets/{asset_id}/episodes | List episodes for asset |
Tags
| Method | Route | Description |
|---|---|---|
| GET | /tags | List tag catalog with asset counts |
| POST | /tags | Create tag |
| POST | /assets/{asset_id}/tags | Attach tag to asset |
| DELETE | /assets/{asset_id}/tags/{tag_id} | Detach tag from asset |
Episodes and Replay
| Method | Route | Description |
|---|---|---|
| GET | /assets/{asset_id}/episodes/{episode_id} | Episode detail |
| GET | /assets/{asset_id}/episodes/{episode_id}/timeline | Bucketed timeline data for scrubber |
| GET | /assets/{asset_id}/episodes/{episode_id}/samples | Sample windows around timestamp |
| WS | /assets/{asset_id}/episodes/{episode_id}/replay | Realtime replay (hello, seek, play, pause, set_speed, set_streams) |
Conversions
| Method | Route | Description |
|---|---|---|
| POST | /conversions | Execute conversion (inline spec, legacy fields, or saved config reference) |
| GET | /conversions | List conversions with filters (including by image payload contract) |
| GET | /conversions/{conversion_id} | Conversion detail with representation policy |
| GET | /conversions/capabilities | Backend capability metadata (policy version, defaults, supported contracts) |
| POST | /conversions/inspect | Inspect asset topics via hephaes |
| POST | /conversions/draft | Generate draft conversion spec |
| POST | /conversions/preview | Preview sample conversion output |
Conversion Configs
| Method | Route | Description |
|---|---|---|
| GET | /conversion-configs | List saved configs |
| POST | /conversion-configs | Create saved config |
| GET | /conversion-configs/{config_id} | Config detail with migration notes |
| PATCH | /conversion-configs/{config_id} | Update config |
| POST | /conversion-configs/{config_id}/duplicate | Duplicate config |
Saved configs persist JSON-backed spec payloads with immutable revision history. Configs migrate on load through hephaes and surface upgrade notes in responses.
Jobs
| Method | Route | Description |
|---|---|---|
| GET | /jobs | List jobs with type/status filters |
| GET | /jobs/{job_id} | Job detail with effective representation policy for conversion jobs |
Job types: index, convert, prepare_visualization. Statuses: queued, running, succeeded, failed.
Outputs
| Method | Route | Description |
|---|---|---|
| GET | /outputs | List with filters (format, role, asset, conversion, availability) |
| GET | /outputs/{output_id} | Output detail with manifest summary |
| GET | /outputs/{output_id}/content | Serve output file content |
| POST | /outputs/{output_id}/actions | Trigger output action |
| GET | /outputs/{output_id}/actions | List actions for output |
| GET | /output-actions/{action_id} | Action detail |
Output roles: datasets, manifests, reports, sidecars. Only refresh_metadata action is implemented end-to-end. Parquet metadata inspection available via pyarrow.
Dashboard
| Method | Route | Description |
|---|---|---|
| GET | /dashboard/summary | Aggregate counts and freshness timestamps |
| GET | /dashboard/trends | Per-day trend buckets (configurable 1-90 day window) |
| GET | /dashboard/blockers | Failed/missing state counts |
Visualization
| Method | Route | Description |
|---|---|---|
| POST | /assets/{asset_id}/episodes/{episode_id}/prepare-visualization | Generate cached Rerun .rrd |
| GET | /assets/{asset_id}/episodes/{episode_id}/viewer-source | Viewer-source manifest for frontend |
| Static | /visualizations/... | Serve prepared visualization files |
Cache reuse when matching artifact exists. Cache invalidation when viewer or recording versions change.
Persistence Model
SQLite database with SQLAlchemy 2.0 declarative ORM. Tables:
| Table | Description |
|---|---|
assets | Registered files with indexing status (pending/indexing/indexed/failed) |
asset_metadata | Indexed content (duration, topics, message counts, sensor types) |
tags | User-defined labels with normalized names |
asset_tags | Many-to-many asset/tag join |
jobs | Durable job records with type, status, timestamps |
conversions | Conversion runs with source IDs, config snapshots, output paths |
conversion_configs | Reusable spec-based templates |
conversion_config_revisions | Immutable config change history |
conversion_draft_revisions | Draft workflow data with status tracking |
output_artifacts | Output files with role, format, availability |
output_actions | Post-processing actions on outputs |
All tables use UUID primary keys and timezone-aware UTC timestamps.
Tests
17 test modules under tests/ using pytest with httpx for async HTTP testing:
- Asset registration, listing, filtering, and indexing
- Conversion CRUD, execution, and authoring workflows
- Conversion config persistence and revision management
- Authoring request/response contracts
- Episode playback and streaming
- Dashboard summary, trends, and blockers
- Visualization preparation
- Job tracking and querying
- Output artifact management and filtering
- Tag creation and assignment
- Image payload contract integration
Known Limitations
- Conversion execution runs inline in the request path — no worker queue for long-running jobs
- Only
refresh_metadataoutput action is implemented; other action types are not yet supported - The frontend replay route does not yet use the backend viewer-source / cached
.rrdflow - Some asset list filters (file size, registration date) are applied client-side in the frontend rather than in backend queries