"""coupon_prompt_engagement 频控加 package 维度(美团/淘宝/京东各自独立弹)

Revision ID: coupon_engage_per_package
Revises: store_mapping_jd_cols
Create Date: 2026-06-14 11:00:00.000000

需求:领券引导窗按 (device, App, 自然日) 频控——在美团弹过/领过,不影响淘宝、京东今天
仍各弹一次。原表唯一键是 (device_id, engage_date),缺 package → 任一 App 弹过就把整台
设备当天标记 engage,其余 App 被压住不弹(bug)。

本迁移:
  1. 加 package 列(NOT NULL,旧行用 server_default "" 填占位,不影响新逻辑判断)。
  2. 旧唯一约束 (device_id, engage_date) → 新 (device_id, package, engage_date)。

SQLite 不支持直接 drop/add 约束,用 batch_alter_table(建临时表 + 拷数据 + 换名,
与 store_mapping_* 同款)。
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'coupon_engage_per_package'
down_revision: Union[str, Sequence[str], None] = 'store_mapping_jd_cols'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    with op.batch_alter_table('coupon_prompt_engagement', schema=None) as batch_op:
        # 加 package 列。旧行(改造前的全局记录)填 "" 占位:它们对应的是"老的全局态",
        # 新逻辑按 (device, package, 日) 判,占位 "" 不会与真实包名(com.xxx)碰撞。
        batch_op.add_column(
            sa.Column('package', sa.String(length=64), nullable=False, server_default='')
        )
        # 旧唯一约束 (device_id, engage_date) → 新三元组 (device_id, package, engage_date)。
        batch_op.drop_constraint('uq_coupon_engage_device_date', type_='unique')
        batch_op.create_unique_constraint(
            'uq_coupon_engage_device_pkg_date',
            ['device_id', 'package', 'engage_date'],
        )


def downgrade() -> None:
    with op.batch_alter_table('coupon_prompt_engagement', schema=None) as batch_op:
        batch_op.drop_constraint('uq_coupon_engage_device_pkg_date', type_='unique')
        batch_op.create_unique_constraint(
            'uq_coupon_engage_device_date',
            ['device_id', 'engage_date'],
        )
        batch_op.drop_column('package')
