Initial Aurora Core 0.1 implementation
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s

Production-grade media metadata backend per docs/aurora-core-spec.md:
Aurora-owned UUIDv7 identity system, normalized movie/TV/people/credits
schema, provider abstraction with a TMDb adapter, an idempotent async
ingestion pipeline (normalize -> match -> upsert -> provenance), a
Postgres FTS/trigram search layer, a stateless FastAPI v1 API with
Redis caching/rate-limiting, arq workers, dev/prod Docker Compose
topologies, unit + integration + load tests, CI, and architecture/
database/API/ERD documentation.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
NixReaper
2026-09-04 17:34:03 -05:00
co-authored by Claude Sonnet 5
commit c20df1c503
111 changed files with 10041 additions and 0 deletions
+201
View File
@@ -0,0 +1,201 @@
# Aurora Core — Entity-Relationship Diagram
This is the Core 0.1 schema (36 tables, see [database.md](database.md) for
column-level detail). Association/junction tables are drawn as relationships
directly where Mermaid supports it; a few many-to-many tables with their own
attributes (`movie_companies.role`, `credits.*`) are drawn as entities.
```mermaid
erDiagram
MOVIE ||--o{ MOVIE_ALTERNATE_TITLE : has
MOVIE ||--o{ MOVIE_SPOKEN_LANGUAGE : has
MOVIE ||--o{ MOVIE_PRODUCTION_COUNTRY : has
MOVIE ||--o{ RELEASE_DATE : has
MOVIE ||--o{ MOVIE_RECOMMENDATION : recommends
MOVIE }o--o{ GENRE : "movie_genres"
MOVIE }o--o{ KEYWORD : "movie_keywords"
MOVIE }o--o{ COMPANY : "movie_companies"
MOVIE }o--|| COLLECTION : "belongs to"
MOVIE ||--o{ CREDIT : "cast/crew"
MOVIE ||--o{ ARTWORK : "images"
MOVIE ||--o{ VIDEO : "trailers"
MOVIE ||--o{ EXTERNAL_ID : "provider refs"
SERIES ||--o{ SEASON : has
SEASON ||--o{ EPISODE : has
SERIES ||--o{ SERIES_ALTERNATE_TITLE : has
SERIES ||--o{ SERIES_SPOKEN_LANGUAGE : has
SERIES ||--o{ SERIES_PRODUCTION_COUNTRY : has
SERIES }o--o{ GENRE : "series_genres"
SERIES }o--o{ KEYWORD : "series_keywords"
SERIES }o--o{ COMPANY : "series_companies (network/studio)"
SERIES ||--o{ CREDIT : "cast/crew/creators"
SERIES ||--o{ ARTWORK : "images"
SERIES ||--o{ VIDEO : "trailers"
SERIES ||--o{ EXTERNAL_ID : "provider refs"
EPISODE ||--o{ CREDIT : "cast/guest stars/crew"
EPISODE ||--o{ ARTWORK : "stills"
EPISODE ||--o{ EXTERNAL_ID : "provider refs"
SEASON ||--o{ ARTWORK : "posters"
SEASON ||--o{ EXTERNAL_ID : "provider refs"
COLLECTION ||--o{ MOVIE : "collection_movies"
COLLECTION ||--o{ SERIES : "collection_series"
COLLECTION ||--o{ COLLECTION : "collection_relations"
COLLECTION ||--o{ ARTWORK : "images"
COMPANY ||--o{ COMPANY : "parent_company"
COMPANY ||--o{ ARTWORK : "logos"
COMPANY ||--o{ EXTERNAL_ID : "provider refs"
COMPANY }o--o| COUNTRY : "based in"
PERSON ||--o{ CREDIT : "credited on"
PERSON ||--o{ ARTWORK : "profile images"
PERSON ||--o{ EXTERNAL_ID : "provider refs"
PROVIDER ||--o{ PROVIDER_RECORD : "provenance"
PROVIDER ||--o{ INGESTION_JOB : "runs"
PROVIDER ||--o{ EXTERNAL_ID : "issues"
PROVIDER ||--o{ ARTWORK : "sourced"
PROVIDER ||--o{ VIDEO : "sourced"
PROVIDER ||--o{ CREDIT : "sourced"
INGESTION_JOB ||--o{ PROVIDER_RECORD : produces
COUNTRY ||--o{ CERTIFICATION : defines
RELEASE_DATE }o--o| CERTIFICATION : rated
MOVIE {
uuid id PK
string title
string sort_title
enum status
date primary_release_date
int runtime_minutes
uuid collection_id FK
uuid source_provider_id FK
}
SERIES {
uuid id PK
string title
enum status
date first_air_date
int number_of_seasons
}
SEASON {
uuid id PK
uuid series_id FK
int season_number
}
EPISODE {
uuid id PK
uuid season_id FK
uuid series_id FK
int episode_number
}
PERSON {
uuid id PK
string name
date birthday
string known_for_department
}
CREDIT {
uuid id PK
uuid person_id FK
string entity_type
uuid entity_id
string department
string job
string character
}
COMPANY {
uuid id PK
string name
enum company_type
uuid parent_company_id FK
}
COLLECTION {
uuid id PK
string name
string slug
}
GENRE {
uuid id PK
string name
}
KEYWORD {
uuid id PK
string name
}
ARTWORK {
uuid id PK
string entity_type
uuid entity_id
enum artwork_type
uuid provider_id FK
string original_url
}
VIDEO {
uuid id PK
string entity_type
uuid entity_id
enum video_type
uuid provider_id FK
string url
}
EXTERNAL_ID {
uuid id PK
string entity_type
uuid entity_id
uuid provider_id FK
string external_id
}
PROVIDER {
uuid id PK
string slug
string name
}
PROVIDER_RECORD {
uuid id PK
uuid provider_id FK
string entity_type
string external_id
uuid aurora_entity_id
enum match_confidence
jsonb raw_data
}
INGESTION_JOB {
uuid id PK
uuid provider_id FK
string job_type
enum status
string idempotency_key
}
COUNTRY {
string code PK
string name
}
CERTIFICATION {
uuid id PK
string country_code FK
string system
string rating
}
RELEASE_DATE {
uuid id PK
uuid entity_id
string country_code FK
date release_date
uuid certification_id FK
}
```
## Notes on the polymorphic tables
`CREDIT`, `ARTWORK`, `VIDEO`, `EXTERNAL_ID`, and `RELEASE_DATE` attach to more
than one entity type (movie, series, season, episode, person, company,
collection) via an `(entity_type, entity_id)` pair rather than a typed
foreign key. Postgres can't enforce referential integrity across a
polymorphic pair with a single `FOREIGN KEY`, so integrity there is enforced
by the repository/service layer (`app/repositories/polymorphic.py`), not the
schema. See [database.md](database.md#polymorphic-associations) for the
tradeoff.