# Special Check Family Asset Liability Backend Implementation Plan

> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** 为专项排查页新增“员工家庭资产负债专项核查”后端查询能力，支持项目内员工列表出数与单个员工家庭收入、资产、负债明细展开。

**Architecture:** 采用专项核查专用查询链路，不复用结果总览员工结果表。新增 `CcdiProjectSpecialCheckController + Service + Mapper`，按项目内已入库流水命中的员工范围聚合本人与配偶的收入、资产、征信本金余额，并拆成列表接口与详情接口两条只读查询。

**Tech Stack:** Java 21, Spring Boot 3, MyBatis XML, Maven, JUnit 5

---

### Task 1: 定义专项核查接口契约、DTO 与 VO

**Files:**
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectSpecialCheckController.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectSpecialCheckService.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectFamilyAssetLiabilityListQueryDTO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectFamilyAssetLiabilityDetailQueryDTO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListItemVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyIncomeDetailVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetItemVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetDetailVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyDebtItemVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyDebtDetailVO.java`
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityDetailVO.java`
- Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectSpecialCheckControllerContractTest.java`

- [ ] **Step 1: Write the failing test**

为控制器契约补静态/反射测试，锁定以下路径和方法：

- `GET /ccdi/project/special-check/family-asset-liability/list`
- `GET /ccdi/project/special-check/family-asset-liability/detail`

并锁定 DTO / VO 基本字段：

- 列表入参：`projectId`
- 详情入参：`projectId`、`staffIdCard`
- 列表项：`staffIdCard`、`staffCode`、`staffName`、`deptName`、`totalIncome`、`totalAsset`、`totalDebt`、`comparisonAmount`、`riskLevelCode`、`riskLevelName`
- 详情：`incomeDetail`、`assetDetail`、`debtDetail`、`summary`

- [ ] **Step 2: Run test to verify it fails**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckControllerContractTest
```

Expected:

- `FAIL`
- 原因是控制器、DTO、VO 尚未创建

- [ ] **Step 3: Write minimal implementation**

补齐控制器、服务接口、DTO 与 VO。

控制器要求：

- 继续使用 `@Tag`、`@Operation`
- 权限沿用 `@PreAuthorize("@ss.hasPermi('ccdi:project:query')")`
- 返回统一使用 `AjaxResult.success(...)`

DTO 要求：

- 使用独立 DTO，不直接裸接 `Long`
- `projectId`、`staffIdCard` 做基础非空约束

- [ ] **Step 4: Run test to verify it passes**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckControllerContractTest
```

Expected:

- `PASS`

- [ ] **Step 5: Commit**

```bash
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectSpecialCheckController.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectSpecialCheckService.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectFamilyAssetLiabilityListQueryDTO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectFamilyAssetLiabilityDetailQueryDTO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListItemVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyIncomeDetailVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetItemVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetDetailVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyDebtItemVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyDebtDetailVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityDetailVO.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectSpecialCheckControllerContractTest.java
git commit -m "定义专项核查家庭资产负债接口契约"
```

### Task 2: 实现项目员工范围与列表聚合 SQL

**Files:**
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapper.java`
- Create: `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml`
- Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapperListSqlTest.java`

- [ ] **Step 1: Write the failing test**

新增 Mapper XML 测试，锁定以下核心 SQL 口径：

- 项目员工范围沿用“项目内已入库流水命中且能匹配员工主数据”的口径
- 配偶通过 `relation_type = '配偶'` 识别
- 收入使用 `annual_income`
- 资产使用 `current_value`
- 负债使用 `principal_balance`
- 风险等级边界为 `<= 1.5`、`> 1.5 and <= 3`、`> 3`

- [ ] **Step 2: Run test to verify it fails**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckMapperListSqlTest
```

Expected:

- `FAIL`

- [ ] **Step 3: Write minimal implementation**

在 `CcdiProjectSpecialCheckMapper.xml` 中实现列表查询。

实现要求：

- 先抽取项目员工基础集合，避免明细聚合时丢失“无资产/无负债/无配偶”的员工
- 家庭总年收入 = 本人年收入 + 配偶年收入，均需 `COALESCE(..., 0)`
- 家庭总资产需限定持有人为“员工本人 + 配偶”
- 家庭总负债需限定归属人为“员工本人 + 配偶”
- 输出 `comparisonAmount = totalIncome + totalDebt`
- 风险等级同时输出 `riskLevelCode` 和 `riskLevelName`
- 排序建议先按风险等级倒序，再按 `comparisonAmount desc`，最后按 `staff_name asc`

