Files
ccdi/docs/plans/backend/2026-03-25-lsfx-mock-all-hit-sql-alignment-backend-implementation.md

12 KiB
Raw Blame History

lsfx-mock All 模式 SQL 对齐强命中 Backend Implementation Plan

For agentic workers: REQUIRED: Use superpowers:executing-plans to implement this plan. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 仅调整 lsfx-mock-server--rule-hit-mode all 生成策略,让 5 条已落地真实 SQL 的规则在真实链路下稳定命中,并尽量抑制噪声命中。

Architecture: 保留 FileService -> StatementService -> phase2_baseline_service 现有分层,不改主工程。all 模式改为“规则专属样本 + 最小关联表基线 + 受控噪声”组合方案;subset 模式保持现状。所有实现以 2026-03-25-lsfx-mock-all-hit-sql-alignment-design.md 为准。

Tech Stack: Python, FastAPI, pytest, 项目内 Mock 服务、MySQL 关联表基线


Task 1: 锁定规则范围与 all 模式计划

Files:

  • Modify: lsfx-mock-server/services/file_service.py

  • Test: lsfx-mock-server/tests/test_file_service.py

  • Reference: ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml

  • Step 1: 为 all 模式规则清单补充失败测试

test_file_service.py 新增断言:

  • SPECIAL_AMOUNT_TRANSACTION 存在于 phase1_hit_rules
  • SUSPICIOUS_INCOME_KEYWORD 存在于 phase1_hit_rules
  • MONTHLY_FIXED_INCOMEFIXED_COUNTERPARTY_TRANSFERLOW_INCOME_RELATIVE_LARGE_TRANSACTION 存在于 phase2_statement_hit_rules
  • all 模式不把占位 SQL 规则误加入强命中计划

示例断言:

assert "SPECIAL_AMOUNT_TRANSACTION" in plan["phase1_hit_rules"]
assert "MONTHLY_FIXED_INCOME" in plan["phase2_statement_hit_rules"]
assert "INTEREST_PAYMENT_BY_OTHERS" not in plan["phase2_statement_hit_rules"]
  • Step 2: 运行测试确认当前实现不能完整表达新口径

Run: cd lsfx-mock-server && pytest tests/test_file_service.py -k "all_mode or phase2_rule_hit_plan" -v

Expected:

  • 新增断言失败,暴露 all 模式规则计划仍是旧口径

  • Step 3: 修改 file_service.py 的 all 模式计划生成逻辑

file_service.py

  • 保持 subset 模式逻辑不变
  • 明确 all 模式只包含真实 SQL 已落地且本次需强命中的规则
  • 保持现有计划字段结构,避免调用方联动修改

实现要求:

  • 不重命名已有字段

  • 不引入新的计划 DSL

  • 仅调整 all 模式规则集合和注释说明

  • Step 4: 运行测试确认计划生成通过

Run: cd lsfx-mock-server && pytest tests/test_file_service.py -k "all_mode or phase2_rule_hit_plan" -v

Expected:

  • PASS

  • Step 5: 提交本任务

git add lsfx-mock-server/services/file_service.py lsfx-mock-server/tests/test_file_service.py
git commit -m "调整all模式规则命中计划"

Task 2: 为 5 条规则补充样本函数测试

Files:

  • Modify: lsfx-mock-server/tests/test_statement_service.py

  • Reference: lsfx-mock-server/services/statement_rule_samples.py

  • Reference: ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml

  • Step 1: 为 SPECIAL_AMOUNT_TRANSACTION 增加失败测试

新增测试断言:

  • 样本金额仅为 5201314
  • 样本主体使用员工本人证件号

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "special_amount" -v

Expected:

  • FAIL当前样本金额仍为 88888.88

  • Step 2: 为 MONTHLY_FIXED_INCOME 增加失败测试

新增测试断言:

  • 命中月份数不少于 6
  • 对手方固定
  • 摘要不带工资关键词

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "monthly_fixed_income" -v

Expected:

  • FAIL当前仅有 4 个月

  • Step 3: 为 SUSPICIOUS_INCOME_KEYWORD 增加失败测试

新增测试断言:

  • userMemocashType 命中 SQL 关键词集合中的明确词

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "suspicious_income_keyword" -v

