补充异常账户模型打标设计文档
This commit is contained in:
382
docs/design/2026-03-31-abnormal-account-bank-tag-design.md
Normal file
382
docs/design/2026-03-31-abnormal-account-bank-tag-design.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# 异常账户模型接入银行流水打标设计文档
|
||||
|
||||
**模块**: 银行流水打标
|
||||
**日期**: 2026-03-31
|
||||
|
||||
## 一、背景
|
||||
|
||||
当前银行流水打标主链路已经具备以下基础能力:
|
||||
|
||||
- 规则元数据管理与启用控制
|
||||
- `CcdiBankTagServiceImpl` 统一执行入口
|
||||
- `CcdiBankTagAnalysisMapper.xml` 承载真实规则 SQL
|
||||
- `ccdi_bank_statement_tag_result` 统一承载 `STATEMENT / OBJECT` 命中结果
|
||||
- 项目风险总览按对象型结果聚合员工风险情况
|
||||
|
||||
根据 [异常账户.xlsx](/Users/wkc/Desktop/ccdi/ccdi/assets/异常账户.xlsx) 与 [员工账户.xlsx](/Users/wkc/Desktop/ccdi/ccdi/assets/员工账户.xlsx),本次需要新增独立模型“异常账户”,并正式接入以下两条规则:
|
||||
|
||||
- `SUDDEN_ACCOUNT_CLOSURE`:突然销户
|
||||
- `DORMANT_ACCOUNT_LARGE_ACTIVATION`:休眠账户大额启用
|
||||
|
||||
这两条规则均依赖新增账户信息表 `ccdi_account_info`,且风险筛查对象明确为“员工本人”。本次目标是在不改造现有打标架构的前提下,将两条规则纳入现有项目打标主链路,并补充能够稳定命中的测试数据与验证手段。
|
||||
|
||||
## 二、目标
|
||||
|
||||
本次设计目标如下:
|
||||
|
||||
1. 新增账户信息表 `ccdi_account_info`,支撑异常账户规则计算。
|
||||
2. 新增独立模型 `ABNORMAL_ACCOUNT`,并接入 2 条对象型规则。
|
||||
3. 将两条规则接入现有 `executeObjectRule(...)` 打标链路,不新增平行处理模块。
|
||||
4. 补充最小可命中的测试数据 SQL,并覆盖正样本与反样本。
|
||||
5. 保留 Java 自动化测试,同时在验证阶段使用 MySQL MCP 执行真实 SQL,确认命中结果符合业务口径。
|
||||
6. 在设计确认后,分别产出后端与前端实施计划文档。
|
||||
|
||||
## 三、范围
|
||||
|
||||
### 3.1 本次范围
|
||||
|
||||
- 新增 `ccdi_account_info` 建表 SQL
|
||||
- 新增模型 `ABNORMAL_ACCOUNT`
|
||||
- 新增规则元数据 `SUDDEN_ACCOUNT_CLOSURE`、`DORMANT_ACCOUNT_LARGE_ACTIVATION`
|
||||
- `CcdiBankTagServiceImpl` 新增对象型规则分发
|
||||
- `CcdiBankTagAnalysisMapper.java/.xml` 新增 2 条对象型查询
|
||||
- 新增测试数据 SQL
|
||||
- 新增 Java 自动化测试
|
||||
- 新增基于 MySQL MCP 的真实 SQL 验证步骤
|
||||
- 新增设计文档、后端实施计划、前端实施计划
|
||||
|
||||
### 3.2 不在本次范围
|
||||
|
||||
- 不开发“异常账户人员信息”独立查询、分页、详情、导出真实数据链路
|
||||
- 不改前端页面展示逻辑
|
||||
- 不扩展到关系人或外部账户
|
||||
- 不新增动态规则引擎、DSL 或兼容性补丁方案
|
||||
- 不改造 `lsfx-mock-server`
|
||||
- 不将固定阈值改造成项目可配置参数
|
||||
|
||||
## 四、现状分析
|
||||
|
||||
### 4.1 当前主链路
|
||||
|
||||
当前项目级银行流水打标流程为:
|
||||
|
||||
1. `CcdiBankTagServiceImpl.rebuildProject(...)` 加载启用规则。
|
||||
2. 规则按 `rule_code` 分发到 `executeStatementRule(...)` 或 `executeObjectRule(...)`。
|
||||
3. `CcdiBankTagAnalysisMapper.xml` 执行真实 SQL,返回流水型或对象型命中结果。
|
||||
4. Service 将命中结果组装为 `CcdiBankTagResult` 并写入 `ccdi_bank_statement_tag_result`。
|
||||
5. 项目结果总览再按对象维度聚合风险人数和命中规则快照。
|
||||
|
||||
### 4.2 当前缺口
|
||||
|
||||
当前仓库中“异常账户人员信息”仍为占位展示,且主打标规则中尚无“异常账户”模型与对应规则编码。也就是说,本次缺口主要是:
|
||||
|
||||
- 缺少账户信息基础表
|
||||
- 缺少异常账户模型与规则元数据
|
||||
- 缺少两条规则的对象型 SQL
|
||||
- 缺少最小可命中的测试样本与真实 SQL 验证
|
||||
|
||||
## 五、方案对比
|
||||
|
||||
### 5.1 方案一:最小闭环接入现有对象型打标链路
|
||||
|
||||
做法:
|
||||
|
||||
- 新增独立模型 `ABNORMAL_ACCOUNT`
|
||||
- 两条规则均按 `OBJECT` 结果类型落到员工维度
|
||||
- 通过 `CcdiBankTagAnalysisMapper.xml` 计算命中结果
|
||||
- 结果继续写入 `ccdi_bank_statement_tag_result`
|
||||
|
||||
优点:
|
||||
|
||||
- 改动最小
|
||||
- 完全复用现有打标主链路
|
||||
- 能直接进入现有员工风险总览聚合
|
||||
|
||||
缺点:
|
||||
|
||||
- 本轮不打通“异常账户人员信息”独立详情链路
|
||||
|
||||
### 5.2 方案二:在方案一基础上同时打通异常账户独立结果链路
|
||||
|
||||
优点:
|
||||
|
||||
- 风险详情中的“异常账户人员信息”可展示真实数据
|
||||
|
||||
缺点:
|
||||
|
||||
- 改动范围明显扩大
|
||||
- 超出本次需求
|
||||
- 不符合最短路径实现要求
|
||||
|
||||
### 5.3 方案三:仅补 SQL 验证,不接入主系统打标链路
|
||||
|
||||
优点:
|
||||
|
||||
- 开发最省
|
||||
|
||||
缺点:
|
||||
|
||||
- 无法满足“正式接入主系统打标链路”的需求
|
||||
|
||||
### 5.4 结论
|
||||
|
||||
采用方案一:
|
||||
|
||||
- 新增独立模型 `ABNORMAL_ACCOUNT`
|
||||
- 两条规则均按对象型规则接入现有打标链路
|
||||
- 结果沉淀到现有结果表
|
||||
- 后续如需开发异常账户独立查询能力,再以此为基础扩展
|
||||
|
||||
## 六、总体设计
|
||||
|
||||
### 6.1 模型与规则设计
|
||||
|
||||
本次新增如下模型与规则:
|
||||
|
||||
- 模型编码:`ABNORMAL_ACCOUNT`
|
||||
- 模型名称:`异常账户`
|
||||
- 规则一:`SUDDEN_ACCOUNT_CLOSURE` / `突然销户`
|
||||
- 规则二:`DORMANT_ACCOUNT_LARGE_ACTIVATION` / `休眠账户大额启用`
|
||||
|
||||
两条规则统一定义为:
|
||||
|
||||
- `result_type = OBJECT`
|
||||
- `object_type = STAFF_ID_CARD`
|
||||
- `object_key = 员工身份证号`
|
||||
|
||||
### 6.2 结果落库
|
||||
|
||||
两条规则命中后继续写入现有结果表 `ccdi_bank_statement_tag_result`,不新增单独结果表。
|
||||
|
||||
结果字段约束如下:
|
||||
|
||||
- `model_code = ABNORMAL_ACCOUNT`
|
||||
- `rule_code` 使用全大写风格
|
||||
- `result_type = OBJECT`
|
||||
- `bank_statement_id = null`
|
||||
- `object_type = STAFF_ID_CARD`
|
||||
- `object_key = 员工身份证号`
|
||||
- `reason_detail` 存储账户号、异常日期与统计快照
|
||||
|
||||
### 6.3 数据流
|
||||
|
||||
数据流保持为:
|
||||
|
||||
1. 项目级打标入口加载启用规则。
|
||||
2. 当规则编码为 `SUDDEN_ACCOUNT_CLOSURE` 或 `DORMANT_ACCOUNT_LARGE_ACTIVATION` 时,进入 `executeObjectRule(...)`。
|
||||
3. Mapper SQL 在项目范围内将 `ccdi_bank_statement` 与 `ccdi_account_info`、`ccdi_base_staff` 关联。
|
||||
4. SQL 返回员工身份证号维度的对象型命中结果。
|
||||
5. Service 将命中结果写入 `ccdi_bank_statement_tag_result`。
|
||||
6. 员工风险聚合继续从该结果表汇总,无需新建平行链路。
|
||||
|
||||
## 七、表结构设计
|
||||
|
||||
### 7.1 新增表 `ccdi_account_info`
|
||||
|
||||
以 [员工账户.xlsx](/Users/wkc/Desktop/ccdi/ccdi/assets/员工账户.xlsx) 为准,新增表 `ccdi_account_info`,核心字段如下:
|
||||
|
||||
- `account_id`
|
||||
- `account_no`
|
||||
- `account_type`
|
||||
- `account_name`
|
||||
- `owner_type`
|
||||
- `owner_id`
|
||||
- `bank`
|
||||
- `bank_code`
|
||||
- `currency`
|
||||
- `is_self_account`
|
||||
- `monthly_avg_trans_count`
|
||||
- `monthly_avg_trans_amount`
|
||||
- `trans_freq_type`
|
||||
- `dr_max_single_amount`
|
||||
- `cr_max_single_amount`
|
||||
- `dr_max_daily_amount`
|
||||
- `cr_max_daily_amount`
|
||||
- `trans_risk_level`
|
||||
- `status`
|
||||
- `effective_date`
|
||||
- `invalid_date`
|
||||
- `created_by`
|
||||
- `updated_by`
|
||||
- `create_time`
|
||||
- `update_time`
|
||||
|
||||
### 7.2 关联约束
|
||||
|
||||
本次规则只识别员工本人账户,关联口径固定为:
|
||||
|
||||
- `ccdi_account_info.owner_type = 'EMPLOYEE'`
|
||||
- `ccdi_account_info.owner_id = ccdi_base_staff.id_card`
|
||||
- `ccdi_account_info.account_no = ccdi_bank_statement.LE_ACCOUNT_NO`
|
||||
|
||||
说明:
|
||||
|
||||
- 仓库中当前未见单独的账号加解密或标准化链路,因此本次设计要求建表脚本、测试数据与流水数据直接使用一致账号值
|
||||
- 本次不将关系人账户纳入规则范围
|
||||
|
||||
## 八、规则 SQL 口径
|
||||
|
||||
### 8.1 `SUDDEN_ACCOUNT_CLOSURE`
|
||||
|
||||
业务口径:
|
||||
|
||||
- 员工本人账户已销户
|
||||
- 销户日前 30 天内仍存在交易记录
|
||||
|
||||
SQL 设计约束:
|
||||
|
||||
- 仅统计项目内流水
|
||||
- 统计窗口限定为 `[invalid_date - 30天, invalid_date)`
|
||||
- 按“员工身份证号 + 账号”粒度聚合,再映射回员工对象
|
||||
|
||||
命中条件:
|
||||
|
||||
- `status = 2`
|
||||
- `invalid_date is not null`
|
||||
- 窗口内存在至少 1 笔交易
|
||||
|
||||
返回结果:
|
||||
|
||||
- `objectType = STAFF_ID_CARD`
|
||||
- `objectKey = 员工身份证号`
|
||||
|
||||
`reasonDetail` 结构:
|
||||
|
||||
- `账户{account_no}于{invalid_date}销户,销户前30天内最后交易日{last_tx_date},累计交易金额{window_total_amount}元,单笔最大金额{window_max_single_amount}元`
|
||||
|
||||
### 8.2 `DORMANT_ACCOUNT_LARGE_ACTIVATION`
|
||||
|
||||
业务口径:
|
||||
|
||||
- 员工本人账户状态正常
|
||||
- 开户后长期未使用
|
||||
- 首次启用后出现大额资金流动
|
||||
|
||||
SQL 设计约束:
|
||||
|
||||
- 仅统计项目内流水
|
||||
- 以该账户在项目内的首次流水日期作为“启用时间”
|
||||
- “沉睡时长”按开户日期到首次交易日期计算
|
||||
|
||||
命中条件:
|
||||
|
||||
- `status = 1`
|
||||
- `effective_date is not null`
|
||||
- `first_tx_date >= effective_date + 6个月`
|
||||
- 且满足以下任一:
|
||||
- 启用后累计交易总额 `>= 500000`
|
||||
- 启用后单笔最大交易金额 `>= 100000`
|
||||
|
||||
返回结果:
|
||||
|
||||
- `objectType = STAFF_ID_CARD`
|
||||
- `objectKey = 员工身份证号`
|
||||
|
||||
`reasonDetail` 结构:
|
||||
|
||||
- `账户{account_no}开户于{effective_date},首次交易日期{first_tx_date},沉睡时长{dormant_months}个月,启用后累计交易金额{total_amount}元,单笔最大金额{max_single_amount}元`
|
||||
|
||||
### 8.3 公共规则约束
|
||||
|
||||
- 仅识别员工本人账户,不识别关系人和外部账户
|
||||
- 仅按项目内流水计算,不跨项目拼接历史流水
|
||||
- 累计金额使用 `amount_dr + amount_cr`
|
||||
- 单笔最大金额使用 `greatest(amount_dr, amount_cr)`
|
||||
- 同一员工多个账户分别判断,允许同一规则写入多条结果,避免强行合并后丢失账户级快照
|
||||
|
||||
## 九、测试数据设计
|
||||
|
||||
### 9.1 测试数据组织原则
|
||||
|
||||
新增一份独立增量 SQL,放在 `sql/migration/`,仅构造本次规则所需最小样本。
|
||||
|
||||
### 9.2 样本设计
|
||||
|
||||
建议最少包含以下样本:
|
||||
|
||||
- 员工 A:命中 `SUDDEN_ACCOUNT_CLOSURE`
|
||||
- 账户已销户
|
||||
- 销户前 30 天内有 2 到 3 笔项目流水
|
||||
- 员工 B:命中 `DORMANT_ACCOUNT_LARGE_ACTIVATION`
|
||||
- 开户日期早于首次交易至少 6 个月
|
||||
- 启用后累计金额超过 50 万
|
||||
- 员工 C:休眠不足 6 个月,不命中
|
||||
- 员工 D:已销户,但销户前 30 天无流水,不命中
|
||||
|
||||
### 9.3 数据一致性要求
|
||||
|
||||
- `ccdi_account_info.account_no` 与 `ccdi_bank_statement.LE_ACCOUNT_NO` 必须一致
|
||||
- `owner_id` 与员工身份证号一致
|
||||
- 正样本与反样本必须处于同一项目验证口径下,避免跨项目误差
|
||||
|
||||
## 十、测试与验证设计
|
||||
|
||||
### 10.1 Java 自动化测试
|
||||
|
||||
保留两层自动化测试:
|
||||
|
||||
1. Service 分发测试
|
||||
- 新规则能进入 `executeObjectRule(...)`
|
||||
2. Mapper / SQL 结构测试
|
||||
- 新 Mapper 方法存在
|
||||
- XML 中存在对应 `<select>`
|
||||
- 规则元数据和模型编码无拼写错误
|
||||
3. 结果聚合测试
|
||||
- 新规则写入后,员工风险总览可正常聚合
|
||||
|
||||
### 10.2 MySQL MCP 真实 SQL 验证
|
||||
|
||||
本次新增一层真实 SQL 验证,要求在测试阶段直接通过 MySQL MCP 执行规则 SQL,确认结果符合口径。
|
||||
|
||||
验证要求:
|
||||
|
||||
- 使用项目数据库连接信息
|
||||
- 不手写 `mysql -e`
|
||||
- 直接执行对象型规则对应 SQL
|
||||
- 校验命中员工身份证号是否与测试样本一致
|
||||
- 校验反样本不会被查出
|
||||
- 校验 `reason_detail` 中异常日期、累计金额、单笔最大金额等关键快照是否符合预期
|
||||
|
||||
### 10.3 测试结束清理
|
||||
|
||||
若验证阶段启动了本地前后端、Mock 服务或其他辅助进程,测试结束后需主动关闭,避免残留占用端口。
|
||||
|
||||
## 十一、实施边界
|
||||
|
||||
### 11.1 后端实施内容
|
||||
|
||||
- 新增建表与规则元数据 SQL
|
||||
- 新增 Mapper 方法和 XML SQL
|
||||
- 新增 Service 分发
|
||||
- 新增测试数据 SQL
|
||||
- 新增自动化测试
|
||||
- 执行 MySQL MCP SQL 验证
|
||||
|
||||
### 11.2 前端实施内容
|
||||
|
||||
本轮前端原则上不改代码,但仍需产出一份前端实施计划,明确说明:
|
||||
|
||||
- 现有页面继续复用项目总览对象聚合结果
|
||||
- 本轮不开发异常账户独立列表与详情
|
||||
- 前端无需新增接口或交互
|
||||
|
||||
## 十二、验收标准
|
||||
|
||||
验收标准如下:
|
||||
|
||||
1. `ccdi_account_info` 建表脚本存在且字段与 Excel 一致。
|
||||
2. 模型 `ABNORMAL_ACCOUNT` 与两条规则元数据已落库,编码统一全大写。
|
||||
3. `CcdiBankTagServiceImpl` 已接入两条规则对象型执行分支。
|
||||
4. 规则命中结果成功写入 `ccdi_bank_statement_tag_result`。
|
||||
5. 员工风险总览聚合后可看到新增模型与规则命中。
|
||||
6. 测试数据中的正样本可命中,反样本不命中。
|
||||
7. MySQL MCP 真实 SQL 验证结果与业务口径一致。
|
||||
|
||||
## 十三、后续文档规划
|
||||
|
||||
设计确认后,继续补充以下文档:
|
||||
|
||||
- `docs/plans/backend/` 下的后端实施计划
|
||||
- `docs/plans/frontend/` 下的前端实施计划
|
||||
- `docs/reports/implementation/` 下的后端实施记录
|
||||
- `docs/reports/implementation/` 下的前端实施记录
|
||||
@@ -0,0 +1,38 @@
|
||||
# 异常账户模型接入银行流水打标设计记录
|
||||
|
||||
**日期**: 2026-03-31
|
||||
**类型**: 设计记录
|
||||
**范围**: 银行流水打标 - 异常账户模型
|
||||
|
||||
## 1. 本次变更内容
|
||||
|
||||
新增正式设计文档:
|
||||
|
||||
- `docs/design/2026-03-31-abnormal-account-bank-tag-design.md`
|
||||
|
||||
设计结论如下:
|
||||
|
||||
- 新增独立模型 `ABNORMAL_ACCOUNT`
|
||||
- 新增两条对象型规则:
|
||||
- `SUDDEN_ACCOUNT_CLOSURE`
|
||||
- `DORMANT_ACCOUNT_LARGE_ACTIVATION`
|
||||
- 新增账户信息表 `ccdi_account_info`
|
||||
- 规则结果继续落到 `ccdi_bank_statement_tag_result`
|
||||
- 通过测试数据 SQL、Java 自动化测试和 MySQL MCP 真实 SQL 验证共同确认命中口径
|
||||
|
||||
## 2. 设计约束
|
||||
|
||||
- 不开发异常账户独立查询、分页或详情链路
|
||||
- 不改前端展示逻辑
|
||||
- 不扩展到关系人或外部账户
|
||||
- 不增加动态规则引擎或兼容性补丁方案
|
||||
- 不改造 `lsfx-mock-server`
|
||||
|
||||
## 3. 后续文档规划
|
||||
|
||||
待用户确认设计文档后,继续补充:
|
||||
|
||||
- 后端实施计划
|
||||
- 前端实施计划
|
||||
- 后端实施记录
|
||||
- 前端实施记录
|
||||
Reference in New Issue
Block a user