"""Where an image came from, and what has been marked on it `source` is the citation as it should be read — figure, authors, publication, licence — and `source_url` is where to check it. `overlay` holds the regions an educator has marked on the image, as vector shapes in normalised coordinates so they land in the right place at any size. Both on the asset rather than typed into each caption: the same figure used in three articles is cited the same way in all three, and a licence that turns out to be wrong is one row to fix rather than three paragraphs to find. Revision ID: l2c3d4e5f6a7 Revises: k1b2c3d4e5f6 """ import sqlalchemy as sa from alembic import op revision = "l2c3d4e5f6a7" down_revision = "k1b2c3d4e5f6" branch_labels = None depends_on = None COLUMNS = { "source": sa.Column("source", sa.Text(), nullable=True), "source_url": sa.Column("source_url", sa.String(length=600), nullable=True), # Vector shapes in normalised coordinates, not a second raster: an overlay # has to be switchable, correctable and correct at any size. "overlay": sa.Column("overlay", sa.JSON(), nullable=True), } def upgrade() -> None: existing = {column["name"] for column in sa.inspect(op.get_bind()).get_columns("media_assets")} for name, column in COLUMNS.items(): if name not in existing: op.add_column("media_assets", column) def downgrade() -> None: for name in COLUMNS: op.drop_column("media_assets", name)