修复流水详情原始文件关联与Mock随机logId

This commit is contained in:
wkc
2026-03-20 16:25:22 +08:00
parent d7c9f0e5bf
commit 079b412d38
11 changed files with 427 additions and 15 deletions

View File

@@ -1,16 +1,224 @@
# 新增模型打标完整验证记录
## 执行命令
- 待补充本次实际执行的 pytest、Maven、SQL、curl 与 Python 核验命令。
```bash
cd lsfx-mock-server
python3 -m pytest tests/test_file_service.py -k "rule_hit_plan or persist_rule_hit_plan" -v
python3 -m pytest tests/test_statement_service.py -k "rule_plan_should_only_include or withdraw_cnt_samples" -v
python3 -m pytest tests/test_statement_service.py -k "follow_rule_hit_plan or fixed_total_count_200 or cached_result" -v
python3 -m pytest tests/integration/test_full_workflow.py -k "same_rule_subset or share_same_primary_binding" -v
python3 -m pytest tests/test_file_service.py tests/test_statement_service.py tests/test_api.py tests/integration/test_full_workflow.py -v
cd ..
mvn test -pl ccdi-project -Dtest=BankTagRuleConfigResolverTest
mvn test -pl ccdi-project -Dtest=CcdiBankTagAnalysisMapperXmlTest
mvn test -pl ccdi-project -Dtest=CcdiBankTagAnalysisMapperXmlTest,CcdiBankTagServiceImplTest
mvn test -pl ccdi-project -Dtest=CcdiBankTagAnalysisMapperXmlTest,BankTagRuleConfigResolverTest,CcdiBankTagServiceImplTest,CcdiBankTagServiceRiskCountRefreshTest
```
## Mock 自动化结果
- 2026-03-20 15:21:54 CST 完成 Mock 聚焦回归与全量回归。
- 聚焦回归结果:
- `tests/test_file_service.py -k "rule_hit_plan or persist_rule_hit_plan"`: `2 passed, 4 deselected, 1 warning`
- `tests/test_statement_service.py -k "rule_plan_should_only_include or withdraw_cnt_samples"`: `2 passed, 11 deselected, 1 warning`
- `tests/test_statement_service.py -k "follow_rule_hit_plan or fixed_total_count_200 or cached_result"`: `3 passed, 10 deselected, 1 warning`
- `tests/integration/test_full_workflow.py -k "same_rule_subset or share_same_primary_binding"`: `2 passed, 3 deselected, 3 warnings`
- 全量回归结果:
- `python3 -m pytest tests/test_file_service.py tests/test_statement_service.py tests/test_api.py tests/integration/test_full_workflow.py -v`
- 摘要:`38 passed, 20 warnings in 4.15s`
- warning 摘要:
- `pydantic` 的 class-based config 弃用提示仍存在。
- `httpx``app` shortcut 弃用提示仍存在。
- 两类 warning 与既有 Mock 验证记录一致,本次未新增 failure 或 error。
## 主工程自动化结果
- 2026-03-20 15:22:27 CST 执行 `mvn test -pl ccdi-project -Dtest=BankTagRuleConfigResolverTest`,结果 `BUILD SUCCESS``Tests run: 6, Failures: 0, Errors: 0, Skipped: 0`
- 2026-03-20 15:22:47 CST 执行 `mvn test -pl ccdi-project -Dtest=CcdiBankTagAnalysisMapperXmlTest`,结果 `BUILD SUCCESS``Tests run: 8, Failures: 0, Errors: 0, Skipped: 0`
- 2026-03-20 15:22:57 CST 执行 `mvn test -pl ccdi-project -Dtest=CcdiBankTagAnalysisMapperXmlTest,CcdiBankTagServiceImplTest`,结果 `BUILD SUCCESS``Tests run: 19, Failures: 0, Errors: 0, Skipped: 0`
- 2026-03-20 15:23:10 CST 执行 `mvn test -pl ccdi-project -Dtest=CcdiBankTagAnalysisMapperXmlTest,BankTagRuleConfigResolverTest,CcdiBankTagServiceImplTest,CcdiBankTagServiceRiskCountRefreshTest`,结果 `BUILD SUCCESS``Tests run: 27, Failures: 0, Errors: 0, Skipped: 0`
- 结果归纳:
- `BankTagRuleConfigResolverTest` 证明第一期规则参数映射保持通过。
- `CcdiBankTagAnalysisMapperXmlTest` 证明真实 SQL 结构保持通过。
- `CcdiBankTagServiceImplTest` 证明规则分发和异常路径断言保持通过。
- `CcdiBankTagServiceRiskCountRefreshTest` 证明风险人数刷新链路保持通过。
- 日志说明:
- 测试日志中的 `threshold missing``refresh failed` 为异常路径断言场景产生的预期日志,不代表本轮 Maven 回归失败。
## 数据库核验
- 待补充采购基线、规则元数据、任务状态与命中结果查询。
```bash
bin/mysql_utf8_exec.sh sql/migration/2026-03-20-lsfx-mock-random-hit-rule-purchase-baseline.sql
python3 - <<'PY'
from pathlib import Path
import pymysql, re
text = Path('ruoyi-admin/src/main/resources/application-dev.yml').read_text(encoding='utf-8')
match = re.search(r"url:\s*jdbc:mysql://(?P<host>[^:/?#]+):(?P<port>\d+)/(?P<db>[^?\n]+).*?\n\s*username:\s*(?P<user>[^\n]+)\n\s*password:\s*(?P<pwd>[^\n]+)", text, re.S)
conn = pymysql.connect(
host=match.group('host'),
port=int(match.group('port')),
user=match.group('user').strip(),
password=match.group('pwd').strip(),
database=match.group('db').strip(),
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor,
)
with conn, conn.cursor() as cursor:
cursor.execute("""
SELECT purchase_id, actual_amount, supplier_name
FROM ccdi_purchase_transaction
WHERE purchase_id = 'LSFXMOCKPUR001'
AND actual_amount > 100000
""")
print(cursor.fetchone())
PY
python3 - <<'PY'
from pathlib import Path
import pymysql, re
TARGET_RULES = (
'GAMBLING_SENSITIVE_KEYWORD','SPECIAL_AMOUNT_TRANSACTION','SUSPICIOUS_INCOME_KEYWORD',
'FOREX_BUY_AMT','FOREX_SELL_AMT','LARGE_PURCHASE_TRANSACTION',
'STOCK_TFR_LARGE','WITHDRAW_CNT','LARGE_STOCK_TRADING'
)
text = Path('ruoyi-admin/src/main/resources/application-dev.yml').read_text(encoding='utf-8')
match = re.search(r"url:\s*jdbc:mysql://(?P<host>[^:/?#]+):(?P<port>\d+)/(?P<db>[^?\n]+).*?\n\s*username:\s*(?P<user>[^\n]+)\n\s*password:\s*(?P<pwd>[^\n]+)", text, re.S)
conn = pymysql.connect(
host=match.group('host'),
port=int(match.group('port')),
user=match.group('user').strip(),
password=match.group('pwd').strip(),
database=match.group('db').strip(),
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor,
)
sql = f"""
SELECT model_code, rule_code, indicator_code
FROM ccdi_bank_tag_rule
WHERE rule_code IN ({','.join(['%s'] * len(TARGET_RULES))})
ORDER BY model_code, sort_order, rule_code
"""
with conn, conn.cursor() as cursor:
cursor.execute(sql, TARGET_RULES)
for row in cursor.fetchall():
print(row)
PY
```
- 采购基线脚本执行结果:
- `bin/mysql_utf8_exec.sh sql/migration/2026-03-20-lsfx-mock-random-hit-rule-purchase-baseline.sql` 执行成功,无报错、无乱码输出。
- 采购基线查询结果:
- 返回 `{'purchase_id': 'LSFXMOCKPUR001', 'actual_amount': Decimal('186000.00'), 'supplier_name': '兰溪市联调供应链有限公司'}`
- 结论:`LSFXMOCKPUR001` 存在,且 `actual_amount > 100000`,采购基线正常。
- 规则元数据查询结果:
- 共查询到 9 条目标规则,`rule_code` 均存在。
- 返回摘要:
- `STOCK_TFR_LARGE -> indicator_code=STOCK_TFR_LARGE`
- `WITHDRAW_CNT -> indicator_code=WITHDRAW_CNT`
- `LARGE_STOCK_TRADING -> indicator_code=NULL`
- `FOREX_BUY_AMT -> indicator_code=FOREX_BUY_AMT`
- `FOREX_SELL_AMT -> indicator_code=FOREX_SELL_AMT`
- 其余 4 条规则 `indicator_code=NULL`
- 异常判定:
- 根据既有实施记录,`FOREX_BUY_AMT` 预期应对齐为 `SINGLE_PURCHASE_AMOUNT`
- `FOREX_SELL_AMT` 预期应对齐为 `SINGLE_SETTLEMENT_AMOUNT`
- `LARGE_STOCK_TRADING` 预期应对齐为 `STOCK_TFR_LARGE`,当前查询为 `NULL`
- 首次执行因此在数据库层判定为“数据基线异常”。
- 修复后复验:
- 已执行 `bin/mysql_utf8_exec.sh sql/migration/2026-03-20-sync-bank-tag-phase1-rule-metadata.sql`
- 修复后查询结果:
- `FOREX_BUY_AMT -> indicator_code=SINGLE_PURCHASE_AMOUNT`
- `FOREX_SELL_AMT -> indicator_code=SINGLE_SETTLEMENT_AMOUNT`
- `LARGE_STOCK_TRADING -> indicator_code=STOCK_TFR_LARGE`
- 9 条一期真实规则 `remark` 均已同步为真实规则说明
- 结论:数据库元数据异常已修复,可继续进入接口端到端验证。
## 接口验证
- 待补充登录、拉取本行信息、手动重算、流水详情回查与结果摘要。
```bash
curl -s http://localhost:62318/login/test \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"admin123"}'
python3 - <<'PY'
# 读取 3 个有效身份证号并生成 /tmp/bank-tag-pull-request.json
PY
curl -s http://localhost:62318/ccdi/file-upload/pull-bank-info \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
--data-binary @/tmp/bank-tag-pull-request.json
curl -s http://localhost:62318/ccdi/project/tags/rebuild \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"projectId":47,"modelCode":null}'
python3 - <<'PY'
# 轮询 ccdi_bank_tag_task 并查询目标规则命中结果
PY
curl -s "http://localhost:62318/ccdi/project/bank-statement/detail/66679" \
-H "Authorization: Bearer $TOKEN"
```
- 登录结果:
- 返回 `code=200`token 非空。
- 拉取本行信息结果:
- 选择身份证号:`558455197203132040``523342199111246421``38056420050404632X`
- 接口返回 `{"msg":"拉取任务已提交","code":200,...}`
- 自动触发任务 `id=36``trigger_type=AUTO_PULL_BANK_INFO`,状态 `SUCCESS`
- 手动重算结果:
- 首次调用命中项目级重算锁,返回“当前项目标签正在重算中,请稍后再试”。
- 自动拉取任务完成后再次调用,返回 `{"msg":"标签重算任务已提交","code":200}`
- 最新任务 `id=37`,状态 `SUCCESS``hit_count=3481``success_rule_count=33``failed_rule_count=0`
- 命中结果查询:
- 已查到目标规则命中,包括:
- `WITHDRAW_CNT`
- `GAMBLING_SENSITIVE_KEYWORD`
- `LARGE_PURCHASE_TRANSACTION`
- 样例明细:
- `rule_code=GAMBLING_SENSITIVE_KEYWORD`
- `bank_statement_id=66679`
- `reason_detail=摘要/对手命中赌博敏感词,摘要“游戏充值”,对手方“欢乐游戏科技有限公司”,支出金额 6888.00 元`
- 详情接口回查:
- `GET /ccdi/project/bank-statement/detail/66679` 返回 `code=200`
- `data.hitTags` 中包含 `GAMBLING_SENSITIVE_KEYWORD`
## 补充复验
- 2026-03-20 16:01 左右,基于修复后的详情查询 SQL 再次执行项目 `47` 端到端链路验证。
- 登录结果:
- `POST /login/test` 返回 `code=200`token 非空。
- 拉取本行信息结果:
- 仍使用身份证号 `558455197203132040``523342199111246421``38056420050404632X`
- `POST /ccdi/file-upload/pull-bank-info` 返回 `{"msg":"拉取任务已提交","code":200,...}`
- 自动触发任务 `id=39``trigger_type=AUTO_PULL_BANK_INFO`,状态 `SUCCESS`
- `hit_count=3636``success_rule_count=33``failed_rule_count=0`
- 手动重算结果:
- `POST /ccdi/project/tags/rebuild` 直接返回 `{"msg":"标签重算任务已提交","code":200}`
- 最新任务 `id=40``trigger_type=MANUAL`,状态 `SUCCESS`
- `hit_count=3636``success_rule_count=33``failed_rule_count=0`
- 命中样例回查:
- 最新 `GAMBLING_SENSITIVE_KEYWORD` 命中样例为 `bank_statement_id=67279`
- `reason_detail=摘要/对手命中赌博敏感词,摘要“游戏充值”,对手方“欢乐游戏科技有限公司”,支出金额 6888.00 元`
- 详情接口回查:
- `GET /ccdi/project/bank-statement/detail/67279` 返回 `code=200`
- 返回结果包含 `originalFileName=558455197203132040_10001.csv`
- `data.hitTags` 中包含 `GAMBLING_SENSITIVE_KEYWORD`
## 结论
- 待本次验证全部执行完成后补充
- 首次执行在数据库核验阶段发现第一期规则元数据异常,问题已定位并修复
- 修复后重新验证结果如下:
- Mock 自动化回归通过。
- 主工程第一期真实规则自动化回归通过。
- 数据库采购基线与第一期规则元数据核验通过。
- 项目 `47` 的自动拉取、手动重算、规则命中查询与详情接口回查通过。
- 补充复验确认:重复上传记录场景下,流水详情接口已不再出现 `selectOne()` 结果重复异常。
- 最终结论:本次“新增模型打标完整验证”在修复元数据缺口后已通过。
## 环境清理
- 待补充本次验证启动的 Mock 与后端进程清理结果。
- 已停止本次复验启动的 Mock 服务与后端 Jar 服务。
- 端口复核结果:
- `62318` 无监听进程
- `8000` 无监听进程