Video state machine

Generated from @energixer/shared's transition table — the same edges the guarded SQL transitions enforce. Terminal states: available, failed, timeout, expired, cancelled.

FromToCause
pending_uploaduploadedtus finish, byte-exact
pending_uploadexpiredupload-expiry sweep (1 h)
pending_uploadfailedsize mismatch at finish
uploadedqueuedenqueue (same request or crash-recovery requeue)
uploadedfailedsize mismatch at finish
queuedlockedworker claim (conditional UPDATE)
queuedtimeoutprocessing-timeout (15 min from queued_at)
lockedencodingfirst heartbeat
lockedqueuedlock expiry, retries left
lockedfailedretries exhausted
lockedtimeoutprocessing-timeout (15 min from queued_at)
encodingavailableworker complete
encodingqueuedfail/lock expiry, retries left
encodingfailedretries exhausted
encodingtimeoutprocessing-timeout (15 min from queued_at)
pending_uploadcancelledowner cancel / delete
uploadedcancelledowner cancel / delete
queuedcancelledowner cancel / delete
lockedcancelledowner cancel / delete
encodingcancelledowner cancel / delete

Mermaid source

Paste into any Mermaid renderer (GitHub renders it natively).

stateDiagram-v2
    pending_upload --> uploaded: tus finish, byte-exact
    pending_upload --> expired: upload-expiry sweep (1 h)
    pending_upload --> failed: size mismatch at finish
    uploaded --> queued: enqueue (same request or crash-recovery requeue)
    uploaded --> failed: size mismatch at finish
    queued --> locked: worker claim (conditional UPDATE)
    queued --> timeout: processing-timeout (15 min from queued_at)
    locked --> encoding: first heartbeat
    locked --> queued: lock expiry, retries left
    locked --> failed: retries exhausted
    locked --> timeout: processing-timeout (15 min from queued_at)
    encoding --> available: worker complete
    encoding --> queued: fail/lock expiry, retries left
    encoding --> failed: retries exhausted
    encoding --> timeout: processing-timeout (15 min from queued_at)
    pending_upload --> cancelled: owner cancel / delete
    uploaded --> cancelled: owner cancel / delete
    queued --> cancelled: owner cancel / delete
    locked --> cancelled: owner cancel / delete
    encoding --> cancelled: owner cancel / delete