Skip to content

Data Models

Engram uses SQLModel for database models, combining SQLAlchemy's ORM with Pydantic's validation.

DiscJob

The central model tracking a disc ripping job through its lifecycle.

app.models.disc_job.DiscJob

Bases: SQLModel

Represents a disc ripping job with full state tracking.

Key Fields

Field Type Description
id int Primary key
drive_id str Drive letter or device path (e.g., E:, /dev/sr0)
volume_label str Disc volume label (e.g., THE_OFFICE_S1)
content_type ContentType tv, movie, or unknown
state JobState Current state in the lifecycle
detected_title str Classified title (e.g., "The Office")
detected_season int Season number for TV shows
classification_source str heuristic, tmdb, or discdb_*
classification_confidence float 0.0 to 1.0
content_hash str TheDiscDB MD5 fingerprint
discdb_mappings_json str Persisted DiscDB title-to-episode mappings
error_message str Error reason if job failed
created_at datetime When the job was created
completed_at datetime When the job reached a terminal state
cleared_at datetime Soft-delete timestamp (hidden from dashboard, still in history)

DiscTitle

Individual title (track) on a disc, linked to a job.

app.models.disc_job.DiscTitle

Bases: SQLModel

Individual title (track) on a disc.

Key Fields

Field Type Description
id int Primary key
job_id int Foreign key to DiscJob
title_index int MakeMKV title index
duration_seconds int Track duration
file_size_bytes int File size
state TitleState Current title state
matched_episode str Matched episode code (e.g., S01E01)
match_confidence float Match confidence score
video_resolution str e.g., 4K, 1080p, 480p
edition str e.g., Extended, Director's Cut
organized_to str Final library path after organization
is_extra bool Whether organized as extra content

Enums

JobState

app.models.disc_job.JobState

Bases: StrEnum

States in the disc processing lifecycle.

Source code in backend/app/models/disc_job.py
class JobState(StrEnum):
    """States in the disc processing lifecycle."""

    IDLE = "idle"
    IDENTIFYING = "identifying"  # Scanning disc structure
    REVIEW_NEEDED = "review_needed"  # Human-in-the-Loop trigger
    RIPPING = "ripping"  # Active extraction
    MATCHING = "matching"  # Audio fingerprinting
    ORGANIZING = "organizing"  # Moving files to library
    COMPLETED = "completed"
    FAILED = "failed"

COMPLETED = 'completed' class-attribute instance-attribute

FAILED = 'failed' class-attribute instance-attribute

IDENTIFYING = 'identifying' class-attribute instance-attribute

IDLE = 'idle' class-attribute instance-attribute

MATCHING = 'matching' class-attribute instance-attribute

ORGANIZING = 'organizing' class-attribute instance-attribute

REVIEW_NEEDED = 'review_needed' class-attribute instance-attribute

RIPPING = 'ripping' class-attribute instance-attribute

ContentType

app.models.disc_job.ContentType

Bases: StrEnum

Type of content on the disc.

Source code in backend/app/models/disc_job.py
class ContentType(StrEnum):
    """Type of content on the disc."""

    TV = "tv"
    MOVIE = "movie"
    UNKNOWN = "unknown"

MOVIE = 'movie' class-attribute instance-attribute

TV = 'tv' class-attribute instance-attribute

UNKNOWN = 'unknown' class-attribute instance-attribute

TitleState

app.models.disc_job.TitleState

Bases: StrEnum

State of an individual title.

Source code in backend/app/models/disc_job.py
class TitleState(StrEnum):
    """State of an individual title."""

    PENDING = "pending"
    RIPPING = "ripping"
    MATCHING = "matching"
    MATCHED = "matched"  # Intermediate state: matched but not yet organized
    REVIEW = "review"  # Ripped successfully but needs human review for episode assignment
    COMPLETED = "completed"
    FAILED = "failed"

COMPLETED = 'completed' class-attribute instance-attribute

FAILED = 'failed' class-attribute instance-attribute

MATCHED = 'matched' class-attribute instance-attribute

MATCHING = 'matching' class-attribute instance-attribute

PENDING = 'pending' class-attribute instance-attribute

REVIEW = 'review' class-attribute instance-attribute

RIPPING = 'ripping' class-attribute instance-attribute

AppConfig

Persisted application configuration, stored in the app_config table.

app.models.AppConfig

Bases: SQLModel

User-configurable application settings stored in database.

Configuration includes paths (staging, library, MakeMKV, FFmpeg), API keys (TMDB, MakeMKV license), matching parameters, ripping coordination settings, staging cleanup policy, extras policy, and naming conventions.