# LSFX Mock Server 异常账户基线同步后端实施记录

**日期**: 2026-03-31  
**范围**: `lsfx-mock-server` 异常账户基线同步后端

## 1. 本次实施内容

本次后端完成以下改动：

- 新增 `AbnormalAccountBaselineService`
  - 复用 `settings.CCDI_DB_*` 连接真实数据库
  - 以 `account_no` 为唯一键向 `ccdi_account_info` 执行幂等 upsert
  - 固定写入最小命中字段：`DEBIT`、`EMPLOYEE`、`兰溪农商银行`、`LXNCSY`、`CNY`、`HIGH`
- 调整 `FileService`
  - 新增 `abnormal_account_baseline_service` 注入点
  - 在 `fetch_inner_flow(...)` 和上传建档链路中，先同步异常账户基线，再写入 `file_records`
  - 当存在异常账户命中计划但未生成 `abnormal_accounts` 时直接抛错
- 锁定 `StatementService` 链路一致性
  - 继续保持只读 `FileRecord` 生成异常账户样本流水
  - 通过新增测试确认不会用主账号覆盖异常账户样本自身的 `accountMaskNo`

## 2. 关键实现语义

- 基线同步触发点固定在建 `logId` 阶段，不放到 `getBSByLogId`
- 异常账户事实为空时直接跳过，不做无意义写库
- 任一 `owner_id_card` 与当前 `staff_id_card` 不一致时，立即失败
- 数据库写入失败时执行回滚，并且本次 `logId` 不进入 `file_records`
- 同一个 `logId` 下：
  - `record.abnormal_accounts`
  - 返回的异常账户样本流水
  - `ccdi_account_info` 中的最小账户事实
  保持账号级一致

## 3. 测试补充

本次新增或扩展了以下测试：

- `tests/test_file_service.py`
  - 校验 `fetch_inner_flow(...)` 会在缓存前调用异常账户基线同步
  - 校验同步失败时不会留下半成品 `logId`
- `tests/test_abnormal_account_baseline_service.py`
  - 校验空输入跳过
  - 校验证件号不一致直接失败
  - 校验按账号插入
  - 校验按账号更新
- `tests/test_statement_service.py`
  - 校验异常账户样本流水仅使用 `record.abnormal_accounts` 中的账号

## 4. 实施结果

- `FileService -> AbnormalAccountBaselineService -> StatementService` 的职责边界保持清晰
- 异常账户基线写库与内存建档顺序已固定为“先同步、后缓存”
- 异常账户样本流水与账户事实的一致性已通过测试锁定
- 本轮未扩展接口协议，也未新增补丁式降级链路
