"""image_asset.variant_label String(32) → String(255).

PID 0bb48ebf E2E에서 chain_bg group_id 패턴 'night_body_blood_curtain_red_circle'
(35자) → varchar(32) StringDataRightTruncation → INSERT 실패 → DB 0 row → 다운스트림
scene_image_pipeline 도미노 실패. 003에서 8→32로 확장했지만 여전히 부족.

255는 group_id가 LLM 생성 라벨(`location_axis1_axis2_axis3_axisN`)이라 길이 분포의
상한이 동적이므로 안전한 한도.

Revision ID: 004_variant_label_extend
Revises: 003_resume_integrity
Create Date: 2026-05-02
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


revision: str = "004_variant_label_extend"
down_revision: Union[str, None] = "003_resume_integrity"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    op.alter_column(
        "image_asset",
        "variant_label",
        type_=sa.String(length=255),
        existing_type=sa.String(length=32),
        existing_nullable=False,
        existing_server_default="v00",
    )


def downgrade() -> None:
    """WARNING: 32자 초과 row가 있으면 잘림(데이터 손실). 사전 검증 후 abort.

    Rollback 전 다음 SQL 로 안전성 확인:
        SELECT COUNT(*) FROM image_asset WHERE LENGTH(variant_label) > 32;
    이 카운트가 0이면 안전. 0이 아니면 manual cleanup 후 다시 시도.
    """
    bind = op.get_bind()
    over_count = bind.execute(
        sa.text("SELECT COUNT(*) FROM image_asset WHERE LENGTH(variant_label) > 32")
    ).scalar()
    if over_count and int(over_count) > 0:
        raise RuntimeError(
            f"alembic 004 downgrade aborted: {over_count} image_asset rows have "
            f"variant_label > 32 chars. Manual cleanup required before downgrade."
        )
    op.alter_column(
        "image_asset",
        "variant_label",
        type_=sa.String(length=32),
        existing_type=sa.String(length=255),
        existing_nullable=False,
        existing_server_default="v00",
    )
