"""Add media_assets table. Revision ID: 040 Revises: 039 """ import sqlalchemy as sa from alembic import op from sqlalchemy.dialects.postgresql import UUID, JSONB revision = '040' down_revision = '039' branch_labels = None depends_on = None def upgrade(): # Create enum type op.execute( "CREATE TYPE media_asset_type AS ENUM (" "'thumbnail','still','turntable','stl_low','stl_high'," "'gltf_geometry','gltf_production','blend_production')" ) op.create_table( 'media_assets', sa.Column('id', UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), sa.Column('tenant_id', UUID(as_uuid=True), sa.ForeignKey('tenants.id', ondelete='CASCADE'), nullable=True), sa.Column('product_id', UUID(as_uuid=True), sa.ForeignKey('products.id', ondelete='CASCADE'), nullable=True), sa.Column('cad_file_id', UUID(as_uuid=True), sa.ForeignKey('cad_files.id', ondelete='SET NULL'), nullable=True), sa.Column('order_line_id', UUID(as_uuid=True), sa.ForeignKey('order_lines.id', ondelete='SET NULL'), nullable=True), sa.Column('workflow_run_id', UUID(as_uuid=True), sa.ForeignKey('workflow_runs.id', ondelete='SET NULL'), nullable=True), sa.Column( 'asset_type', sa.Enum( 'thumbnail', 'still', 'turntable', 'stl_low', 'stl_high', 'gltf_geometry', 'gltf_production', 'blend_production', name='media_asset_type', ), nullable=False, ), sa.Column('storage_key', sa.Text, nullable=False), sa.Column('file_size_bytes', sa.BigInteger, nullable=True), sa.Column('mime_type', sa.String(100), nullable=True), sa.Column('width', sa.Integer, nullable=True), sa.Column('height', sa.Integer, nullable=True), sa.Column('duration_s', sa.Float, nullable=True), sa.Column('render_config', JSONB, nullable=True), sa.Column('is_archived', sa.Boolean, nullable=False, server_default='false'), sa.Column('created_at', sa.DateTime, nullable=False, server_default=sa.text('NOW()')), ) op.create_index('ix_media_assets_product', 'media_assets', ['product_id']) op.create_index('ix_media_assets_tenant', 'media_assets', ['tenant_id']) op.create_index('ix_media_assets_order_line', 'media_assets', ['order_line_id']) op.create_index('ix_media_assets_asset_type', 'media_assets', ['asset_type']) # RLS op.execute("ALTER TABLE media_assets ENABLE ROW LEVEL SECURITY") op.execute( """CREATE POLICY tenant_isolation ON media_assets USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid)""" ) op.execute( """CREATE POLICY admin_bypass ON media_assets USING (current_setting('app.current_tenant_id', true) = 'bypass')""" ) def downgrade(): op.drop_table('media_assets') op.execute("DROP TYPE IF EXISTS media_asset_type")