from datetime import datetime from sqlalchemy import DateTime, ForeignKey, Integer, String, UniqueConstraint, func from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base class OrderRecord(Base): """归因订单记录。 客户端判定「比价完 5 分钟内 + 用户点了结果链接 + 支付金额与比价价相差 ≤1 元」成立时, 带 JWT 上报一条,视为用户经由我们下了一笔单。本表只做记录(不发金币,避免刷单风险)。 幂等:(user_id, client_event_id) 唯一。client_event_id 由客户端为每次归因生成 UUID, 重试/重复上报不会产生多条。 """ __tablename__ = "order_record" __table_args__ = ( UniqueConstraint("user_id", "client_event_id", name="uq_order_user_event"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column( Integer, ForeignKey("user.id"), index=True, nullable=False ) client_event_id: Mapped[str] = mapped_column(String(64), nullable=False) # 平台展示名(如 美团 / 淘宝闪购),来自比价结果 comparison_results.platform_name platform: Mapped[str] = mapped_column(String(32), nullable=False) platform_package: Mapped[str | None] = mapped_column(String(128), nullable=True) # 支付渠道:wechat / alipay(哪条支付通道检测到的支付成功) pay_channel: Mapped[str] = mapped_column(String(16), nullable=False) # 我们给出的(用户点击的那个平台的)比价价,单位分 compared_price_cents: Mapped[int] = mapped_column(Integer, nullable=False) # 实际支付金额,单位分 paid_amount_cents: Mapped[int] = mapped_column(Integer, nullable=False) device_id: Mapped[str | None] = mapped_column(String(128), nullable=True) source: Mapped[str] = mapped_column(String(32), nullable=False, default="attribution") created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False )