- [ ] **Step 4: Run test to verify it passes**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckMapperListSqlTest
```

Expected:

- `PASS`

- [ ] **Step 5: Commit**

```bash
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapper.java ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapperListSqlTest.java
git commit -m "补充专项核查家庭资产负债列表查询"
```

### Task 3: 实现详情聚合 SQL 与明细结构

**Files:**
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapper.java`
- Modify: `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml`
- Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapperDetailSqlTest.java`

- [ ] **Step 1: Write the failing test**

新增详情查询 XML 测试，锁定以下内容：

- 详情必须返回收入、资产、负债三组结构
- 资产明细包含：资产名称、大类、小类、持有人、当前估值、估值日期
- 负债明细包含：负债名称、大类、小类、债权人类型、归属人、本金余额、查询日期
- 本人与配偶小计必须拆开

- [ ] **Step 2: Run test to verify it fails**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckMapperDetailSqlTest
```

Expected:

- `FAIL`

- [ ] **Step 3: Write minimal implementation**

在 Mapper 中新增详情查询与结果映射。

实现要求：

- 详情接口按 `projectId + staffIdCard` 查询
- 先校验该员工属于当前项目员工范围，再返回详情
- 资产、负债列表都要显式带出“归属人”名称或证件号映射
- 详情返回值中保留 `summary`，避免前端展开区自行重复计算
- 对空列表返回空数组，不返回 `null`

- [ ] **Step 4: Run test to verify it passes**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckMapperDetailSqlTest
```

Expected:

- `PASS`

- [ ] **Step 5: Commit**

```bash
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapper.java ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectSpecialCheckMapperDetailSqlTest.java
git commit -m "补充专项核查家庭资产负债详情查询"
```

### Task 4: 完成服务组装与控制器返回

**Files:**
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImpl.java`
- Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImplTest.java`
- Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectSpecialCheckControllerTest.java`

- [ ] **Step 1: Write the failing test**

补服务层与控制器测试，覆盖：

- 项目不存在时返回统一异常
- 列表接口返回空列表而不是 `null`
- 详情接口在员工不属于当前项目时返回明确错误
- 详情 `summary` 中金额与列表同口径

- [ ] **Step 2: Run test to verify it fails**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckServiceImplTest,CcdiProjectSpecialCheckControllerTest
```

Expected:

- `FAIL`

- [ ] **Step 3: Write minimal implementation**

在服务层：

- 校验项目存在性
- 调用 Mapper 查询列表与详情
- 空数据场景统一封装为空列表或空明细结构
- 不在服务层新增与本次需求无关的缓存、异步、预计算逻辑

在控制器层：

- 直接接收 DTO
- 维持 GET 查询模式
- 返回 `AjaxResult.success(...)`

- [ ] **Step 4: Run test to verify it passes**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckServiceImplTest,CcdiProjectSpecialCheckControllerTest
```

Expected:

- `PASS`

- [ ] **Step 5: Commit**

```bash
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImpl.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImplTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectSpecialCheckControllerTest.java
git commit -m "完成专项核查家庭资产负债服务组装"
```

### Task 5: 写实施记录与验证记录

**Files:**
- Create: `docs/reports/implementation/2026-03-24-special-check-family-asset-liability-backend-record.md`
- Create: `docs/tests/records/2026-03-24-special-check-family-asset-liability-backend-verification.md`

- [ ] **Step 1: Write implementation record**

在 `docs/reports/implementation/2026-03-24-special-check-family-asset-liability-backend-record.md` 中记录：

- 本次新增的接口、Mapper、DTO、VO、测试文件
- 项目员工范围口径
- 收入、资产、负债、风险等级的计算口径
- 未扩展到其他家庭成员的范围说明

- [ ] **Step 2: Run targeted verification and record output**

Run:

```bash
mvn test -pl ccdi-project -Dtest=CcdiProjectSpecialCheckControllerContractTest,CcdiProjectSpecialCheckMapperListSqlTest,CcdiProjectSpecialCheckMapperDetailSqlTest,CcdiProjectSpecialCheckServiceImplTest,CcdiProjectSpecialCheckControllerTest
```

Expected:

- `PASS`

将实际执行命令、结果和结论记录到 `docs/tests/records/2026-03-24-special-check-family-asset-liability-backend-verification.md`。

- [ ] **Step 3: Commit**

```bash
git add docs/reports/implementation/2026-03-24-special-check-family-asset-liability-backend-record.md docs/tests/records/2026-03-24-special-check-family-asset-liability-backend-verification.md
git commit -m "补充专项核查家庭资产负债后端记录"
```
