Add watch providers (where to stream/rent/buy)
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
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
New TMDb integration end to end: append_to_response "watch/providers", normalizer parsing grouped by country/monetization type, a WatchProvider catalog entry (external-id keyed, same get_or_create pattern as Company/ Collection/Person) + polymorphic WatchProviderOffering table (new migration 0002), ingestion write (including provider logos via the existing Artwork table), and API exposure -- embedded on movie/series detail plus a dedicated /watch-providers sub-route, shaped to mirror TMDb's own response for easy porting. Note: this data comes from JustWatch via TMDb and carries its own attribution requirement separate from TMDb's general one -- flagged in docs/api.md, must be satisfied before showing this in the frontend. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
74ebad379a
commit
6c95e18aad
@@ -0,0 +1,61 @@
|
||||
"""watch providers
|
||||
|
||||
Revision ID: 0002_watch_providers
|
||||
Revises: 0001_initial_schema
|
||||
Create Date: 2026-09-06
|
||||
|
||||
Adds the where-to-watch tables (section 17, additive): a WatchProvider
|
||||
catalog entry (Netflix, Apple TV, etc. -- TMDb's own provider_id links in
|
||||
via the existing external_ids table, same pattern as Company/Collection/
|
||||
Person) and WatchProviderOffering, a polymorphic (entity_type, entity_id)
|
||||
table like release_dates, one row per (movie/series, country,
|
||||
monetization type, provider).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision: str = "0002_watch_providers"
|
||||
down_revision: str | None = "0001_initial_schema"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"watch_providers",
|
||||
sa.Column("id", sa.Uuid(), primary_key=True),
|
||||
sa.Column("name", sa.String(200), nullable=False),
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"watch_provider_offerings",
|
||||
sa.Column("id", sa.Uuid(), primary_key=True),
|
||||
sa.Column("entity_type", sa.String(30), nullable=False),
|
||||
sa.Column("entity_id", sa.Uuid(), nullable=False),
|
||||
sa.Column("country_code", sa.String(2), sa.ForeignKey("countries.code"), nullable=False),
|
||||
sa.Column("monetization_type", sa.String(20), nullable=False),
|
||||
sa.Column(
|
||||
"watch_provider_id",
|
||||
sa.Uuid(),
|
||||
sa.ForeignKey("watch_providers.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("display_priority", sa.Integer(), nullable=True),
|
||||
sa.Column("link", sa.Text(), nullable=True),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_watch_provider_offerings_entity",
|
||||
"watch_provider_offerings",
|
||||
["entity_type", "entity_id"],
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index("ix_watch_provider_offerings_entity", table_name="watch_provider_offerings")
|
||||
op.drop_table("watch_provider_offerings")
|
||||
op.drop_table("watch_providers")
|
||||
Reference in New Issue
Block a user