288766443a
从最新 origin/main 重拉的干净分支,只含本人记账改动,不含 marco 的归因订单(order_record)——后者是另一条未合并分支 feat/user-order-records 的功能,此前被误用 git add -A 和记账混进了 feat/savings-accounting-m1。本分支不带它:savings_record 升级为唯一真相表(新增原价/比价价/支付渠道/源平台/幂等键等列,迁移 savings_report_fields 直接挂 f01db5d77dac、不经 order_record_table);/order/report 改写 savings_record(source='compare'),省额=源平台原价−实付;展示 /api/v1/savings/* 真实优先 demo 兜底。无 order_record 的 model/repo/迁移/路由。alembic 单一 head + pytest 54 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: xianze <ze@192.168.0.138> Reviewed-on: #10 Co-authored-by: zhangxianze <zhangxianze@wonderable.ai> Co-committed-by: zhangxianze <zhangxianze@wonderable.ai>
50 lines
2.3 KiB
Python
50 lines
2.3 KiB
Python
"""savings_record:真实比价上报字段 + (user_id, client_event_id) 幂等唯一约束
|
|
|
|
把 savings_record 升级为「记账唯一真相表」:真实上报(source='compare')写入
|
|
原价/比价价/支付渠道/平台包名/源平台名/源链接/幂等键/device_id;
|
|
demo seeder 行(source='demo')这些列均为 NULL。
|
|
|
|
Revision ID: savings_report_fields
|
|
Revises: f01db5d77dac
|
|
Create Date: 2026-05-31 19:00:00.000000
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = 'savings_report_fields'
|
|
down_revision: Union[str, Sequence[str], None] = 'f01db5d77dac'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
with op.batch_alter_table('savings_record', schema=None) as batch_op:
|
|
batch_op.add_column(sa.Column('original_price_cents', sa.Integer(), nullable=True))
|
|
batch_op.add_column(sa.Column('compared_price_cents', sa.Integer(), nullable=True))
|
|
batch_op.add_column(sa.Column('pay_channel', sa.String(length=16), nullable=True))
|
|
batch_op.add_column(sa.Column('platform_package', sa.String(length=128), nullable=True))
|
|
batch_op.add_column(sa.Column('source_platform_name', sa.String(length=32), nullable=True))
|
|
batch_op.add_column(sa.Column('source_deeplink', sa.String(length=512), nullable=True))
|
|
batch_op.add_column(sa.Column('client_event_id', sa.String(length=64), nullable=True))
|
|
batch_op.add_column(sa.Column('device_id', sa.String(length=128), nullable=True))
|
|
# (user_id, client_event_id) 幂等;demo 行 client_event_id 为 NULL 不冲突
|
|
batch_op.create_unique_constraint('uq_savings_user_event', ['user_id', 'client_event_id'])
|
|
|
|
|
|
def downgrade() -> None:
|
|
with op.batch_alter_table('savings_record', schema=None) as batch_op:
|
|
batch_op.drop_constraint('uq_savings_user_event', type_='unique')
|
|
batch_op.drop_column('device_id')
|
|
batch_op.drop_column('client_event_id')
|
|
batch_op.drop_column('source_deeplink')
|
|
batch_op.drop_column('source_platform_name')
|
|
batch_op.drop_column('platform_package')
|
|
batch_op.drop_column('pay_channel')
|
|
batch_op.drop_column('compared_price_cents')
|
|
batch_op.drop_column('original_price_cents')
|