Files
Neo-ZQYY/docs/_overview/04a-feedback/P0-1-SPI-research.md
Neo 509cf43284 chore(docs): Wave 0 调研产出 + P0/P1/P2 反馈调研
建立项目级标杆文档 docs/_overview/ 作为产品全景索引,
解决"PRD 零碎、文档膨胀、跨子系统调研无入口"的问题。

主要内容:
- 00-index 总索引 + 维护协议 + 与 CLAUDE.md 关系
- 01-product-overview 产品全景脑图(6 角色 / 6 子系统 / 数据流 /
  7 业务概念 / 8+1 AI 矩阵 / 22 术语)
- 02a-miniprogram-page-matrix 小程序 21 页业务指纹
- 02b-adminweb-page-matrix admin-web 19 路由业务指纹
- 03-test-spec 测试规范 (L1-L5 分层 + 走查模板 + 75-95 case 估算)
- 04-doc-conflicts 39 条冲突索引(P0×8 / P1×13 / P2×13 + 5 子项)
- 04a/b/c-conflicts-*-detail 业务故事卡(7 字段:关联/逻辑/影响/选项/判定)
- 05-orphan-pages-cleanup admin-web 6 孤儿页面处置(1 归档 + 4 保留)
- WAVES-MASTER-PLAN.md 全 Wave 主计划(0-5,共 22-32 工作日)
- WAVE-1-KICKOFF.md Wave 1 实施 kickoff
- GLOBAL-DECISION-DASHBOARD.md 全局决策仪表板

反馈调研产物:
- 04a-feedback/ P0 两轮反馈(8+8 项决策 + D-1/2/3 + F-1/2 子代理产出)
- 04b-feedback/ P1 两轮反馈(13+1+5 项 + E-1/2/3/4 + G-1/2 子代理产出)
- 04c-feedback/ P2 反馈(13 项 + 5 子项 + H-1/2/3 子代理产出)
- NEO-DECISIONS-LOG 累积决策记录

关键追加发现 8 处 D Bug(原蓝本 0):
- P0-3 看板沙箱接入(Wave 1 W1-T1)
- P0-5 致命 1 (4 处 fdw_etl 残留, 已修 commit 17f045a)
- P0-5 致命 2 (JWT aud 缺失, 已修 commit 17f045a)
- P0-6 clearAllTasks 守卫 (Wave 3)
- P0-8 DBViewer 黑名单漏 (已修 commit 17f045a)
- P1-3 task-detail 跳转传 task_id 而非 customer_id
- P2-7 board-finance 隐式 null
- 2 个独立 Bug (page_context.created_at + ClueCategory 字典)

参考: docs/_overview/00-index.md
2026-05-04 07:38:28 +08:00

