# LSFX Mock 数据库身份绑定实施计划

> **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:** 让 `lsfx-mock-server` 在创建 `logId` 时从员工信息库随机选择一个员工，并读取该员工亲属，后续同一 `logId` 的流水仅使用这组数据库身份。

**Architecture:** 在 Mock 服务中新增一个只读身份仓储，负责从 `ccdi_base_staff` 与 `ccdi_staff_fmy_relation` 读取员工及亲属。`FileService` 在创建 `FileRecord` 时写入选中的员工/亲属身份，`StatementService` 只复用该记录中的证件号，不再依赖内置固定身份证池。

**Tech Stack:** FastAPI, Python 3.9, PyMySQL, pytest

---

### Task 1: 补数据库身份绑定失败测试

**Files:**
- Modify: `lsfx-mock-server/tests/test_file_service.py`
- Modify: `lsfx-mock-server/tests/test_statement_service.py`

- [ ] Step 1: 写出 `FileService` 需要保存员工与亲属身份的失败测试
- [ ] Step 2: 运行对应测试，确认当前实现失败
- [ ] Step 3: 写出 `StatementService` 只能使用该员工及其亲属证件号的失败测试
- [ ] Step 4: 运行对应测试，确认当前实现失败

### Task 2: 新增只读身份仓储

**Files:**
- Create: `lsfx-mock-server/services/staff_identity_repository.py`
- Modify: `lsfx-mock-server/config/settings.py`
- Modify: `lsfx-mock-server/requirements.txt`

- [ ] Step 1: 定义员工/亲属身份查询结果结构与仓储接口
- [ ] Step 2: 接入 MySQL 只读查询配置
- [ ] Step 3: 实现“随机取一个有身份证号员工 + 读取该员工有效亲属”的最小查询逻辑
- [ ] Step 4: 保持仓储可被测试替身替换

### Task 3: 将 logId 与数据库身份绑定

**Files:**
- Modify: `lsfx-mock-server/services/file_service.py`
- Modify: `lsfx-mock-server/services/statement_service.py`
- Modify: `lsfx-mock-server/routers/api.py`

- [ ] Step 1: 在 `FileRecord` 中增加员工/亲属身份字段
- [ ] Step 2: 在上传文件与拉取行内流水时写入随机员工及其亲属
- [ ] Step 3: 在流水生成阶段只使用 `FileRecord` 中的员工/亲属证件号
- [ ] Step 4: 保留 deterministic fallback，但不影响真实记录链路

### Task 4: 回归验证与文档沉淀

**Files:**
- Create: `docs/reports/implementation/2026-03-19-lsfx-mock-db-backed-identity-selection-fix.md`

- [ ] Step 1: 运行 `lsfx-mock-server` 相关测试
- [ ] Step 2: 记录根因、改动点和验证结果
