"""Govern external creative resources, measurements, and action attestations. Revision ID: 20260909_0031 Revises: 20260909_0030 """ import sqlalchemy as sa from alembic import op revision = "20260909_0031" down_revision = "20260909_0030" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "external_creative_resources", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column( "project_id", sa.Uuid(), sa.ForeignKey("projects.id", ondelete="RESTRICT"), nullable=False, ), sa.Column("resource_ref", sa.String(255), nullable=False), sa.Column("workload", sa.String(16), nullable=False), sa.Column("provider_resource_id", sa.String(128), nullable=False), sa.Column("approved", sa.Boolean(), nullable=False, server_default=sa.false()), sa.Column("configured_vram_bytes", sa.BigInteger(), nullable=False), sa.Column("measured_peak_vram_bytes", sa.BigInteger()), sa.Column("measurement_count", sa.Integer(), nullable=False, server_default="0"), sa.Column( "updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now() ), sa.UniqueConstraint( "project_id", "resource_ref", "workload", "provider_resource_id", name="uq_external_creative_resource_binding", ), sa.CheckConstraint("configured_vram_bytes > 0", name="ck_external_resource_vram_positive"), ) op.create_index( "ix_external_creative_resources_project", "external_creative_resources", ["project_id", "approved"], ) op.create_table( "external_creative_action_attestations", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column( "allocation_id", sa.Uuid(), sa.ForeignKey("external_creative_allocations.id", ondelete="RESTRICT"), nullable=False, ), sa.Column("action", sa.String(64), nullable=False), sa.Column("before_vram_bytes", sa.BigInteger(), nullable=False), sa.Column("after_vram_bytes", sa.BigInteger(), nullable=False), sa.Column("observed_at", sa.DateTime(timezone=True), nullable=False), sa.Column("validated", sa.Boolean(), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now() ), sa.UniqueConstraint( "allocation_id", "action", name="uq_external_creative_action_attestation" ), sa.CheckConstraint( "before_vram_bytes >= 0 AND after_vram_bytes >= 0", name="ck_external_action_vram_nonnegative", ), ) op.create_table( "external_creative_profile_observations", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column( "allocation_id", sa.Uuid(), sa.ForeignKey("external_creative_allocations.id", ondelete="RESTRICT"), nullable=False, ), sa.Column("resource_ref", sa.String(255), nullable=False), sa.Column("provider_resource_id", sa.String(128), nullable=False), sa.Column("workload", sa.String(16), nullable=False), sa.Column("observed_peak_vram_bytes", sa.BigInteger(), nullable=False), sa.Column("reserved_vram_bytes", sa.BigInteger(), nullable=False), sa.Column("duration_ms", sa.BigInteger(), nullable=False), sa.Column("outcome", sa.String(16), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now() ), sa.UniqueConstraint( "allocation_id", name="uq_external_creative_profile_observation_allocation" ), sa.CheckConstraint( "observed_peak_vram_bytes > 0 AND reserved_vram_bytes > 0", name="ck_external_profile_vram_positive", ), sa.CheckConstraint( "duration_ms >= 0 AND duration_ms <= 604800000", name="ck_external_profile_duration" ), ) def downgrade() -> None: op.drop_table("external_creative_profile_observations") op.drop_table("external_creative_action_attestations") op.drop_index( "ix_external_creative_resources_project", table_name="external_creative_resources" ) op.drop_table("external_creative_resources")