354 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P0-1 SPI 参数深入调研报告(step1)
> 日期:2026-05-04
> 触发:Neo 在 `04a-conflicts-P0-detail.md` § P0-1 反馈,要求"先深入调研后实施"
> 调研者:子代理(SPI 深入调研专项)
> 范围:仅 step1(A 实现 PRD 全集 + B 历史变更 + C 当前实现),step2 实施由 Neo 拍板后另开
> 结论先行:测试库实际 27 行 SPI 参数,与代码 DEFAULT_PARAMS、BD 手册三方一致;
> 文档矛盾根源:`docs/prd/specs/00-数据依赖矩阵.md` L272 写"26 个" 是文档过期,
> `scripts/ops/run_seed_spi_params.py` L62 写"期望 28 个" 是脚本设计期未对齐最终值。
---
## 一、SPI 是什么(业务定位摘要)
**SPI**(Spending Power Index,消费力指数)是 NeoZQYY 指数体系第 7 个指数(继 WBI/NCI/RS/OS/MS/ML 之后),粒度为 `(site_id, member_id)`,**衡量会员在门店内的综合消费力层级**。
**业务回答的问题**:
- 这个客户整体消费能力在门店内属于什么层级?
- 近期消费推进速度是否明显变快?
- 是稳定高消费,还是偶发冲高?
**运营定位**(与其他指数的分工):
- NCI/WBI:决定"要不要优先触达"(紧迫度)
- **SPI:决定"投入多大资源、用什么档位策略"**(消费力分层)
- OS/RS/MS/ML:决定"谁来做、什么时候、谁更容易做成"(关系归属)
**算法结构**:主分(SPI_raw)= w_L × Level + w_S × Speed + w_P × Stability,默认权重 0.60/0.30/0.10。三子分各自由"金额压缩 + 加权"得到原始分,再经 BaseIndexTask 统一映射为 [0, 10] 展示分。
---
## 二、SPI 三子分参数清单(基于 PRD + SPEC + 代码 + DB 四方对照)
> 列说明:
> - **PRD 默认值** = `docs/prd/SPI 消费力指数.md` § 8.2 的取值(部分基数标"按门店分布校准",此处用"校准"表示)
> - **SPEC 默认值** = `docs/specs/spi-spending-power-index/design.md` 中 DEFAULT_PARAMS 的取值
> - **代码默认值** = `apps/etl/connectors/feiqiu/tasks/dws/index/spending_power_index_task.py` L70-L106
> - **DB 实际值** = 测试库 `test_etl_feiqiu.dws.cfg_index_parameters` 当前取值(2026-05-04 查)
> - 本表共 27 行,与代码 DEFAULT_PARAMS、BD 手册、测试库 DB 三方一致
### 2.1 窗口与平滑(3 个)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 1 | `spend_window_short_days` | 短窗口(速度) | 30 | 30 | 30 | 30 |
| 2 | `spend_window_long_days` | 长窗口(层级/稳定性上限) | 90 | 90 | 90 | 90 |
| 3 | `ewma_alpha_daily_spend` | 日消费 EWMA 平滑系数 | 0.3 | 0.3 | 0.3 | 0.3 |
### 2.2 金额压缩基数(6 个,可被门店中位数自动校准覆盖)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 4 | `amount_base_spend_30` | 30 天消费压缩基数 | 校准 | 500.0 | 500.0 | 500.0 |
| 5 | `amount_base_spend_90` | 90 天消费压缩基数 | 校准 | 1500.0 | 1500.0 | 1500.0 |
| 6 | `amount_base_ticket_90` | 90 天客单压缩基数 | 校准 | 200.0 | 200.0 | 200.0 |
| 7 | `amount_base_recharge_90` | 90 天充值压缩基数 | 校准 | 1000.0 | 1000.0 | 1000.0 |
| 8 | `amount_base_speed_abs` | 绝对速度压缩基数 | 校准 | 100.0 | 100.0 | 100.0 |
| 9 | `amount_base_ewma_90` | EWMA 速度压缩基数 | 校准 | 50.0 | 50.0 | 50.0 |
### 2.3 总分权重(3 个)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 10 | `weight_level` | 总分中 Level 权重 | 0.60 | 0.60 | 0.60 | 0.60 |
| 11 | `weight_speed` | 总分中 Speed 权重 | 0.30 | 0.30 | 0.30 | 0.30 |
| 12 | `weight_stability` | 总分中 Stability 权重 | 0.10 | 0.10 | 0.10 | 0.10 |
> 校验:0.60 + 0.30 + 0.10 = 1.00 (`run_seed_spi_params.py` 第 96-103 行 SQL 已覆盖此校验)
### 2.4 Level 子分内部权重(4 个)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 13 | `w_level_spend_30` | Level 子分中 30 天消费项 | 0.30 | 0.30 | 0.30 | 0.30 |
| 14 | `w_level_spend_90` | Level 子分中 90 天消费项 | 0.35 | 0.35 | 0.35 | 0.35 |
| 15 | `w_level_ticket_90` | Level 子分中 90 天客单项 | 0.20 | 0.20 | 0.20 | 0.20 |
| 16 | `w_level_recharge_90` | Level 子分中 90 天充值项 | 0.15 | 0.15 | 0.15 | 0.15 |
> 校验:0.30 + 0.35 + 0.20 + 0.15 = 1.00
### 2.5 Speed 子分内部权重(3 个)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 17 | `w_speed_abs` | 绝对速度项 | 0.50 | 0.50 | 0.50 | 0.50 |
| 18 | `w_speed_rel` | 相对速度项(加速) | 0.30 | 0.30 | 0.30 | 0.30 |
| 19 | `w_speed_ewma` | EWMA 速度项 | 0.20 | 0.20 | 0.20 | 0.20 |
> 校验:0.50 + 0.30 + 0.20 = 1.00
### 2.6 稳定性参数(2 个,90 天上限)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 20 | `stability_window_days` | 稳定性窗口(固定上限 90) | 90 | 90 | 90 | 90 |
| 21 | `use_stability` | 是否启用稳定性子分(0/1) | 1 | 1 | 1 | 1 |
> PRD § 8.2 还列了一个 `stability_mode`(默认 1=周覆盖率),**但 SPEC/代码/DB 均未实现**。当前只有"周覆盖率"一种实现,因此 `stability_mode` 落地时被合理省略——这不是缺失。
### 2.7 映射与平滑(5 个,复用 BaseIndexTask)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 22 | `percentile_lower` | 下分位 | 5 | 5 | 5 | 5 |
| 23 | `percentile_upper` | 上分位 | 95 | 95 | 95 | 95 |
| 24 | `compression_mode` | 压缩模式(0/1/2) | 1 | 1 | 1 | 1 |
| 25 | `use_smoothing` | 是否分位 EWMA 平滑 | 1 | 1 | 1 | 1 |
| 26 | `ewma_alpha` | 分位 EWMA 平滑系数 | 0.2 | 0.2 | 0.2 | 0.2 |
### 2.8 速度计算辅助(1 个,代码新增)
| # | 参数 key | 含义 | PRD | SPEC | 代码 | DB |
|---|---------|------|-----|------|------|-----|
| 27 | `speed_epsilon` | 防除零小量 | (隐含) | 1e-6 | 1e-6 | 1e-6 |
> PRD § 5.3 公式 V_rel = ln((v_30 + ε) / (v_90 + ε)) 用了 ε,但 § 8.2 没把 ε 单列为参数。SPEC 与代码把它显式化为 `speed_epsilon=1e-6`,这是工程合理的"PRD 隐含→代码显式"补全,不是参数膨胀。
### 2.9 期望参数总数对比
| 来源 | 期望数量 | 是否与实际(27)吻合 | 备注 |
|------|---------|-------------------|------|
| PRD § 8.2 表格累加 | 27(若把 stability_mode 算上则 28) | 否(差 1,stability_mode 未落地) | PRD 写了 stability_mode 默认 1,但工程未实现 |
| SPEC `P2-etl-dws-miniapp-extensions.md` § AC6 | 26 | **否(少 1)** | T3 任务清单又写"27 个",**SPEC 内部前后矛盾** |
| SPEC `P2-etl-dws-miniapp-extensions.md` § T3 | 27 | **是** | 与代码 DEFAULT_PARAMS 一致 |
| SPEC `design.md` DEFAULT_PARAMS | 27 | **是** | 27 行清单 |
| `docs/prd/specs/00-数据依赖矩阵.md` L272 | 26 | **否(少 1)** | 文档过期,当前 P0-1 冲突的源头 |
| BD 手册 `BD_Manual_dws_member_spending_power_index.md` § 5 | 27 | **是** | 表格 27 行 |
| 代码 `DEFAULT_PARAMS` | 27 | **是** | 真理之源 |
| 运维脚本 `run_seed_spi_params.py` L62 | **28** | 否(多 1) | 脚本写"期望 28",但实际表里只有 27;若该脚本最近未跑,则只是脚本 stale |
| 测试库 `test_etl_feiqiu.dws.cfg_index_parameters` | **27** | (基准) | 实际值 |
> 真理之源:**测试库 27 行 = 代码 DEFAULT_PARAMS 27 项 = BD 手册 27 行 = SPEC § T3 / SPEC design 27 项**。
> 所有偏差都集中在两份文档(00 矩阵 26、SPEC AC6 26)和一个脚本(`run_seed_spi_params.py` 28)上。
---
## 三、历史变更时间线
> 数据来源:`git log --all -- "**spending_power**" "**SPI**"` + `docs/audit/changes/*.md` Grep
> 注:本仓库历史 commit 较粗(多为周累积合流),无 SPI 单独 commit。下表按审计文件粒度还原。
| 日期 | 提交 / 审计文件 | 摘要 |
|------|----------------|------|
| 2026-02-22 ~ 02-23 | commit `b25308c` "feat: P1-P3 全栈集成" | SPI 任务初次落地:`spending_power_index_task.py` 入仓、`dws.dws_member_spending_power_index` 表创建、cfg_index_parameters 27 行 SPI 种子数据初始化(测试库)。SPEC `P2-etl-dws-miniapp-extensions.md` AC6 标注"effective_from=2026-02-23" |
| 2026-02-27 | `docs/audit/changes/2026-02-27__biz-day-cutoff-prd-sync-check.md` | 营业日切点(`BUSINESS_DAY_START_HOUR=8`)全栈贯通,SPI 任务被列入 20+ DWS 任务批量重构清单——`tasks/dws/index/spending_power_index_task.py` 引入 `biz_date_sql_expr` 适配营业日分割。**只改代码,未改参数** |
| 2026-03-02 | `docs/audit/changes/2026-03-02__spi-calibration-nonzero-median.md` | **SPI 基数校准改用非零样本中位数**:`_CALIBRATE_MIN_SAMPLE = 10`,零消费会员不再拉低中位数。验证 6/6 回退 → 4/6 有效校准 + 2/6 安全回退。**只改代码,不改 cfg_index_parameters 内容** |
| 2026-03-15 | `docs/audit/changes/2026-03-15__ddl-baseline-consolidation-bd-manual-reorg.md` | DDL 基线合并 + BD 手册重整,SPI 表 DDL 从迁移目录被合并到 `docs/database/ddl/etl_feiqiu__dws.sql`。**只动 DDL/文档,不动参数** |
| 2026-03-20 | `docs/audit/changes/2026-03-20__rns13-board-apis-e2e-fix.md` 等 | board-customer 看板用到 SPI 展示分,联调修复。**未触参数** |
| 2026-03-24 | `docs/audit/changes/2026-03-24__lookback_days_60_to_90.md` | RS/MS/ML 的 `lookback_days` 60→90,**与 SPI 无关**(SPI 用 `spend_window_long_days=90` 而非 lookback_days),但同时间段有人改过指数体系参数,需注意 |
**关键观察**:
1. SPI 自 2026-02-23 落地以来,**参数总数 27 没变过**,只动过代码(校准逻辑改进、营业日切点适配)。
2. 历史会话档案(`docs/ai-env-history/``docs/claude-history/`)Glob 不命中 SPI 关键词——本机历史会话归档主要按时间分目录,无 SPI 专项会话。
3. 没有"参数从 26 加到 27"或"从 27 减到 26"的迁移脚本或审计记录。**00 矩阵的 26 是早期文档草稿值,未随后续 27 项落地而更新**。
---
## 四、当前测试库实际数据
### 4.1 总数
```sql
-- 测试库 test_etl_feiqiu @ 2026-05-04
SELECT COUNT(*) FROM dws.cfg_index_parameters WHERE index_type='SPI';
-- 结果: 27
SELECT COUNT(DISTINCT param_name) FROM dws.cfg_index_parameters WHERE index_type='SPI';
-- 结果: 27 (无重复 param_name)
```
### 4.2 全部 param_name 清单(按字母序,实际查询结果)
```
1. amount_base_ewma_90 = 50.000000
2. amount_base_recharge_90 = 1000.000000
3. amount_base_speed_abs = 100.000000
4. amount_base_spend_30 = 500.000000
5. amount_base_spend_90 = 1500.000000
6. amount_base_ticket_90 = 200.000000
7. compression_mode = 1.000000
8. ewma_alpha = 0.200000
9. ewma_alpha_daily_spend = 0.300000
10. percentile_lower = 5.000000
11. percentile_upper = 95.000000
12. speed_epsilon = 0.000001
13. spend_window_long_days = 90.000000
14. spend_window_short_days = 30.000000
15. stability_window_days = 90.000000
16. use_smoothing = 1.000000
17. use_stability = 1.000000
18. w_level_recharge_90 = 0.150000
19. w_level_spend_30 = 0.300000
20. w_level_spend_90 = 0.350000
21. w_level_ticket_90 = 0.200000
22. w_speed_abs = 0.500000
23. w_speed_ewma = 0.200000
24. w_speed_rel = 0.300000
25. weight_level = 0.600000
26. weight_speed = 0.300000
27. weight_stability = 0.100000
```
### 4.3 与 PRD/SPEC 期望对比
- **缺哪几行**: 0 行(代码 DEFAULT_PARAMS 27 项全部存在)
- **多哪几行**: 0 行
- **值偏差**: 0 项(每一项的 `param_value` 都与 PRD § 8.2 + SPEC design.md DEFAULT_PARAMS 完全一致)
- **结论**: **DB 当前状态是干净的、与代码默认值完全对齐**
### 4.4 权重归一化校验(运维脚本逻辑搬运)
| 校验项 | 实际值 | 预期值 | 通过? |
|-------|-------|-------|-------|
| `weight_level + weight_speed + weight_stability` | 1.00 | 1.00 | ✓ |
| Level 内部权重之和(spend_30 + spend_90 + ticket_90 + recharge_90) | 1.00 | 1.00 | ✓ |
| Speed 内部权重之和(abs + rel + ewma) | 1.00 | 1.00 | ✓ |
---
## 五、代码兜底默认值清单
> 来源:`apps/etl/connectors/feiqiu/tasks/dws/index/spending_power_index_task.py` L70-L106 `DEFAULT_PARAMS`
> 兜底机制:`execute()` L181-L182 `params = {**self.DEFAULT_PARAMS, **db_params}`,**DB 缺失时用代码默认值**
| param_key | 代码 default | PRD/SPEC default | 一致? |
|-----------|-------------|-----------------|-------|
| spend_window_short_days | 30 | 30 | ✓ |
| spend_window_long_days | 90 | 90 | ✓ |
| ewma_alpha_daily_spend | 0.3 | 0.3 | ✓ |
| amount_base_spend_30 | 500.0 | (PRD: 校准/SPEC: 500.0) | ✓(SPEC 一致) |
| amount_base_spend_90 | 1500.0 | (PRD: 校准/SPEC: 1500.0) | ✓ |
| amount_base_ticket_90 | 200.0 | (PRD: 校准/SPEC: 200.0) | ✓ |
| amount_base_recharge_90 | 1000.0 | (PRD: 校准/SPEC: 1000.0) | ✓ |
| amount_base_speed_abs | 100.0 | (PRD: 校准/SPEC: 100.0) | ✓ |
| amount_base_ewma_90 | 50.0 | (PRD: 校准/SPEC: 50.0) | ✓ |
| w_level_spend_30 | 0.30 | 0.30 | ✓ |
| w_level_spend_90 | 0.35 | 0.35 | ✓ |
| w_level_ticket_90 | 0.20 | 0.20 | ✓ |
| w_level_recharge_90 | 0.15 | 0.15 | ✓ |
| w_speed_abs | 0.50 | 0.50 | ✓ |
| w_speed_rel | 0.30 | 0.30 | ✓ |
| w_speed_ewma | 0.20 | 0.20 | ✓ |
| weight_level | 0.60 | 0.60 | ✓ |
| weight_speed | 0.30 | 0.30 | ✓ |
| weight_stability | 0.10 | 0.10 | ✓ |
| stability_window_days | 90 | 90 | ✓ |
| use_stability | 1 | 1 | ✓ |
| percentile_lower | 5 | 5 | ✓ |
| percentile_upper | 95 | 95 | ✓ |
| compression_mode | 1 | 1 | ✓ |
| use_smoothing | 1 | 1 | ✓ |
| ewma_alpha | 0.2 | 0.2 | ✓ |
| speed_epsilon | 1e-6 | (PRD 隐含 ε,SPEC 显式 1e-6) | ✓ |
**结论**:**代码兜底默认值 100% 与 PRD/SPEC 一致**。即使 cfg_index_parameters 表被清空,SPI 任务也能用 DEFAULT_PARAMS 跑出与当前 DB 完全相同的结果。
---
## 六、step2 推荐更新方案(给 Neo 拍板)
> 调研结论:DB(27)、代码(27)、BD 手册(27)、SPEC § T3(27) 完全对齐。**实际没有"参数缺失"问题,只有"两份文档 + 一个脚本写错数字"的文档维护问题**。
### 选项 A:仅改文档(推荐,工作量最小)
**动作**:
1.`docs/prd/specs/00-数据依赖矩阵.md` L272: "26 个参数" → "27 个参数"
2.`docs/prd/specs/P2-etl-dws-miniapp-extensions.md` AC6: "26 个参数" → "27 个参数",与同文件 T3 任务清单的"27 个参数"对齐
3.`scripts/ops/run_seed_spi_params.py` L62: 期望 28 → 27,并修正注释 "应为 28 个" → "应为 27 个"
4.`docs/audit/changes/2026-05-04__spi-param-count-doc-fix.md` 写审计
**优点**:零代码风险、零 DB 风险,5 分钟完成。
**劣势**:依赖"DB 当前 27 是正确的"这一事实,所以**前提是 Neo 接受 step1 调研结论**(已在第四节用三方对照证明)。
### 选项 B:加 CI 校验脚本(配合选项 A,长期保险)
**动作**:在选项 A 基础上,新增 `scripts/audit/verify_spi_params.py`,实现"对照代码 DEFAULT_PARAMS keyset 与 cfg_index_parameters DISTINCT param_name keyset",有差异时退出码非零,可挂到 pre-commit 或 CI。
**优点**:防止未来再次出现"代码加了参数但 DB 没补 / DB 残留 deprecated 参数"的漂移。
**劣势**:本次冲突解决周期略增,需要一份新脚本 + 测试。
### 选项 C:补 step2 提到的"更新所有每日 SPI 参数"(最大动作)
> 关键澄清:Neo 反馈写"完成后更新所有每日的 SPI 参数",这条措辞需要 Neo 进一步明确意图,有两种解读:
>
> **解读 1**:把"每日跑出来的 SPI 分数"重算一遍。但 SPI 任务本身就是 delete-before-insert 全量刷新,**不存在"历史每日参数"这个概念**——`cfg_index_parameters` 不分天,只有 effective_from。除非 Neo 想做参数版本化(表结构都得改)。
>
> **解读 2**:把现在 27 行参数依据真实业务数据重新校准、调权重(产品/算法层调优)。这不是"P0-1 文档冲突"的范畴,而是 SPI 算法迭代,工作量很大,需要单独立项。
>
> **建议先与 Neo 对齐:**P0-1 的目标只是"让文档与现状一致" → 选项 A(+ 选项 B 加保险)就够了。如果 Neo 想做参数调优,应当独立提出 Phase 2 任务,有自己的 SPEC、影子跑数、效果评估。
### 推荐最终路径
1. **Neo 拍板**:确认"DB 27 行是正确状态"(基于本报告第四节)。
2. **执行选项 A** + **选项 B**:5 分钟改文档 + 新增 ~50 行校验脚本。
3. **关闭 P0-1**:在 `docs/_overview/04a-conflicts-P0-detail.md` 标注已解决。
4. **如有 SPI 算法调优需求**:独立立项,与本次冲突无关。
---
## 七、调研中发现的其他问题(可选,Neo 自行判断是否处理)
1. **`db/etl_feiqiu/seeds/seed_index_parameters.sql` 文件实际不存在**
- `run_seed_spi_params.py` L28 引用此文件,但仓库内查无此文。
- BD 手册 § 1 也写"种子数据:`db/etl_feiqiu/seeds/seed_index_parameters.sql`"——同样指向不存在的文件。
- 影响:此运维脚本若被运行,会在 L125-L127 因文件不存在直接 `sys.exit(1)`。但这不影响生产,因为 SPI 任务的 27 行参数已经在测试库存在(可能是历史另一种方式 INSERT 进去的,或在已删除的 commit 中有过 seed 文件)。
- 建议:在选项 A 中顺手把脚本与 BD 手册的文件引用注释为 "(历史 seed 已合并,本脚本仅作幂等校验)"。
2. **PRD § 8.2 列了 `stability_mode`,但代码/SPEC/DB 均无**
- PRD 默认 `stability_mode=1`(周覆盖率),意图是"留 mode=2/3 供未来切换其他稳定性算法(如 CV/Gini)"。
- 当前只实现了周覆盖率(mode 1),所以参数没有意义因此被合理省略。
- 建议:不补,但在选项 A 修文档时把 PRD § 8.2 标注 "stability_mode 暂未启用,v2 启用多种稳定性算法时再加",避免将来再被读者误判为"缺失参数"。
3. **`run_seed_spi_params.py` 的"期望 28" 不仅与 DB 27 不符,与代码 27 也不符**
- 推测:脚本被写出来时,原作者打算同时插入 SPI(27) + 一个特殊标记参数(如 `_meta_version`)。但最终未实现这第 28 项,脚本期望值未同步回 27。
- 建议:选项 A 修脚本时一起改正。
4. **`docs/prd/specs/00-数据依赖矩阵.md` L123 "指数总览(WBI/NCI/SPI)" 缺 RS/OS/MS/ML**
- 与本次 P0-1 不直接相关,但矩阵在指数枚举上不完整,顺手可补。
- 建议:与本次 P0-1 解耦,转 P2 矩阵补充任务。
---
## 附录:调研用到的文件清单(便于复核)
### A.PRD / SPEC
- `c:\Project\NeoZQYY\docs\prd\SPI 消费力指数.md`(主 PRD,706 行)
- `c:\Project\NeoZQYY\docs\prd\specs\P2-etl-dws-miniapp-extensions.md`(实施 SPEC)
- `c:\Project\NeoZQYY\docs\prd\specs\00-数据依赖矩阵.md`(冲突源 1,L272)
- `c:\Project\NeoZQYY\docs\specs\spi-spending-power-index\design.md`
- `c:\Project\NeoZQYY\docs\specs\spi-spending-power-index\requirements.md`
- `c:\Project\NeoZQYY\docs\specs\spi-spending-power-index\tasks.md`
### B.代码
- `c:\Project\NeoZQYY\apps\etl\connectors\feiqiu\tasks\dws\index\spending_power_index_task.py`(SPI 任务实现,837 行)
- `c:\Project\NeoZQYY\scripts\ops\run_seed_spi_params.py`(运维脚本,冲突源 2,L62 期望 28)
### C.数据库 / 文档
- `c:\Project\NeoZQYY\apps\etl\connectors\feiqiu\docs\database\DWS\changes\BD_Manual_dws_member_spending_power_index.md`(BD 手册 27 行清单)
- 测试库 `test_etl_feiqiu.dws.cfg_index_parameters` WHERE index_type='SPI'(实际 27 行)
### D.审计记录
- `c:\Project\NeoZQYY\docs\audit\changes\2026-02-27__biz-day-cutoff-prd-sync-check.md`(SPI 营业日切点适配)
- `c:\Project\NeoZQYY\docs\audit\changes\2026-03-02__spi-calibration-nonzero-median.md`(SPI 基数校准改进)
- `c:\Project\NeoZQYY\docs\audit\changes\2026-03-15__ddl-baseline-consolidation-bd-manual-reorg.md`(SPI DDL 合并)
- `c:\Project\NeoZQYY\docs\audit\changes\2026-03-20__rns1-ai-autonomous-decision-risk-audit.md`(SPI 提及,非主体)
- `c:\Project\NeoZQYY\docs\audit\changes\2026-03-20__rns13-board-apis-e2e-fix.md`(看板用 SPI 联调,无参数变更)
- `c:\Project\NeoZQYY\docs\audit\changes\2026-03-24__lookback_days_60_to_90.md`(同时段动指数参数,非 SPI)
---
> 本报告 step1 部分到此为止。step2 实施待 Neo 拍板"选项 A / A+B / 其他" 后开新会话执行。