Files
ccdi/docs/superpowers/specs/2026-03-18-lsfx-large-transaction-mock-design.md

278 lines
9.6 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.
# LSFX Mock 大额交易命中样本设计
## 背景
当前 `lsfx-mock-server` 的银行流水接口会返回完全随机的流水数据,但后端银行流水打标中的大额交易模型依赖摘要关键词、收支方向、金额阈值、交易日期,以及 `cretNo` 与员工/家属身份关系的匹配。仅有随机金额和随机摘要不足以稳定命中后端规则,导致联调时即使接口返回成功,后端打标结果仍可能为空。
本设计用于调整 Mock 流水生成策略,使其在保留随机噪声数据的同时,稳定产出可命中后端大额交易 8 条规则的样本流水。
## 目标
- 更新 `lsfx-mock-server` 的银行流水生成逻辑。
- 每个 `logId` 首次生成流水时,稳定包含可命中大额交易 8 条规则的样本。
- 在命中样本之外继续混入普通随机流水,保持 Mock 数据的随机感和分页场景。
- 不修改后端打标实现,以后端现有 SQL 口径作为唯一准绳。
## 范围
### In Scope
- `lsfx-mock-server` 获取银行流水接口的生成逻辑。
- 大额交易 8 条规则所需的命中样本模板。
- 对应的 Mock 单元测试与接口测试。
- 本次改动的实施记录文档。
### Out of Scope
- 后端 `CcdiBankTagAnalysisMapper.xml` 或打标 Service 逻辑调整。
- 其他模型组规则的 Mock 命中样本。
- Mock 服务接入主系统数据库或动态读取后端参数。
## 后端规则现状
后端当前已实际实现并可命中的大额交易规则为:
1. `HOUSE_OR_CAR_EXPENSE`
2. `TAX_EXPENSE`
3. `SINGLE_LARGE_INCOME`
4. `CUMULATIVE_INCOME`
5. `ANNUAL_TURNOVER`
6. `LARGE_CASH_DEPOSIT`
7. `FREQUENT_CASH_DEPOSIT`
8. `LARGE_TRANSFER`
这些规则的关键命中条件总结如下:
- 房车消费、税务支出:依赖 `userMemo``customerName` 的关键词命中,且 `drAmount > 0`
- 单笔大额收入、累计收入、年流水、大额转账:依赖员工身份、对手方名称、收支方向、阈值及排除条件。
- 大额存现、单日多次存现:依赖 `cashType``userMemo``customerName``crAmount` 的联合条件。
- 多条规则要求 `cretNo` 能在后端库中关联到员工或家属,否则规则不会命中。
## 关键前提
Mock 必须复用一组后端环境中真实可识别的身份证号,否则仅靠金额和摘要无法满足后端 `exists staff/relation` 条件。
本次默认复用现有文档中已用于大额交易验证的身份池:
- 员工:`330101198801010011`
- 家属:`330101199001010022`
- 员工:`330101198802020033`
- 家属:`330101199202020044`
这些身份已在既有大额交易验证文档与种子 SQL 中使用,可作为 Mock 默认命中身份池。若后续目标环境不存在这些身份,需要在样本配置中同步替换。
## 设计概览
将现有“逐条完全随机生成”的策略调整为“两段式生成”:
1. 先生成固定数量的规则命中样本。
2. 再补充普通随机噪声流水。
3. 合并后统一排序/洗牌,写入当前 `logId` 缓存。
4. 分页接口继续基于缓存返回,保证同一 `logId` 多次请求结果一致。
## 组件设计
### 1. 普通随机流水生成器
保留现有随机生成能力,继续负责生成非命中噪声数据。其职责仅限于提供分页场景和背景数据,不承担命中保障。
### 2. 大额交易样本生成器
新增专用样本生成层,负责生成 8 条规则所需的流水组合。建议拆为独立模块,例如:
- `services/statement_rule_samples.py`
该模块维护:
- 默认身份池
- 默认阈值常量
- 每条规则的样本构造函数
- 公共流水字段构造辅助函数
### 3. 汇总与缓存层
`statement_service.py` 负责:
- 调用大额交易样本生成器获取命中样本
- 生成指定数量的噪声流水
- 为所有记录补齐唯一 `bankStatementId``bankTrxNumber``uploadSequnceNumber`
- 合并、打乱顺序并缓存
- 按页返回 `bankStatementList`
## 样本组织方案
为避免只为单一规则生成孤立流水8 条规则拆为 5 组样本簇:
### A. 房车消费支出样本
- 1 至 2 条支出流水
- `drAmount > 0`
- `userMemo``购买房产首付款``购车首付款` 等关键词
-`customerName` 命中 `房地产``贝壳``汽车销售``4S店` 等关键词
- `cretNo` 使用员工或家属身份证
### B. 税务支出样本
- 1 至 2 条支出流水
- `drAmount > 0`
- `userMemo``customerName` 命中 `税务``税款``税务局``国库`
- `cretNo` 使用员工或家属身份证
### C. 大额收入样本簇
使用同一员工身份证与同一非亲属对手方生成多条收入流水,复用命中:
- `SINGLE_LARGE_INCOME`
- `CUMULATIVE_INCOME`
- `ANNUAL_TURNOVER`
约束如下:
- 至少 1 条 `crAmount` 大于 `SINGLE_TRANSACTION_AMOUNT`
- 多条累计 `crAmount` 大于 `CUMULATIVE_TRANSACTION_AMOUNT`
- 再叠加大额收入/支出,使近一年累计交易额大于 `ANNUAL_TURNOVER`
- `leName != customerName`
- `customerName` 不得映射为该员工家属名称
- 避开工资排除条件,不能使用 `浙江兰溪农村商业银行股份有限公司``userMemo` 也不得含 `代发``工资``奖金``薪酬` 等词
### D. 大额存现样本簇
使用同一身份证、同一天生成 6 条现金存入流水,复用命中:
- `LARGE_CASH_DEPOSIT`
- `FREQUENT_CASH_DEPOSIT`
约束如下:
- 每条 `crAmount` 大于 `LARGE_CASH_DEPOSIT`
- 同日条数大于 `FREQUENT_CASH_DEPOSIT`
- `cashType` / `userMemo` / `customerName` 的组合需满足后端 `cashDepositPredicate`
- 推荐使用 `现金存款``ATM现金存款``自助存款现金存入``CRS存款``本行ATM存款` 等摘要
### E. 大额转账支出样本
- 1 至 2 条支出流水
- `drAmount > FREQUENT_TRANSFER`
- `userMemo``手机银行转账``对外转账`
-`cashType` / `customerName` 含转账特征
- `userMemo` 不能包含 `款`,避免被后端排除
- `leName != customerName`
## 默认阈值策略
Mock 不接主系统数据库,因此不动态读取项目参数。为保证命中稳定,样本生成器内置与当前系统默认参数一致的阈值常量:
- `SINGLE_TRANSACTION_AMOUNT = 1111`
- `CUMULATIVE_TRANSACTION_AMOUNT = 50000001`
- `ANNUAL_TURNOVER = 50000001`
- `LARGE_CASH_DEPOSIT = 2000001`
- `FREQUENT_CASH_DEPOSIT = 5`
- `FREQUENT_TRANSFER = 100001`
样本金额应显著高于阈值,避免边界值因格式化或比较方式差异导致误判。
## 数据生成细节
### 字段稳定要求
以下字段不得继续完全随机:
- `cretNo`
- `leName`
- `customerName`
- `userMemo`
- `cashType`
- `trxDate`
- `crAmount`
- `drAmount`
它们需要按规则模板构造。
### 可以继续随机的字段
以下字段可保留随机生成或在模板基础上随机化:
- `accountMaskNo`
- `customerAccountMaskNo`
- `bankTrxNumber`
- `balanceAmount`
- `bank`
- `customerBank`
- `uploadSequnceNumber`
### 日期策略
- `ANNUAL_TURNOVER` 相关样本统一放在当前日期前 12 个月内。
- `FREQUENT_CASH_DEPOSIT` 相关样本统一放在同一天但不同时间点。
- 其他样本可分布在近一年内,避免全部集中到同一时刻。
### 总量策略
- 继续沿用当前 `1200-1500` 的总条数范围。
- 先生成全部命中样本,再以 `totalCount - sampleCount` 的差值补足噪声流水。
- 若后续命中样本数量增长超过随机总量下限,应自动以命中样本数作为最小总量,避免截断命中数据。
### 排序与分页
生成完成后统一打乱顺序,再根据请求分页返回。这样:
- 前端仍能看到类似真实的随机顺序
- 同一 `logId` 由于缓存存在,重复请求时顺序稳定
## 错误处理
- 若大额交易样本构造失败,直接抛出明确异常,不静默降级为纯随机流水。
- 这样能避免接口返回正常但后端永远打不中的隐性问题。
- 不新增复杂容错或回退机制,保持 Mock 行为可预测。
## 测试设计
至少补充两类验证:
### 1. 样本生成测试
验证大额交易样本生成器输出满足关键特征:
- 存在房车消费关键词支出
- 存在税务关键词支出
- 存在单笔超阈值收入
- 存在同一对手方累计超阈值收入
- 存在近一年累计交易额超阈值样本
- 存在同日 6 笔以上现金存入
- 存在单笔存现超阈值
- 存在单笔转账支出超阈值且摘要不含 `款`
### 2. 接口返回测试
调用 `getBSByLogId`,验证:
- 返回总数正常
- `bankStatementList` 中能找到各类命中样本特征
- 同一 `logId` 多次请求返回相同数据
- 分页拼接后的全量结果仍包含全部命中样本
## 成功标准
- Mock 每次首次生成流水时都稳定包含大额交易 8 条规则所需样本。
- 同一 `logId` 多次分页请求数据一致。
- 在默认身份池存在于目标环境的前提下,后端接入 Mock 返回数据后,现有大额交易 8 条规则可以被正确命中。
- 普通随机噪声流水仍然存在,不退化为完全固定数据集。
## 风险与约束
- 默认身份池依赖后端环境已有对应员工/家属数据;若环境不一致,需要替换身份池常量。
- Mock 使用内置阈值若后端系统默认参数未来变更Mock 也需要同步更新。
- 若后端 SQL 规则继续演进,本设计中的样本关键词和排除词也要同步校准。
## 实施输出
实施阶段应至少产出:
- Mock 代码改动
- 对应测试用例
- 一份前端实施计划
- 一份后端实施计划
- 一份实施记录文档
其中前后端实施计划用于说明联调影响面:本次主要改动在 Mock 服务,但后端计划中需要明确验证路径和命中校验方式。