Expected:

  • FAIL当前“咨询返现收入”不在 SQL 关键词集内

  • Step 4: 为 FIXED_COUNTERPARTY_TRANSFER 增加失败测试

新增测试断言:

  • 样本 cretNo 为员工本人
  • 至少跨 2 个季度
  • 同一对手方季度金额落在 [3000,15000]

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "fixed_counterparty_transfer" -v

Expected:

  • FAIL当前主体落在家属号

  • Step 5: 为 LOW_INCOME_RELATIVE_LARGE_TRANSACTION 增加失败测试

新增测试断言:

  • 使用家属证件号
  • 累计金额大于 100000
  • 依赖的低收入基线需要单独由 baseline 服务补齐

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "low_income_relative_large_transaction" -v

Expected:

  • 可先只验证流水样本金额与主体范围,若测试已通过则继续后续 baseline 测试

  • Step 6: 提交本任务

git add lsfx-mock-server/tests/test_statement_service.py
git commit -m "补充SQL对齐样本测试"

Task 3: 按真实 SQL 改写 5 条样本生成函数

Files:

  • Modify: lsfx-mock-server/services/statement_rule_samples.py

  • Test: lsfx-mock-server/tests/test_statement_service.py

  • Step 1: 改写 build_special_amount_transaction_samples

要求:

  • 使用员工本人证件号

  • 生成 5201314

  • 不复用配偶/子女姓名

  • Step 2: 改写 build_monthly_fixed_income_samples

要求:

  • 连续至少 6 个月

  • 每月固定收入

  • 对手方固定

  • 不命中工资排除条件

  • Step 3: 改写 build_suspicious_income_keyword_samples

要求:

  • 直接命中 SQL 关键词

  • 保持收入流水

  • 优先用摘要关键词,不依赖偶然命中对手方名称

  • Step 4: 改写 build_fixed_counterparty_transfer_samples

要求:

  • 主体切换为员工本人

  • 固定对手方

  • 至少 2 个季度

  • 每季度累计金额位于 [3000,15000]

  • Step 5: 改写 build_low_income_relative_large_transaction_samples

要求:

  • 主体为家属证件号

  • 累计金额大于 100000

  • 与 baseline 服务使用同一目标家属域

  • Step 6: 运行规则样本测试

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "special_amount or monthly_fixed_income or suspicious_income_keyword or fixed_counterparty_transfer or low_income_relative_large_transaction" -v

Expected:

  • PASS

  • Step 7: 提交本任务

git add lsfx-mock-server/services/statement_rule_samples.py lsfx-mock-server/tests/test_statement_service.py
git commit -m "按真实SQL改写命中样本"

Task 4: 扩展 baseline 服务,补齐低收入家属基线

Files:

  • Modify: lsfx-mock-server/services/phase2_baseline_service.py

  • Modify: lsfx-mock-server/services/file_service.py

  • Modify: lsfx-mock-server/tests/test_phase2_baseline_service.py

  • Modify: lsfx-mock-server/tests/test_file_service.py

  • Step 1: 为 baseline 服务补充失败测试

新增测试断言:

  • 当命中 LOW_INCOME_RELATIVE_LARGE_TRANSACTION 时,目标家属 annual_income 被写成 0NULL 或小于 36000
  • 重复执行时保持幂等

Run: cd lsfx-mock-server && pytest tests/test_phase2_baseline_service.py -k "low_income" -v

Expected:

  • FAIL当前 baseline 服务未覆盖该规则的低收入写入

  • Step 2: 扩展 phase2_baseline_service.py

实现要求:

  • 只补当前目标员工域相关关系数据

  • 不污染其他员工或历史关系记录

  • FileService 当前身份绑定保持一致

  • Step 3: 确认 FileService 在 all 模式下会触发对应 baseline

若已有计划写入链路不够明确,则在 test_file_service.py 补充断言:

  • 包含该规则时baseline 服务收到对应规则编码与家属上下文

  • Step 4: 运行 baseline 相关测试

Run: cd lsfx-mock-server && pytest tests/test_phase2_baseline_service.py tests/test_file_service.py -k "low_income or baseline" -v

Expected:

  • PASS

  • Step 5: 提交本任务

