MP-2 经 4 轮调研 + Neo 反馈,采纳方案 C(推迟到 F1-6 沙箱时光机阶段 B): - 第 1 轮原方案 D(双口径) → 第 2 轮 D'(单口径) - 第 3 轮 Neo 架构纠正:不读 DWD,走 Core/DWS/app - 第 4 轮 DWS 视图靠谱性审计:dws_assistant_daily_detail 是计费明细 (ledger_amount),不是助教工资(gross_salary 需等级时薪 + 抽成 + 罚分),且缺 effective_hours / work_days - 结论:MP-2 真正实施需要新建 dws_assistant_daily_salary 表(ETL 改造),跟其他 14 个 P1 指标一起做更高效 → 推迟到 F1-6 本次 Wave B 只做 prep:DB schema + 模块 spec + tasks.md 状态调整。 DB 迁移(zqyy_app): - db/zqyy_app/migrations/20260505__add_effective_date_for_excel_adjustments.sql - 3 张 Excel 暂存表(全空,Neo 确认尚无 Excel 上传)ADD COLUMN effective_date DATE NOT NULL(无 DEFAULT,强制未来 Excel 上传必须带): * biz.salary_adjustments(助教薪资扣款/奖励) * biz.stg_finance_expense(月度支出) * biz.stg_platform_income(平台结算收入) - 3 个复合索引 (site_id, effective_date) 支持后续 daily 截断查询 - biz.stg_recharge_commission 已有 recharge_date,无需改造 测试库执行 + 5/5 校验 PASS: - 字段存在(NOT NULL DATE 无 default) - 复合索引存在 + 列序正确 - 字段注释含 'F1-5b MP-2 prep' - INSERT 不带 effective_date 触发 NotNullViolation docs/database/ 同步: - docs/database/changes/2026-05-05__add_effective_date_for_excel_adjustments.md 完整变更说明 + 兼容性 + 回滚 + 5 条校验 SQL + 正式库执行说明 沙箱时光机模块 spec(主干任务排期登记): - docs/_overview/sandbox-replay-engine-spec.md - 22 个相关指标分 P1/P2/P3 优先级: * P1 14 项(daily 视图已有,后端切换) * P2 5 项(算法重算,含 MP-2 完整 daily salary) * P3 3 项(状态算法 + sandbox_audit_log 用户行为) - 4 阶段实施路径: * 阶段 0(本次 prep) * 阶段 A(F1-5a/b 已完成) * 阶段 B(F1-6,2-3 周)— MP-2 真正实施在此 * 阶段 C(F1-7+,1-2 周) - sandbox_replay 模块结构 + runtime_aware decorator 接口契约 - 性能 + 测试 + 前置依赖清单 F1-5b-tasks.md 状态调整: - §4.3 顺序 15:MP-2 从"待开始/C4" → "延期 F1-6" - §6 进度表 MP-2 行同步标"延期 F1-6 + 改方向说明" - 关联到 mp2_prep.md 审计 业务影响: - board-coach sandbox 行为暂遗留(F1-6 解决) - 旧 Excel 模板上传将因 NOT NULL 失败,需 F1-6 同期 ETL UI 改造 + 操作员培训 - 跨页面已 audit:board-finance / customer-records / coach-service-records / customer-service-records 等已合规(F1-5b A1/A3 + MP-1/3/5 收益) 审计:docs/audit/changes/2026-05-05__wave1_f1_5b_mp2_prep.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
25 KiB
F1-5b 任务拆分(规范化稳健版)
日期:2026-05-05 上游:F1-5a 主体(commit
421e193)+ 走查 bug fix(1baa212a045625)已完成 走查报告:docs/audit/changes/2026-05-05__wave1_f1_5a_backend_walkthrough.md决策卡:F1-5-impl-decisions.md(D1-D6 已 Neo 拍板) 用法:本文档为 F1-5b 阶段唯一权威任务清单。每项任务按 §3 标准 5 步流程实施,每个 Wave 末做 checkpoint。
〇、与 v1 版的关键调整(规范化)
| 调整 | 原版 | 调整版 |
|---|---|---|
| 实施流程 | 各任务自由实施 | 统一 5 步:调研 → TDD → 实施 → 验证 → 审计(§3) |
| Step 4 验证(关键稳健性) | 单口径 mcp 走查 | 双口径:4a live 主验 + 4b sandbox 二验,防沙箱遗漏(§3.1 + §3.3 必做清单) |
| Commit 粒度 | 2 个 commit(混合后端/前端/测试) | 4-6 个 commit,每个逻辑独立可 review/revert(§4.3) |
| 防御机制 | 仅 grep 验证 | A1 完成立即加 PreToolUse hook 防回归(§5.1) |
| Wave 节奏 | A 收尾直接进 B | Wave A 末 mid-wave checkpoint,Neo 复审后启动 B(§4.2) |
| 进度跟踪 | 无 | §6 进度表,每项含 status / commit / audit / 4a 4b 完成状态 |
| Neo 决策点 | 末尾"反馈区"空白 | §7 结构化决策表(D7-D10 4 项,Neo 拍板后启动) |
| 失败兜底 | 仅回退路径 | §8 失败决策矩阵:严重度阈值 + 升级路径 |
| 测试守护 | 测试整体在 Wave A | TDD 红绿重构嵌入每项 A 任务,T1 case 与 A 任务同步演进 |
一、阶段总览
1.1 阶段目标(不变)
把 F1-5a "沙箱 batch-run 接入 runtime_context"上半场未收口的工作做完:
- 架构主体收口:F1-5a 计划但未做的 admin_service
CURRENT_DATE→business_date、fdw_queries 异常分支兜底、apply_runtime_session_vars 全 DB 入口统一注入(D2 决策"完整且统一") - F1-5a 走查 follow-up:12 项闭环
- 测试 3 套:test_runtime_context.py / test_admin_ai_batch_runtime.py / test_dispatcher_runtime.py
- 文档同步:P20 SPEC §6/§10/§11/§15
1.2 验收标准(不变)
| # | 标准 | 验证手段 |
|---|---|---|
| AC1 | sandbox=2026-04-20 时,admin-web 全局可见沙箱状态 | Playwright 多页面截图 |
| AC2 | sandbox=2026-04-20 时,小程序所有看板 + 子页 lastService / 月份切换均严格 ≤ 业务日 | weixin-devtools-mcp + DB 累计核对 |
| AC3 | admin_service.py 6 处 CURRENT_DATE 全部走 business_date | pytest integration |
| AC4 | apply_runtime_session_vars 在选定"统一注入点"全部生效,grep 0 处遗漏 | grep + integration test |
| AC5 | 3 套测试本地全绿,覆盖 ≥ 80% RuntimeContext 公共 API | pytest --cov |
| AC6 | P20 SPEC §6/§10/§11/§15 文字与现状一致;§10 矩阵 12 项全 ✓ | 逐项 reviewer 核对 |
| AC7 | board-finance 储值充值 132000 vs 66000 字段差异有结论 | DB 复算脚本入仓 |
| AC8 | task-list 403 manager 权限链路矛盾找到根因并修复 | curl + DB 双源核对 |
| AC9 新增 | A1 落地后 PreToolUse hook 阻止 PR 引回 CURRENT_DATE / date.today() | 手动测试 hook + 审计 |
1.3 工作量估算(微调)
| 组 | 任务数 | 工作量 | 折算人天 |
|---|---|---|---|
| 架构主体收口 | 6 | 1×L + 2×M + 3×S | 1.5 |
| 走查 follow-up | 12 | 1×L + 4×M + 5×S + 2×XS | 2.0 |
| 测试 | 3 | 2×M + 1×L | 1.0 |
| 文档同步 | 4 | 4×S | 0.5 |
| 防御 hook(新增) | 1 | S | 0.2 |
| mid-wave checkpoint(新增) | 1 | M | 0.3 |
| 合计 | 27 | — | 5.5 天 |
二、关键背景与判断(同 v1)
2.1 D2"完整且统一"解读 = (a) 不 (b)
(a) 在所有 DB 入口注入 GUC ✅ 本次必做(F1-5a 仅 run_log_service 试点,不统一)
(b) zqyy_app 新建 RLS 视图层 ❌ 不做(zqyy_app app 实为 fdw_etl 外表,业务读写 biz.* 走应用层 A 方案已覆盖,新建会形成两套保护违反"单一权威源")
后续 Wave 2/3 业务模块新增直查 biz.* 的 SQL,沿用应用层 A 方案,通过 PreToolUse hook 保障(§5.1)。
2.2 月度聚合表 MP-2 推荐 D 双口径
dws_assistant_salary_calc 月度粒度含罚分扣减,daily 不可还原。
推荐方案 D:API 同时返回 current_month_partial(daily 累计到 business_date)+ current_month_settled(monthly 全量),前端默认显 partial 加"实时累计(不含扣减)"标。约 4h 改造。
2.3 BE-1 task-list 403 首要假设
require_permission factory 取 site_id 不一致(JWT vs path/query/body)。F1-5a 走查临时插桩已删,需重做。
2.4 BE-2 db-health UnicodeDecodeError
_get_etl_connection 强制 SET client_encoding TO 'UTF8' + db-health 端点 try/except 降级。属偶发不阻塞,P2。
三、实施流程标准化(每项任务必走 5 步)
3.1 五步流程(Step 4 双口径)
每项任务实施时必须按以下 5 步,Step 4 验证拆 live + sandbox 双口径(关键稳健性补强):
Step 1: 调研(强制,符合 CLAUDE.md "逻辑改动前置调研")
- 用 Explore agent 找现有相关代码
- 输出"改动前上下文摘要":模块职责 / 历史变更 / 影响范围 / 风险点
- Neo 确认后才进 Step 2
Step 2: TDD 红(测试先行)
- 写 test case(若任务在测试组,本身就是 case;若在收口/follow-up,补对应 test case)
- 运行 test → 红(测试失败,因为代码还未改)
Step 3: 实施(写代码)
- 改代码,最小改动原则
- 运行 test → 绿
- 重构(如有)
Step 4: 验证(双口径)
─ Step 4a: live 模式主验证(默认起点)
· 后端改动: curl + Python 脚本 DB 核对(主路径功能正确)
· admin-web 改动: Playwright 截图核对
· 小程序改动: weixin-devtools-mcp 实地 + DB 核对
· 多端: 逐端 live 验证
─ Step 4b: sandbox 二次验证(强制,除非任务标"sandbox 无关")
· 切 sandbox=2026-04-20(主走查日,有数据)
· 重复 4a 同样的验证,确认 sandbox 下:
(i) 业务日上界裁剪正确
(ii) UI 沙箱状态透出(若涉及)
(iii) 业务时钟生效(若涉及)
· 若 4b 发现 4a 未暴露的 bug → 回 Step 3 修复 → 重做 4a + 4b
· 验证完成 → 切回 live(fixture try/finally 保证)
─ 4b 跳过条件: 任务在 Step 1 调研时明确标"sandbox 无关",
如纯文档同步 / 与时间无关的字段映射 / hook 注册等
Step 5: 审计
- 写"改动后摘要":diff / 风险点 / 未覆盖路径 / **4a 与 4b 验证结果**
- 审计记录入 docs/audit/changes/2026-05-XX__wave1_f1_5b_<slug>.md
3.2 跳过条件(罕见)
| 步骤 | 可跳条件 |
|---|---|
| Step 1 调研 | 任务标"XS 工作量"+ 文档已显式列改动行号 |
| Step 2 TDD | 文档/SPEC 类任务(组 4) |
| Step 3 实施 | 仅文档/SPEC 类任务 |
| Step 4a live 验证 | XS 文档类任务,但仍需 grep 验证 |
| Step 4b sandbox 二次验证 | 任务在 Step 1 调研时明确标"sandbox 无关"(纯文档/无时间字段/hook 等) |
| Step 5 审计 | 无可跳条件,所有改动必入审计 |
3.3 Step 4b 必做任务清单(预判)
| 任务 | sandbox 必验? | 验证关注点 |
|---|---|---|
| A1 admin_service 6 处 CURRENT_DATE | 是 | dashboard 区间显示业务月而非真实今天 |
| A2 fdw_queries 异常分支兜底 | 是 | conn=None 路径降级 RuntimeContext.business_date |
| A3 apply_runtime_session_vars 统一注入 | 是 | EXPLAIN 视图 WHERE 含 ≤ business_date |
| A4 zqyy_app 永不做登记 | 否(纯文档) | — |
| A5 batch_id 命名规则 | 否(纯文档) | — |
| A6 db-health UnicodeDecodeError | 否(与 sandbox 无关) | — |
| Hook §5.1 防回归 | 否(hook 触发只与代码改动相关) | — |
| UI-1/2/4 admin-web runtime 透出 | 是 | sandbox 下徽章/列/Drawer 真显沙箱 |
| UI-3 AIDashboard sandbox 提示+分组 | 是 | sandbox 下提示条显示 + 分组数据正确 |
| UI-5 AITriggerJobs runtime 列 | 是 | sandbox 下列正确显示 |
| MP-1 board-finance 储值充值复核 | 是 | sandbox 月数据 vs DB 累计核对 |
| MP-2 board-coach 月度面板双口径 | 是 | sandbox 月 partial vs settled 字段 |
| MP-3 customer-detail lastService 裁剪 | 是 | sandbox 下 lastService 不超业务日 |
| MP-4 coach-detail data.coachId 修复 | 否(预存前端 bug,与 sandbox 无关) | — |
| MP-5 coach-service-records 接 runtime-clock | 是 | sandbox 下默认月 = 业务月 |
| BE-1 task-list 403 manager 权限 | 否(权限链路与 sandbox 无关) | — |
| BE-3 ai_run_logs runtime 回归测试 | 是(测试本身覆盖 sandbox 路径) | runtime_mode='sandbox' 字段写入 |
| T1 unit RuntimeContext | 否(测试用 mock,不切真实 sandbox) | — |
| T2 integration ctx_snapshot | 是(测试本身就是 sandbox/live 切换) | ctx_snapshot 不漂移 |
| T3 unit dispatcher | 否(测试用 mock) | — |
| D1-D4 文档 | 否(纯文档) | — |
四、任务执行顺序
4.1 DAG 依赖图(同 v1)
T1-pre (RuntimeContext API test cases) ─┐
A1 (admin_service CURRENT_DATE) ────────┼─> A3 (GUC 统一注入) ──┐
A2 (fdw_queries 异常分支) ──────────────┘ │
├─> T2 (integration)
T1 (其他 unit) ────────────────────────────────────────────────┤
└─> T3 (dispatcher unit) ──> A4
A1 完成 ──> Hook (§5.1 防回归) ──> Wave A 内继续
UI-1 ──> UI-2 / UI-3 (依赖 A1) / UI-4 (独立) / UI-5 (独立)
MP-1 (独立) / MP-2 (依赖 A2) / MP-3 (独立) / MP-4 (独立, 预存 bug) / MP-5 (依赖已修)
BE-1 (独立) / BE-2 (独立) / BE-3 (依赖 T2)
D1 ──> D2 ──> D3 ──> D4 (本阶段全部完成后)
4.2 Wave 节奏(强化 mid-wave checkpoint)
Wave F1-5b-A(P0 核心,2 天)
目标:架构主体收口 + 沙箱硬要求 + 关键回归测试就位 + 防御 hook 落地
| 顺序 | 任务 | 类型 | 工作量 | 依赖 | Commit 归属 |
|---|---|---|---|---|---|
| 1 | T1 unit RuntimeContext 公共 API | 测试 | M | 无 | C1 |
| 2 | A1 admin_service.py 6 处 CURRENT_DATE | 收口 | M | T1 部分 case | C2 |
| 3 | §5.1 PreToolUse hook 防回归 | 新增 | S | A1 | C2 |
| 4 | A2 fdw_queries 异常分支兜底 | 收口 | S | T1 | C2 |
| 5 | A3 apply_runtime_session_vars 统一注入 | 收口 | L | A1+A2 | C2 |
| 6 | T2 integration estimate→confirm ctx_snapshot 不漂移 | 测试 | L | A1+A3 | C2 |
| 7 | UI-1 + UI-2 AIRunLogs runtime 列+Drawer | follow-up | S+XS | 无 | C3 |
| 8 | UI-4 全局 sandbox 徽章 | follow-up | M | 无 | C3 |
| 9 | MP-3 customer-detail lastService 裁剪 | follow-up | M | 无 | C4 |
| 10 | MP-5 coach-service-records 接入 runtime-clock | follow-up | M | 已修 | C4 |
| 11 | MP-1 board-finance 储值充值复核 | follow-up | M | 无 | C2 |
| 12 | BE-1 task-list 403 详查 | follow-up | M | 无 | C2 |
Wave A mid-wave checkpoint(强制):
1. 切 sandbox=2026-04-20
2. 跑全套 P0 走查(Playwright 5 页 admin-web + weixin-devtools-mcp 7 页小程序)
3. 写 mid-wave 走查报告 docs/audit/changes/2026-05-XX__wave1_f1_5b_wave_a_checkpoint.md
4. Neo 复审 → 决定是否进 Wave B / 调整 Wave B 优先级 / 修复发现的新 bug
5. 切回 live
Wave F1-5b-B(P1/P2 增强 + 文档,3 天)
目标:剩余 follow-up + 测试补全 + SPEC 同步
| 顺序 | 任务 | 类型 | 工作量 | 依赖 | Commit 归属 |
|---|---|---|---|---|---|
| 13 | UI-3 AIDashboard sandbox 提示条 + runtime 分组 | follow-up | M | A1 | C3 |
| 14 | UI-5 AITriggerJobs runtime 列 | follow-up | XS | 无 | C3 |
| 15 | MP-2 board-coach 月度面板双口径 | 延期 F1-6 | L | A2 + dws_assistant_daily_salary 视图(F1-6 内建) | F1-6 |
| 16 | MP-4 coach-detail data.coachId 修复 | follow-up | S | 无 | C4 |
| 17 | T3 unit dispatcher runtime | 测试 | M | A3 | C5 |
| 18 | BE-3 ai_run_logs runtime 写入回归 | follow-up | S | T2 | C5 |
| 19 | A6 db-health UnicodeDecodeError | 收口 | M | 无 | C5 |
| 20 | A4 zqyy_app 永不做登记 | 收口 | XS | A3 | C6 |
| 21 | A5 batch_id 命名规则文档化 | 收口 | XS | 无 | C6 |
| 22 | D1 P20 SPEC §6 | 文档 | S | A3+A4 | C6 |
| 23 | D2 P20 SPEC §10 | 文档 | S | 全部 follow-up | C6 |
| 24 | D3 P20 SPEC §11 | 文档 | XS | 全部任务 | C6 |
| 25 | D4 P20 SPEC §15 + audit dashboard | 文档 | S | C5 commit 后 | C6 |
4.3 Commit 策略(细化为 4-6 个独立逻辑单元)
| Commit | 主题 | 内容 | 验证 |
|---|---|---|---|
C1 feat(test): F1-5b-A1 RuntimeContext unit 测试基础 |
测试基础 | T1 部分 case(为 A 任务红绿) | pytest 红(预期) |
C2 fix(backend): F1-5b-A 沙箱主体收口 + 测试 + 防御 hook |
后端架构 | A1+A2+A3 + 防御 hook + T2 + MP-1 + BE-1 | pytest 绿 + curl + Playwright + MCP |
C3 feat(admin-web): F1-5b UI sandbox runtime 透出 |
admin-web | UI-1/2/4 (Wave A) + UI-3/5 (Wave B) | Playwright 截图核对 |
C4 fix(miniprogram): F1-5b 小程序 sandbox 上界 + 时钟接入 |
小程序 | MP-3/5 (Wave A) + MP-2/4 (Wave B) | weixin-devtools-mcp + DB 累计 |
C5 test+fix(backend): F1-5b 测试增量 + db-health 编码 + retry 回归 |
测试 + 杂项 | T3 + BE-3 + A6 | pytest 全绿 |
C6 docs(spec): F1-5b P20 SPEC §6/§10/§11/§15 同步 + audit |
文档收尾 | A4+A5 + D1-D4 + audit dashboard 刷新 | grep 一致性 |
每个 commit 跑一次 /audit → 生成 docs/audit/changes/2026-05-XX__wave1_f1_5b_<slug>.md。
C2 是"原 Commit 1"的精炼,C5 是"原 Commit 2 后端部分",C6 是"原 Commit 2 文档部分" — 拆细后每个 commit 独立可 review,失败可单独 revert 不影响其他。
五、防御机制(本次新增)
5.1 PreToolUse hook 防回归(A1 完成立即落地)
A1 完成后立即加 hook,防 PR 引回 CURRENT_DATE 或 date.today():
位置:.claude/hooks/pre_check_business_date_regression.py(参照 F2-1B post_edit_*_reminder.py 同类机制)
触发:Edit/Write 命中 apps/backend/app/services/**/*.py 时
逻辑:
- 读取目标文件 new_content
- grep
CURRENT_DATE/date\.today\(\)(排除 fallback 注释行) - 命中则提示:"检测到 CURRENT_DATE / date.today() 直接调用,F1-5b 决策要求走 RuntimeContext.business_date,如确需绕过请加
# RUNTIME_CTX_BYPASS: <理由>注释" - 不强阻断(soft warning),允许 fallback 路径
配套:.claude/settings.json 加 hook 注册;CLAUDE.md 加"业务日上界规范"章节,引用本 hook。
工作量:S(60min) 优先级:P0(防回归)
5.2 Lint 加 grep 校验
每个 commit 之前自动跑:
# 不应出现:
grep -rn "CURRENT_DATE\|date\.today\(\)" apps/backend/app/services/ | grep -v "# RUNTIME_CTX_BYPASS"
# 期望:0 处(或仅 RUNTIME_CTX_BYPASS 注释行)
集成到 scripts/audit/prescan.py,作为 audit 前置检查。
5.3 测试库环境守护
每项 Step 4 验证前后,强制切回 live:
# 通用 fixture(F1-5b-T2 复用)
@pytest.fixture(autouse=True)
def reset_runtime_context_to_live():
yield
# try/finally 保证测试失败也切回 live
requests.patch(BASE+"/api/admin/runtime-context",
json={"site_id": SITE, "mode": "live", "sandbox_date": None,
"reason": "F1-5b 测试 fixture autorestore"},
headers=auth_header())
六、进度跟踪表
每项任务完成后填写。Wave A 完成后 mid-wave checkpoint 复审本表。
4a/4b 列说明:- 任务无需 / ▢ 待做 / ✓ 通过 / ✗ 发现问题需回 Step 3。任一为 ✗ 该任务不算完成。
| ID | 任务 | 状态 | 完成时间 | Commit | 审计 | 4a live | 4b sandbox | 备注 |
|---|---|---|---|---|---|---|---|---|
| T1 | RuntimeContext unit 测试 | 待开始 | — | C1 | — | ▢ | - | mock 不切真实 sandbox |
| A1 | admin_service CURRENT_DATE → business_date | 待开始 | — | C2 | — | ▢ | ▢ | dashboard 显示业务月 |
| Hook | PreToolUse 防回归 hook | 待开始 | — | C2 | — | ▢ | - | hook 与 sandbox 无关 |
| A2 | fdw_queries 异常分支兜底 | 待开始 | — | C2 | — | ▢ | ▢ | conn=None 路径 |
| A3 | apply_runtime_session_vars 统一注入 | 待开始 | — | C2 | — | ▢ | ▢ | EXPLAIN GUC 生效 |
| T2 | integration estimate→confirm 不漂移 | 待开始 | — | C2 | — | ▢ | ▢ | 测试本身就是双模式 |
| UI-1 | AIRunLogs 列表 runtime 列 | 待开始 | — | C3 | — | ▢ | ▢ | sandbox 行 Tag 显示 |
| UI-2 | AIRunLogs 详情 Drawer | 待开始 | — | C3 | — | ▢ | ▢ | Drawer runtime 字段 |
| UI-4 | 全局 sandbox 徽章 | 待开始 | — | C3 | — | ▢ | ▢ | 顶栏徽章颜色切换 |
| MP-3 | customer-detail lastService 裁剪 | 待开始 | — | C4 | — | ▢ | ▢ | sandbox 下不显未来 |
| MP-5 | coach-service-records 接入 runtime-clock | 待开始 | — | C4 | — | ▢ | ▢ | 默认月=业务月 |
| MP-1 | board-finance 储值充值复核 | 待开始 | — | C2 | — | ▢ | ▢ | DB 累计 vs 前端 |
| BE-1 | task-list 403 manager 权限详查 | 待开始 | — | C2 | — | ▢ | - | 权限与 sandbox 无关 |
| — | Wave A mid-wave checkpoint | — | — | — | — | — | — | Neo 复审 |
| UI-3 | AIDashboard sandbox 提示+分组 | 待开始 | — | C3 | — | ▢ | ▢ | 双线分组显示 |
| UI-5 | AITriggerJobs runtime 列 | 待开始 | — | C3 | — | ▢ | ▢ | 列正确显示 |
| MP-2 | board-coach 月度面板双口径 | 延期 F1-6 | 2026-05-05 | C10(prep) | mp2_prep.md | - | - | 改方向:走 D 方案需新建 dws_assistant_daily_salary,本次只做 schema prep(3 stg 表加 effective_date)+ spec 文档,完整实施在 F1-6 沙箱时光机阶段 B |
| MP-4 | coach-detail data.coachId 修复 | 待开始 | — | C4 | — | ▢ | - | 预存 bug 与 sandbox 无关 |
| T3 | dispatcher unit | 待开始 | — | C5 | — | ▢ | - | mock |
| BE-3 | ai_run_logs runtime 回归 | 待开始 | — | C5 | — | ▢ | ▢ | runtime 字段写入 |
| A6 | db-health UnicodeDecodeError | 待开始 | — | C5 | — | ▢ | - | 与 sandbox 无关 |
| A4 | zqyy_app RLS 永不做登记 | 待开始 | — | C6 | — | ▢ | - | 纯文档 |
| A5 | batch_id 命名规则文档化 | 待开始 | — | C6 | — | ▢ | - | 纯文档 |
| D1 | SPEC §6 GUC 路线 | 待开始 | — | C6 | — | ▢ | - | 纯文档 |
| D2 | SPEC §10 矩阵 | 待开始 | — | C6 | — | ▢ | - | 纯文档 |
| D3 | SPEC §11 已知遗漏 | 待开始 | — | C6 | — | ▢ | - | 纯文档 |
| D4 | SPEC §15 + audit dashboard | 待开始 | — | C6 | — | ▢ | - | 纯文档 |
七、Neo 决策点(D7-D10)
启动 Wave A 前,Neo 拍板以下 4 项决策。同 D1-D6 模式,在每项下用 斜体 写反馈。
D7 Commit 拆分粒度
v1 推荐 2 个 commit。规范化版改 4-6 个独立逻辑单元(C1-C6)。
| 选项 | 优势 | 劣势 |
|---|---|---|
| a 4-6 个独立 commit(规范版推荐) | 每个 commit 可独立 review/revert / 历史清晰 | commit 数量多 |
| b 沿用 v1 的 2 个 commit | 数量少 | 一个 commit 含混合主题 |
| c 折中 3 个 commit(测试 / 后端架构 / 前端+文档) | 平衡 | 仍混合后端架构 + UI 改动 |
Claude 推荐 a。
Neo 反馈:
(待填)
D8 PreToolUse hook 防回归是否落地
§5.1 描述。
| 选项 | 评估 |
|---|---|
| a 落地(规范版推荐) | A1 完成立即加 hook,长期防御未来 PR 引回 CURRENT_DATE |
| b 不落地 | 仅靠 grep 在 commit 前手动检查 |
Claude 推荐 a。F2-1B 已验证 hook 防御机制有效,本次类似场景。
Neo 反馈:
(待填)
D9 Wave A mid-wave checkpoint 是否做
§4.2 Wave A 末加 mid-wave checkpoint(切 sandbox + 全套 P0 走查 + Neo 复审 + 切回 live)。
| 选项 | 评估 |
|---|---|
| a 做(规范版推荐) | Wave B 启动前确认 Wave A 闭环,降低 B 阶段集成 bug 风险 |
| b 不做 | A B 连续做,集成失败时回退面更大 |
Claude 推荐 a。F1-5a 走查的教训证明"假定全过其实没过"风险高(走查后才发现 5 个 bug)。
Neo 反馈:
(待填)
D10 MP-2 月度聚合表方案选型
§2.2 推荐 D 双口径,但破坏性较强(API 字段变 + 前端展示变)。
| 选项 | 评估 |
|---|---|
| a 方案 D 双口径(推荐) | 业务一致 + 不丢扣减信息 + 不需新 ETL 表;~4h |
| b 方案 C 接受月度全量 + 前端标注 | 简单透明;但破坏"≤ 业务日"严格性,不符 AC2 |
| c 方案 A daily 累计实时计算 | 业务正确,失去 salary_calc 扣减算法 |
| d 方案 B monthly snapshot + daily 增量 | 实施量大(ETL+DWS+DDL),F1-5b 内做不完 |
Claude 推荐 a。
Neo 反馈:
(待填)
八、失败决策矩阵(本次新增)
每项任务实施中遇到问题时,按严重度自主或升级处理。
8.1 严重度阈值
| 严重度 | 描述 | 处理 |
|---|---|---|
| L0 自主修复 | 单元测试失败 / lint 警告 / 文档拼错 | Claude 自主修,不打断 Neo |
| L1 自主回退 | 单 task 出错且不影响其他 task / Step 4 验证发现局部回归 | Claude git revert 单 task → 写回退报告 → 跳过该 task 进下一项 |
| L2 升级 Neo | 数据 bug 影响生产财务 / 跨组依赖断裂 / 走查发现 ≥ 2 个生产 bug | 立即停止 Wave → 写阻塞报告 → 等 Neo 决定 |
| L3 紧急停 Wave | 全 PG 库不可达 / 测试库被污染影响其他正在跑的测试 / commit 已 push 后发现关键 bug | 立即停止全部任务 → 报警 → 等 Neo 决定回滚或修补 |
8.2 阶段级回退
| 场景 | 严重度 | 回退路径 |
|---|---|---|
| Wave A 完成后 mid-wave checkpoint 发现 ≥ 1 个 P0 bug | L2 | 当 commit revert + 原任务回 Wave A 重做 |
| Wave A 完成后 checkpoint 发现 sandbox 仍漏裁剪 | L2 | revert C2 → 加补丁 task → 重过 A3 |
| Wave B 完成后 SPEC 与代码不一致 | L0 | 单独修 D1-D4 文字,不动代码 |
| 整个 F1-5b 失败 | L3 | revert C1-C6 → 回到 F1-5a 完整状态(421e193+1baa212+a045625) |
8.3 单项风险表(细化 v1)
| 任务 | 风险 | 严重度 | 回退路径 | 升级阈值 |
|---|---|---|---|---|
| A1 | live 模式 RuntimeContext 失效 → 显示旧日期 | L1 | 三层 fallback:RuntimeContext → date.today() → warning | RuntimeContext 完全不可用 → L2 |
| A2 | conn=None + RuntimeContext 同时失效 | L1 | fallback 真实 today + warning | 同上 |
| A3 | GUC 注入与 _fdw_context SET LOCAL 重复 |
L1 | grep _fdw_context 之前已 SET 跳过 |
性能 ≥ 5ms / 调用 → L2 |
| A6 | SET client_encoding 影响其他 ETL 连接 | L1 | feature flag ETL_FORCE_UTF8 |
ETL 全部断 → L3 |
| Hook §5.1 | hook 误伤 fallback 路径 | L1 | soft warning,允许 RUNTIME_CTX_BYPASS 注释 bypass | 正常代码 ≥ 30% 命中误报 → L2 调整 grep 规则 |
| UI-3 | 分组显示破坏图表 | L1 | feature flag VITE_AI_RUNTIME_GROUPING |
manager 反馈强 → L2 回退视图 |
| UI-4 | 顶栏徽章 API 500 整站破 | L1 | ErrorBoundary 包裹 | 整站破 → L3 |
| MP-1 | 修后影响生产财务数据 | H/L2 | 修前后对照表给 Neo 确认 | 任何指标变负 / 误差 > 5% → L2 |
| MP-2 | 双口径 UX 不直观 | L1 | feature flag enable_partial_month |
反馈强 → L2 |
| MP-3 | 月末闭区间 <= vs < 边界 |
L0 | boundary case test 守护 | — |
| MP-4 | setData 时机修复连带 | L1 | 仅 line 247-251 加补强 | 影响其他 page.data → L2 |
| MP-5 | localFallback 仍走真实 today | L1 | localFallback 改读 RuntimeContext sandbox_date 缓存 | sandbox 看到 5 月 → L2 |
| BE-1 | 插桩日志噪音 | L0 | logger.warning 加 [F1-5b-BE-1 DIAG] 前缀,排查完删除 | — |
| T2 | fixture 不切回 live 污染下次 | L1 | autouse fixture 强制切回 | 测试库被污染影响生产模拟 → L3 |
九、关联
- F1-5a 主体审计:
docs/audit/changes/2026-05-05__wave1_f1_5a_sandbox_batch_run.md - F1-5a 走查报告:
docs/audit/changes/2026-05-05__wave1_f1_5a_backend_walkthrough.md - F1-5 实施决策卡:
F1-5-impl-decisions.md - P20 SPEC:
docs/prd/specs/P20-runtime-context-sandbox.md - W1-T7 PRD 批 1:
docs/_overview/admin-api-prd/batch1-runtime-context-and-ai.md - 测试库 site 清单:
memory/project_test_db_sites.md(只有2790685415443269有数据) - F2-1B 防御 hook 经验:
.claude/hooks/post_edit_openapi_reminder.py/.claude/hooks/post_edit_prompt_sync_reminder.py - Reload 卡死预防:
scripts/ops/start-admin.ps1/apps/backend/start_uvicorn.py/scripts/ops/backend-watchdog.ps1
十、启动指令
Neo 复核 §7 D7-D10 后,在每项决策下填 斜体 反馈,然后回复"启动 Wave A"或"调整后启动",Claude 即按 §4.2 + §3 标准 5 步流程执行。
每项任务完成后:
- 更新 §6 进度表(状态 / 完成时间 / commit)
- 写审计记录(§3 Step 5)
- 跑 §5.2 lint grep 校验(必过)
- 进下一项
Wave A 末做 §4.2 mid-wave checkpoint,等 Neo 复审。