feat(backend): F1-6 sprint2 #2 累计消费总额加入 sandbox_replay
新增指标(无 fdw_queries 原查询 + 0 现有调用方 + 无 thin wrapper),沿用 sprint 1/sprint2 #1 模式 @trace_service + @runtime_aware decorator + 显式 stat_date <= ctx.business_date 上界 + dws_member_consumption_summary .total_consume_amount 字段 items_sum 口径。 双口径数值验证 PASS(member=2799207087163141 黄先生,直接 Python 调用): - 4a live(today=2026-05-05): get_total_consume_amount=1252.65 - 4b sandbox=2026-04-20: get_total_consume_amount=999.99(walkthrough 测试快照) unit test sprint1+sprint2 累计 19/19 PASS,无回归。 记录 thin wrapper 决策原则到 spec §5.5(迁移辅助层,非常态架构; fdw_queries 长远退化纯 ETL 物理访问层,清理放收尾 sprint)。 注:#3 累计交易笔数因 spec §4 字段未明确(dws_order_summary vs total_visit_count)暂停,等 Neo 决断后继续。 详见 docs/audit/changes/2026-05-06__f1_6_sprint2_total_consume_amount.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -119,6 +119,35 @@ def get_member_balance(site_id: int, member_id: int) -> Decimal:
|
||||
- 建议:sandbox 模式下接受性能折衷;live 模式仍走原 dws 月度路径
|
||||
- 必要时可做 in-memory cache(business_date 不变时缓存命中)
|
||||
|
||||
### 5.5 thin wrapper 使用原则(2026-05-06 决策)
|
||||
|
||||
`fdw_queries.*` 中的 thin wrapper(转发到 `sandbox_replay.*`)是**迁移辅助层,不是常态架构**。决策树:
|
||||
|
||||
```
|
||||
Q1: fdw_queries 已有同名函数?
|
||||
└─ 没有 → 不写 thin wrapper(直接在 sandbox_replay 加新函数)
|
||||
└─ 有 → Q2
|
||||
|
||||
Q2: 业务方已经在调用 fdw_queries.X?
|
||||
└─ 没有 → 不写 thin wrapper(老函数直接删)
|
||||
└─ 有 → Q3
|
||||
|
||||
Q3: 改这些调用方的 import 风险大?
|
||||
└─ 改起来便宜(≤3 处) → 直接改 import,不写 thin wrapper
|
||||
└─ 改起来贵(多处 / 容易漏改) → 写 thin wrapper
|
||||
```
|
||||
|
||||
**对 Sprint 2 应用**:
|
||||
- #1 60d 消费(原有 + 2 处调用)→ 写 thin wrapper(已完成)
|
||||
- #2 累计消费总额 / #3 累计交易笔数 / #5 累计 GMV(原无 + 0 调用)→ 不写
|
||||
- #4 储值卡余额(原有 + 多处调用)→ 写 thin wrapper
|
||||
|
||||
**长远走向**:F1-6 全部迁完后,所有老调用方逐步改成 `from sandbox_replay import ...`,
|
||||
`fdw_queries.py` 退化成纯 ETL 物理访问层(`_fdw_context` + 直接 SQL helper),不再承载业务指标接口。
|
||||
thin wrapper 一次性清理可放到"sandbox_replay 收尾 sprint"(F1-7+ 或更晚,本 spec §11.5 待定)。
|
||||
|
||||
**新功能/新接口判断**:不要因为"风格一致"在 fdw_queries 加 0 调用方的空 thin wrapper(churn,违反改动最小化原则)。
|
||||
|
||||
## 六、阶段 B 前置依赖清单
|
||||
|
||||
| 依赖 | 来源 | 状态 |
|
||||
|
||||
@@ -77,11 +77,11 @@
|
||||
|
||||
| # | 指标 | 当前实现位置 | 目标迁移到 | 复杂度 | 状态 |
|
||||
|---|------|-------------|----------|------|------|
|
||||
| 1 | 60 天消费 | `fdw_queries.get_consumption_60d` | `sandbox_replay/consumption_replay.py`(扩展) | S | ✅ 2026-05-06 |
|
||||
| 2 | 累计消费总额 | (待补,目前无独立查询) | `sandbox_replay/consumption_replay.py`(扩展) | S | ⏳ 待启动 |
|
||||
| 3 | 累计交易笔数 | (待补,后端无实现) | `sandbox_replay/consumption_replay.py`(扩展) | S | ⏳ 待启动 |
|
||||
| 1 | 60 天消费 | `fdw_queries.get_consumption_60d` | `sandbox_replay/consumption_replay.py`(扩展) | S | ✅ 2026-05-06(thin wrapper)|
|
||||
| 2 | 累计消费总额 | (无,新增) | `sandbox_replay/consumption_replay.py`(扩展) | S | ✅ 2026-05-06(无 wrapper,0 调用方)|
|
||||
| 3 | 累计交易笔数 | (字段未定,需 Neo 决断 dws_order_summary vs total_visit_count) | `sandbox_replay/consumption_replay.py`(扩展) | S | ⏸️ **暂停**(spec §4 字段未明确)|
|
||||
| 4 | 会员储值卡余额 | `fdw_queries.get_member_balance` | `sandbox_replay/balance_replay.py`(新建) | S | ⏳ 待启动 |
|
||||
| 5 | 累计 GMV | `board_service` 财务总额 | `sandbox_replay/finance_replay.py`(新建) | S | ⏳ 待启动 |
|
||||
| 5 | 累计 GMV | `dws_finance_daily_summary.gross_amount`(门店级,与现有"区间 GMV"语义不同) | `sandbox_replay/finance_replay.py`(新建) | S | ⏳ 待启动 |
|
||||
|
||||
### Sprint 2 实施模式
|
||||
所有指标走 `@runtime_aware` decorator + `app.v_dws_*` 视图查询。每个指标:
|
||||
@@ -91,7 +91,9 @@
|
||||
- 审计 + 单独 commit
|
||||
|
||||
### Sprint 2 commit
|
||||
- #1 60d 消费 — `feat(backend): F1-6 sprint2 #1 60d 消费迁移 sandbox_replay`(待提交)
|
||||
- #1 60d 消费 — commit `d418621`(2026-05-06)
|
||||
- #2 累计消费总额 — `feat(backend): F1-6 sprint2 #2 累计消费总额加入 sandbox_replay`(待提交)
|
||||
- #3 累计交易笔数 — **暂停**(spec §4 字段未明确,需 Neo 决断 `dws_order_summary` vs `dws_member_consumption_summary.total_visit_count`)
|
||||
|
||||
### 估算
|
||||
5 指标 × 30-50min = 3-4h(#1 实际 ~ 40min)
|
||||
|
||||
Reference in New Issue
Block a user