补充LSFX Mock第二期稳定随机命中设计文档
This commit is contained in:
253
docs/design/2026-03-20-lsfx-mock-phase2-random-hit-design.md
Normal file
253
docs/design/2026-03-20-lsfx-mock-phase2-random-hit-design.md
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
# 兰溪流水 Mock 第二期稳定随机命中设计
|
||||||
|
|
||||||
|
## 1. 背景
|
||||||
|
|
||||||
|
当前仓库已经具备两条基础能力:
|
||||||
|
|
||||||
|
- `lsfx-mock-server` 已支持按 `logId` 稳定随机命中第一期规则子集,并通过 Mock 流水为主工程提供可重复联调输入。
|
||||||
|
- 主工程第二期真实规则已在 [`docs/plans/backend/2026-03-20-bank-tag-real-rule-phase2-backend-implementation.md`](/Users/wkc/Desktop/ccdi/ccdi/docs/plans/backend/2026-03-20-bank-tag-real-rule-phase2-backend-implementation.md) 中明确范围,但 `lsfx-mock-server` 尚未补齐第二期命中输入与配套基线。
|
||||||
|
|
||||||
|
本次目标不是重写主工程打标逻辑,而是在保留第一期稳定随机命中方案的前提下,为第二期补齐可联调、可重复、可命中真实 SQL 的输入数据。
|
||||||
|
|
||||||
|
## 2. 目标
|
||||||
|
|
||||||
|
- 保留现有第一期 `logId -> 稳定随机规则子集` 行为不变。
|
||||||
|
- 为第二期规则新增稳定随机命中计划。
|
||||||
|
- 让“拉取本行信息 / 获取流水列表 -> 入库到本地 -> 执行重打标”后,最终标签结果中可以查到抽中的第二期规则命中。
|
||||||
|
- 对依赖采购、资产等外部事实表的规则,补最小且幂等的本地数据库基线。
|
||||||
|
|
||||||
|
## 3. 非目标
|
||||||
|
|
||||||
|
- 不新增主工程打标补丁逻辑。
|
||||||
|
- 不把采购类、资产类规则伪造成纯银行流水规则。
|
||||||
|
- 不引入“指定特殊 `logId` 固定命中全部第二期规则”的双轨模式。
|
||||||
|
- 不扩展第二期范围外的新规则。
|
||||||
|
|
||||||
|
## 4. 方案对比
|
||||||
|
|
||||||
|
### 4.1 方案 A:稳定随机命中 + 第二期基线编排
|
||||||
|
|
||||||
|
保留现有 `FileService -> StatementService -> 缓存分页` 主链路;对可由银行流水驱动的第二期规则继续通过 Mock 流水样本触发;对依赖采购、资产等外部事实表的规则,通过本地数据库最小基线补齐真实 SQL 输入。
|
||||||
|
|
||||||
|
优点:
|
||||||
|
|
||||||
|
- 与主工程真实 SQL 数据来源一致。
|
||||||
|
- 能同时覆盖“Mock 取数正确”和“真实规则可命中”。
|
||||||
|
- 保持现有第一期链路结构不变,扩展成本最低。
|
||||||
|
|
||||||
|
缺点:
|
||||||
|
|
||||||
|
- 需要同时维护流水样本和数据库基线两类输入。
|
||||||
|
|
||||||
|
### 4.2 方案 B:只改 Mock 流水
|
||||||
|
|
||||||
|
只扩充 `lsfx-mock-server` 返回的流水数据,不补采购、资产等业务表。
|
||||||
|
|
||||||
|
缺点:
|
||||||
|
|
||||||
|
- 第二期中存在真实依赖 `ccdi_purchase_transaction`、`ccdi_asset_info` 的规则,最终会出现 Mock 看似有数据、真实 SQL 仍然无法命中的偏差。
|
||||||
|
|
||||||
|
### 4.3 方案 C:只补数据库基线
|
||||||
|
|
||||||
|
Mock 仅返回普通流水,把第二期命中主要交给数据库灌数。
|
||||||
|
|
||||||
|
缺点:
|
||||||
|
|
||||||
|
- 无法证明“兰溪本地接口获取流水列表并入库”的链路本身正确。
|
||||||
|
- 偏离本次验收口径。
|
||||||
|
|
||||||
|
## 5. 推荐方案
|
||||||
|
|
||||||
|
采用方案 A。
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
- 第二期联调必须同时证明两件事:Mock 取数入库链路没问题,真实 SQL 也确实能命中。
|
||||||
|
- 采购类和资产类规则本来就不是纯流水规则,直接补最小事实基线才符合真实业务口径。
|
||||||
|
- 继续使用“同一 `logId` 稳定随机命中一部分规则”可以复用现有测试与排障习惯。
|
||||||
|
|
||||||
|
## 6. 模块边界与数据流
|
||||||
|
|
||||||
|
### 6.1 `FileService`
|
||||||
|
|
||||||
|
继续负责生成并持久化规则命中计划。
|
||||||
|
|
||||||
|
在现有字段基础上新增两组规则计划:
|
||||||
|
|
||||||
|
- `phase2_statement_hit_rules`
|
||||||
|
- `phase2_baseline_hit_rules`
|
||||||
|
|
||||||
|
职责边界:
|
||||||
|
|
||||||
|
- 只负责决定“这个 `logId` 抽中了哪些第二期规则”。
|
||||||
|
- 不直接构造流水明细,也不直接写数据库业务基线。
|
||||||
|
|
||||||
|
### 6.2 `StatementService` 与 `statement_rule_samples.py`
|
||||||
|
|
||||||
|
继续负责把命中计划转成最小流水样本,并与噪声流水合并后返回。
|
||||||
|
|
||||||
|
职责边界:
|
||||||
|
|
||||||
|
- 只生成能通过 `ccdi_bank_statement` 真实入库后触发的第二期样本。
|
||||||
|
- 不为采购、资产等外部事实规则伪造流水替代。
|
||||||
|
|
||||||
|
### 6.3 第二期基线服务
|
||||||
|
|
||||||
|
在 `lsfx-mock-server/services/` 下新增一个轻量服务,负责根据 `phase2_baseline_hit_rules` 幂等写入本地 MySQL 最小事实数据。
|
||||||
|
|
||||||
|
职责边界:
|
||||||
|
|
||||||
|
- 只补真实 SQL 所需输入。
|
||||||
|
- 不直接写标签结果表,不参与打标逻辑计算。
|
||||||
|
|
||||||
|
### 6.4 主工程
|
||||||
|
|
||||||
|
主工程 `CcdiFileUploadServiceImpl -> CcdiBankStatement -> CcdiBankTagServiceImpl` 链路保持不变。
|
||||||
|
|
||||||
|
验收以真实链路为准:
|
||||||
|
|
||||||
|
1. 拉取本行信息或通过兰溪接口获取流水。
|
||||||
|
2. 流水成功入库到 `ccdi_bank_statement`。
|
||||||
|
3. 执行项目重打标。
|
||||||
|
4. 在 `ccdi_bank_statement_tag_result` 或结果接口中看到抽中的第二期规则命中。
|
||||||
|
|
||||||
|
## 7. 第二期规则分层
|
||||||
|
|
||||||
|
### 7.1 流水样本直接驱动
|
||||||
|
|
||||||
|
以下规则以 `ccdi_bank_statement` 为核心输入,使用 Mock 流水样本驱动:
|
||||||
|
|
||||||
|
- `LOW_INCOME_RELATIVE_LARGE_TRANSACTION`
|
||||||
|
- `MULTI_PARTY_GAMBLING_TRANSFER`
|
||||||
|
- `MONTHLY_FIXED_INCOME`
|
||||||
|
- `FIXED_COUNTERPARTY_TRANSFER`
|
||||||
|
- `SALARY_QUICK_TRANSFER`
|
||||||
|
- `SALARY_UNUSED`
|
||||||
|
|
||||||
|
要求:
|
||||||
|
|
||||||
|
- 样本必须落在同一个真实员工域或其亲属域上。
|
||||||
|
- 时间窗口、金额区间、对手方稳定性等聚合条件必须在同一对象范围内闭环。
|
||||||
|
- 互斥规则不得使用同一员工样本组。
|
||||||
|
|
||||||
|
### 7.2 数据库基线驱动
|
||||||
|
|
||||||
|
以下规则需要外部事实表配合:
|
||||||
|
|
||||||
|
- `HOUSE_REGISTRATION_MISMATCH`
|
||||||
|
- `PROPERTY_FEE_REGISTRATION_MISMATCH`
|
||||||
|
- `TAX_ASSET_REGISTRATION_MISMATCH`
|
||||||
|
- `SUPPLIER_CONCENTRATION`
|
||||||
|
|
||||||
|
处理方式:
|
||||||
|
|
||||||
|
- 三条资产不匹配规则:
|
||||||
|
- Mock 生成对应交易流水。
|
||||||
|
- 基线服务在 `ccdi_asset_info` 中补“故意缺失或不匹配”的最小资产事实。
|
||||||
|
- `SUPPLIER_CONCENTRATION`:
|
||||||
|
- 直接补 `ccdi_purchase_transaction` 聚合命中基线。
|
||||||
|
- 不伪造银行流水替代。
|
||||||
|
|
||||||
|
## 8. 第二期样本设计
|
||||||
|
|
||||||
|
### 8.1 `LOW_INCOME_RELATIVE_LARGE_TRANSACTION`
|
||||||
|
|
||||||
|
- 选择一个真实员工及其亲属身份证范围。
|
||||||
|
- 亲属收入基线维持低收入事实。
|
||||||
|
- 生成大额累计转入或转出流水,确保超过低收入亲属的大额交易阈值。
|
||||||
|
|
||||||
|
### 8.2 `MULTI_PARTY_GAMBLING_TRANSFER`
|
||||||
|
|
||||||
|
- 同一员工对象、同一天、多名不同对手方。
|
||||||
|
- 每笔金额落在 `MULTI_PARTY_AMT_MIN ~ MULTI_PARTY_AMT_MAX` 区间。
|
||||||
|
- 命中依赖“多人 + 多次 + 同日 + 区间金额”,不依赖敏感词。
|
||||||
|
|
||||||
|
### 8.3 `MONTHLY_FIXED_INCOME`
|
||||||
|
|
||||||
|
- 为同一员工构造连续 3 至 4 个月的固定收入转入。
|
||||||
|
- 排除工资代发主体和工资关键词。
|
||||||
|
- 每月金额稳定高于 `MONTHLY_FIXED_INCOME`。
|
||||||
|
|
||||||
|
### 8.4 `FIXED_COUNTERPARTY_TRANSFER`
|
||||||
|
|
||||||
|
- 为同一员工与固定对手方构造季度稳定转入。
|
||||||
|
- 每季累计金额落在 `FIXED_COUNTERPARTY_TRANSFER_MIN ~ FIXED_COUNTERPARTY_TRANSFER_MAX` 区间。
|
||||||
|
|
||||||
|
### 8.5 `SALARY_QUICK_TRANSFER`
|
||||||
|
|
||||||
|
- 先生成可识别工资入账。
|
||||||
|
- 再在 24 小时内生成大额转出,满足比例条件。
|
||||||
|
|
||||||
|
### 8.6 `SALARY_UNUSED`
|
||||||
|
|
||||||
|
- 先生成工资入账。
|
||||||
|
- 后续 30 天不生成可计入“工资使用”的消费或转账支出。
|
||||||
|
- 与 `SALARY_QUICK_TRANSFER` 不共用同一员工对象。
|
||||||
|
|
||||||
|
### 8.7 资产不匹配三条规则
|
||||||
|
|
||||||
|
- `HOUSE_REGISTRATION_MISMATCH`:生成购房交易流水,但不提供可匹配房产登记。
|
||||||
|
- `PROPERTY_FEE_REGISTRATION_MISMATCH`:生成物业缴费流水,但不提供对应房产登记。
|
||||||
|
- `TAX_ASSET_REGISTRATION_MISMATCH`:生成大额纳税流水,但不提供与税费相符的资产登记。
|
||||||
|
|
||||||
|
### 8.8 `SUPPLIER_CONCENTRATION`
|
||||||
|
|
||||||
|
- 为同一申请人写入多笔采购记录。
|
||||||
|
- 使单一供应商采购额占比显著超过 70%。
|
||||||
|
- 使用固定业务主键和稳定供应商集合,确保可重复验证。
|
||||||
|
|
||||||
|
## 9. 实现落点
|
||||||
|
|
||||||
|
- Modify: `lsfx-mock-server/services/file_service.py`
|
||||||
|
- Modify: `lsfx-mock-server/services/statement_service.py`
|
||||||
|
- Modify: `lsfx-mock-server/services/statement_rule_samples.py`
|
||||||
|
- Add: `lsfx-mock-server/services/phase2_baseline_service.py`
|
||||||
|
- Add/Modify: `lsfx-mock-server/tests/test_file_service.py`
|
||||||
|
- Add/Modify: `lsfx-mock-server/tests/test_statement_service.py`
|
||||||
|
- Add/Modify: `lsfx-mock-server/tests/integration/test_full_workflow.py`
|
||||||
|
- Add: `sql/migration/2026-03-20-lsfx-mock-phase2-hit-baseline.sql`
|
||||||
|
|
||||||
|
## 10. 幂等策略
|
||||||
|
|
||||||
|
- 规则命中计划继续由 `logId` 决定,不新增第二随机源。
|
||||||
|
- 流水样本继续由 `StatementService` 缓存,同一 `logId` 重复分页读取结果一致。
|
||||||
|
- 采购基线使用固定业务主键,按固定主键删后重建。
|
||||||
|
- 资产基线使用固定特征组合,确保可精确清理与重建。
|
||||||
|
- 所有基线写入都必须只作用于本次选中的员工域,避免污染无关人员。
|
||||||
|
|
||||||
|
## 11. 验证设计
|
||||||
|
|
||||||
|
### 11.1 Mock 单元测试
|
||||||
|
|
||||||
|
- 第二期规则池抽样稳定性。
|
||||||
|
- 第二期流水样本只装配被抽中的规则。
|
||||||
|
- 第二期数据库基线写入的幂等性。
|
||||||
|
|
||||||
|
### 11.2 Mock 集成测试
|
||||||
|
|
||||||
|
- `getJZFileOrZjrcuFile -> getBSByLogId` 同一 `logId` 下结果稳定。
|
||||||
|
- 抽中第二期规则时,流水样本与基线写入同步成立。
|
||||||
|
|
||||||
|
### 11.3 主工程端到端验证
|
||||||
|
|
||||||
|
- 拉取本行信息后流水成功入库。
|
||||||
|
- 执行项目重打标后,第二期目标规则出现在结果中。
|
||||||
|
- 明细型规则可通过流水详情接口回查。
|
||||||
|
- 对象型规则可在标签结果表中看到正确 `objectType/objectKey/reasonDetail`。
|
||||||
|
|
||||||
|
## 12. 风险与边界
|
||||||
|
|
||||||
|
- 不为了联调成功去修改主工程真实 SQL。
|
||||||
|
- 不把 `SUPPLIER_CONCENTRATION` 伪造成纯流水命中。
|
||||||
|
- 不引入兜底、补丁或兼容性双轨逻辑。
|
||||||
|
- 若第二期真实 SQL 与现有基线字段口径不一致,按验证失败暴露,不在 Mock 侧偷偷修正业务规则。
|
||||||
|
|
||||||
|
## 13. 结论
|
||||||
|
|
||||||
|
本方案采用“保留第一期稳定随机命中方案 + 为第二期补齐稳定随机命中计划、最小流水样本和幂等数据库基线”的最短路径实现。
|
||||||
|
|
||||||
|
这样可以同时保证:
|
||||||
|
|
||||||
|
- 兰溪本地接口能够正确返回并入库存量流水;
|
||||||
|
- 第二期新增模型所需输入事实完整;
|
||||||
|
- 主工程重打标后能够命中新增模型的真实规则结果。
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# LSFX Mock 第二期稳定随机命中设计记录
|
||||||
|
|
||||||
|
## 本次变更
|
||||||
|
|
||||||
|
- 新增第二期联调设计文档:
|
||||||
|
- `docs/design/2026-03-20-lsfx-mock-phase2-random-hit-design.md`
|
||||||
|
|
||||||
|
## 设计收敛结果
|
||||||
|
|
||||||
|
- 明确保留第一期 `logId` 稳定随机命中方案,不引入第二套命中模式。
|
||||||
|
- 明确第二期规则按“流水样本驱动”和“数据库基线驱动”两层处理。
|
||||||
|
- 明确验收口径为“兰溪本地接口取数并入库后,执行重打标,最终标签结果中可查到抽中的第二期规则命中”。
|
||||||
|
|
||||||
|
## 关键边界
|
||||||
|
|
||||||
|
- 不修改主工程真实打标逻辑。
|
||||||
|
- 不把采购类、资产类规则伪造成纯流水规则。
|
||||||
|
- 不新增兼容性或补丁式方案。
|
||||||
|
|
||||||
|
## 后续动作
|
||||||
|
|
||||||
|
- 待用户审核设计文档后,再进入实施计划编写。
|
||||||
Reference in New Issue
Block a user