feat(ad-revenue): 领券/比价看板逐次广告收益(ad_ecpm.trace_id + 逐页聚合) #131

Merged
guke merged 6 commits from feat/per-session-ad-revenue into main 2026-07-10 22:14:01 +08:00
Member

背景

admin「领券数据」「比价记录」两个看板此前只能看到场景级(所有领券/比价)的广告收益,
无法定位「这一次领券/比价具体赚了多少」。根因:收益表 ad_ecpm_recordtrace_id,
无法与领券会话 / 比价记录按 trace 关联。

改动

  • 模型/迁移:ad_ecpm_record 新增 trace_id(String(64), index, nullable);
    迁移 ad_ecpm_trace_id 加列 + 索引 ix_ad_ecpm_record_trace_id,并收敛当前两个
    alembic head
    (11c44afbea58 selfstat + merge_pages_override_coupon_slot)为单 head。
  • 上报链路:EcpmReportIntrace_id 字段;/api/v1/ad/ecpm-report 透传;
    create_ecpm_record 落库。
  • 收益聚合:新增 revenue_yuan_by_trace(db, trace_ids)——按 trace_id 聚合展示收益,
    单条 = min(eCPM元, ¥500钳顶)/1000,与广告收益报表 ad_revenue.py 同口径;
    只吃当前页的 trace_id(逐页批量,索引命中,无 N+1)。
  • 两个看板:CouponDataRow / AdminComparisonListItemad_revenue_yuan;
    coupon_data_report(主表 + 用户抽屉)与 list_comparison_records 分页后逐页补该字段。
  • 测试:tests/test_ad_ecpm_trace_revenue.py(聚合/钳顶/落库)、
    tests/test_board_ad_revenue.py(两看板 + 抽屉)。
## 背景 admin「领券数据」「比价记录」两个看板此前只能看到场景级(所有领券/比价)的广告收益, 无法定位「这一次领券/比价具体赚了多少」。根因:收益表 `ad_ecpm_record` 缺 `trace_id`, 无法与领券会话 / 比价记录按 trace 关联。 ## 改动 - **模型/迁移**:`ad_ecpm_record` 新增 `trace_id`(String(64), index, nullable); 迁移 `ad_ecpm_trace_id` 加列 + 索引 `ix_ad_ecpm_record_trace_id`,并**收敛当前两个 alembic head**(`11c44afbea58` selfstat + `merge_pages_override_coupon_slot`)为单 head。 - **上报链路**:`EcpmReportIn` 增 `trace_id` 字段;`/api/v1/ad/ecpm-report` 透传; `create_ecpm_record` 落库。 - **收益聚合**:新增 `revenue_yuan_by_trace(db, trace_ids)`——按 trace_id 聚合展示收益, 单条 = `min(eCPM元, ¥500钳顶)/1000`,与广告收益报表 `ad_revenue.py` **同口径**; 只吃当前页的 trace_id(逐页批量,索引命中,无 N+1)。 - **两个看板**:`CouponDataRow` / `AdminComparisonListItem` 增 `ad_revenue_yuan`; `coupon_data_report`(主表 + 用户抽屉)与 `list_comparison_records` 分页后逐页补该字段。 - **测试**:`tests/test_ad_ecpm_trace_revenue.py`(聚合/钳顶/落库)、 `tests/test_board_ad_revenue.py`(两看板 + 抽屉)。
guke added 6 commits 2026-07-10 17:09:38 +08:00
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- AdEcpmRecord 新增 trace_id(String 64, index, nullable)列,与 ad_feed_reward_record 一致
- 迁移 ad_ecpm_trace_id:ADD COLUMN + CREATE INDEX,同时收敛双 head
  (11c44afbea58 selfstat + merge_pages_override_coupon_slot → 单 head)
- EcpmReportIn.trace_id 字段透传客户端本场比价/领券 session ID
- create_ecpm_record 新增 trace_id 参数并落库
- ecpm_report 端点 forward payload.trace_id 到 repository

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
三个测试覆盖:
- 同一 trace 多条 eCPM 求和 + min(eCPM元, ¥500)/1000 钳顶
- 空 trace 列表直接返回 {}(避免 IN () 非法)
- create_ecpm_record 落 trace_id 持久化验证

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
按本页 trace_id 一次性聚合 ad_ecpm_record 展示收益(元),挂到领券数据
看板明细行(dict 字段)与比价记录列表项(ORM 瞬态属性),防 N+1 范式与
现有 _attach_user_info / _ad_coins_by_trace 一致。

- CouponDataRow: 新增 ad_revenue_yuan: float = 0.0 字段
- AdminComparisonListItem: 新增 ad_revenue_yuan: float = 0.0 字段
- coupon_data.py: _session_to_row 增 ad_revenue_yuan 参数;coupon_data_report
  在分页后调用 crud_ecpm.revenue_yuan_by_trace 按本页批量聚合
- queries.py: list_comparison_records 在 _attach_user_info 后瞬态挂 ad_revenue_yuan
- 新增 tests/test_board_ad_revenue.py:两个看板各一个集成测试

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
guke merged commit 930eff822c into main 2026-07-10 22:14:01 +08:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: WonderableAI/shaguabijia-app-server#131