8fa55eec3e
bug: 弹窗 engagement 表只按 (device, 日) 全局记一条,美团弹过/领过就把整台设备当天 标记 engage,淘宝/京东被压住不弹。需求是美团/淘宝/京东各自独立、每日各弹一次。 改动: - model: CouponPromptEngagement 加 package 列,唯一约束 (device,日) → (device,package,日) - alembic: 新增迁移 coupon_engage_per_package(加列 + 改唯一约束, batch_alter_table) - repository: has_engaged_today / mark_engagement 加 package 维度;新增 reset_today_completion - api: should-show / dismiss 接收 package;coupon_step(step=0) 按 App 记 engagement; 补 /prompt/shown 接口(客户端一直在调但后端缺失, 原 404); 补 /completed-today/reset(开发设置全重置用, 解首页卡置灰) 验证: curl 端到端 —— 美团弹过后 should-show 美团=false 淘宝/京东=true; shown/reset/completion-reset 端点全 ok。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: no_gen_mu <liujianhishen@gmail.com> Reviewed-on: #52 Co-authored-by: liujiahui <liujiahui@wonderable.ai> Co-committed-by: liujiahui <liujiahui@wonderable.ai>
54 lines
2.3 KiB
Python
54 lines
2.3 KiB
Python
"""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')
|