git add lsfx-mock-server/services/phase2_baseline_service.py lsfx-mock-server/services/file_service.py lsfx-mock-server/tests/test_phase2_baseline_service.py lsfx-mock-server/tests/test_file_service.py
git commit -m "补充低收入家属基线写入"

Task 5: 收紧 all 模式噪声,避免聚合规则被干扰

Files:

  • Modify: lsfx-mock-server/services/statement_service.py

  • Modify: lsfx-mock-server/tests/test_statement_service.py

  • Step 1: 为 all 模式噪声约束补充失败测试

新增测试断言:

  • 员工本人不会被随机生成多个稳定季度重复对手
  • 员工本人不会被随机叠加过多大额同月收入,破坏 MONTHLY_FIXED_INCOME

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "noise and (monthly or fixed_counterparty)" -v

Expected:

  • FAIL当前噪声仍可能污染聚合规则

  • Step 2: 修改 statement_service.py 的噪声生成约束

实现要求:

  • 仅在 all 模式生效

  • 不取消背景噪声,只收紧对目标员工域的对手方与收入分布

  • 不影响 subset 模式

  • Step 3: 运行噪声相关测试

Run: cd lsfx-mock-server && pytest tests/test_statement_service.py -k "noise and (monthly or fixed_counterparty)" -v

Expected:

  • PASS

  • Step 4: 提交本任务

git add lsfx-mock-server/services/statement_service.py lsfx-mock-server/tests/test_statement_service.py
git commit -m "收紧all模式噪声生成"

Task 6: 补充集成测试,验证 all 模式真实链路

Files:

  • Modify: lsfx-mock-server/tests/integration/test_full_workflow.py

  • Reference: lsfx-mock-server/routers/api.py

  • Step 1: 为 all 模式新增集成测试场景

测试目标:

  • 固定 all 模式计划包含这 5 条规则
  • 调用 Mock 取数链路后,返回流水中可见对应关键样本
  • baseline 服务在链路中被调用

建议断言示例:

assert any(item["userMemo"] == "劳务费发放" for item in statements)
assert any(item["transAmount"] in (520.0, 1314.0) for item in statements)
  • Step 2: 运行集成测试

Run: cd lsfx-mock-server && pytest tests/integration/test_full_workflow.py -k "all_hit or baseline or workflow" -v

Expected:

  • PASS

  • Step 3: 提交本任务

git add lsfx-mock-server/tests/integration/test_full_workflow.py
git commit -m "补充all模式强命中集成测试"

Task 7: 完整回归与人工联调核验

Files:

  • Modify: docs/reports/implementation/2026-03-25-lsfx-mock-all-hit-sql-alignment-record.md

  • Step 1: 运行 Mock 服务回归

Run: cd lsfx-mock-server && pytest tests/test_file_service.py tests/test_statement_service.py tests/test_phase2_baseline_service.py tests/integration/test_full_workflow.py -v

Expected:

  • 全部 PASS

  • Step 2: 启动 Mock 服务进行手工联调

Run:

cd lsfx-mock-server
python main.py --rule-hit-mode all

Expected:

  • 服务正常启动

  • Step 3: 按真实链路执行联调

使用现有后端联调路径:

  • 拉取流水
  • 触发重打标
  • 查询 ccdi_bank_statement_tag_result

人工核验结果:

  • SPECIAL_AMOUNT_TRANSACTION
  • MONTHLY_FIXED_INCOME
  • SUSPICIOUS_INCOME_KEYWORD
  • FIXED_COUNTERPARTY_TRANSFER
  • LOW_INCOME_RELATIVE_LARGE_TRANSACTION

都至少命中 1 条,并且无明显失控噪声命中。

  • Step 4: 记录实施与验证结果

2026-03-25-lsfx-mock-all-hit-sql-alignment-record.md 记录:

  • 修改文件

  • 测试命令

  • 联调项目与命中结果

  • 是否需要后续补充规则

  • Step 5: 停止测试进程

若本轮启动了 Mock 或后端进程,结束后立即停止,避免残留端口占用。

  • Step 6: 提交本任务
git add docs/reports/implementation/2026-03-25-lsfx-mock-all-hit-sql-alignment-record.md
git commit -m "记录lsfx-mock全命中改造结果"