修复流水详情原始文件关联与Mock随机logId
This commit is contained in:
@@ -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` 无监听进程
|
||||
|
||||
Reference in New Issue
Block a user