digraph data_model {
rankdir=LR
bgcolor="#0a0e17"
fontname="Helvetica"
node [fontname="Helvetica" fontsize=11 shape=plaintext]
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
label="Data Model"
labelloc=t
fontsize=16
fontcolor="#0066ff"
MediaAsset [label=<
| MediaAsset |
| id | UUID PK |
| filename | str |
| file_path | str (relative) |
| duration / fps / size | probe metadata |
>]
Profile [label=<
| Profile |
| name | str |
| pipeline | JSONB topology |
| configs | JSONB per-stage |
>]
Timeline [label=<
| Timeline |
| id | UUID PK |
| source_asset_id | FK MediaAsset |
| chunk_paths | str[] |
| profile_name | str |
| fps / status | cached, ready, ... |
>]
Job [label=<
| Job |
| id | UUID PK |
| timeline_id | FK Timeline |
| parent_id | FK Job (replay tree) |
| profile_name | str |
| config_overrides | JSONB |
| run_type | initial / replay / retry |
| status / current_stage | runtime |
>]
Checkpoint [label=<
| Checkpoint |
| id | UUID PK |
| timeline_id | FK Timeline |
| job_id | FK Job (nullable) |
| parent_id | FK Checkpoint (tree) |
| stage_name | str |
| config_overrides / stats | JSONB (no blobs) |
>]
StageOutput [label=<
| StageOutput |
| id | UUID PK |
| job_id | FK Job |
| timeline_id | FK Timeline |
| stage_name | str |
| checkpoint_id | FK Checkpoint (nullable) |
| output | JSONB (flat upsert) |
>]
Brand [label=<
| Brand |
| canonical_name | str (indexed) |
| aliases | str[] |
| source | ocr / local_vlm / cloud_llm / manual |
| airings | JSONB[] |
>]
MediaAsset -> Timeline [label="source_asset_id"]
Timeline -> Job [label="timeline_id"]
Job -> Job [label="parent_id\n(replay tree)" style=dashed]
Profile -> Job [label="profile_name" color="#0066ff"]
Job -> Checkpoint [label="job_id"]
Timeline -> Checkpoint [label="timeline_id"]
Checkpoint -> Checkpoint [label="parent_id\n(tree)" style=dashed]
Job -> StageOutput [label="job_id"]
Checkpoint -> StageOutput [label="checkpoint_id" style=dotted]
}