liuyun 3afd009420 docs(openspec): C1 待遇档案 change 提案 + 归档 C0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 14:21:25 +08:00

55 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## Context
C0 已落地机构=租户、RBAC、目录四层、菜单、多租户过滤(PrismaService 注入 tenantCode)。C1 新增待遇档案域(elder + elder_status_log),纯新增、不侵入脚手架。设计背景见 `docs/superpowers/specs/2026-10-14-服务机构端-C1待遇档案-design.md`。
## Goals / Non-Goals
**Goals:**
- elder 建档(身份证校验/防重、参保核验留痕、评估结论承载)。
- 十态待遇状态机 + elder_status_log 变更留痕。
- 评估结论副本上传(MinIO)+ 等级唯一来源约束。
- 身份证服务端掩码 + 明文查看留痕。
**Non-Goals:**
- OCR、Excel 批量导入、elder_svc、评估结论打水印、id_card_no 存储层加密、官方接口拉评估结论、need_assess 采集交互。
## Decisions
1. **文件存储用 MinIO**(`http://localhost:9000`,bucket `carelink`,minioadmin/minioadmin)。抽象 `StorageService.upload(buffer, key)` 接口,内部用 `minio` 官方包;后续切腾讯云 COS 只换实现与配置。
2. **等级唯一来源=「评估结论副本 + 评估结论字段」绑定**:建档时 `assess_level/care_level/assess_date/assess_org` 与 `assess_evidence_file` 绑定——有副本才能填等级,填等级必须有副本。前端不提供「直接填等级」的自由入口,等级区块 = 上传副本 + 录入评估结论字段。
3. **身份证掩码在服务端**:`maskIdCard()` 返回 `前4 + 10个* + 后4`(18 位)/`前3+*+后4`(15 位兜底)。列表用掩码;详情仅 admin/qc 可明文 + 落审计。
4. **id_card_no 存储层加密后置**(与 staff 统一走 security change);C1 明文存 + TODO。掩码/查看留痕 C1 做。
5. **建档初始状态**:`benefit_start ≤ today ≤ benefit_end` → `active`;否则 `waiting_period`。
## 数据模型(DDL 概览)
通用字段 `created_at/by`、`updated_at`、`deleted_at`;主键 UUID v7;`@@map` snake_case;软删。
- **elder**(`sys_elder`):id、tenant_code、loc_code、prev_loc_code、transfer_confirm_at、name、gender(char1)、birth_date、id_card_no(varchar255)、phone、address、guardian_name、guardian_phone、insur_no、insur_type、insur_years、insur_verify_status、insur_verify_date、assess_level、care_level、assess_date、assess_org、assess_evidence_file、benefit_start、benefit_end、treat_status、status_source、status_change_date、hosp_start、hosp_end、photo_tier_override(json)、need_assess(json)、note(text)、biz_line。唯一索引 `(tenant_code, id_card_no)`。
- **elder_status_log**(`sys_elder_status_log`):id、elder_id、from_status、to_status、change_reason(必填)、source、operator_id、evidence_file、changed_at。
PrismaService:`elder`/`elder_status_log` 均为租户级模型(带 tenantCode,自动过滤);`elder` 加入 SOFT_DELETE。
## 接口(`@Controller('elder')`)
| 方法/路径 | 权限 | 说明 |
|---|---|---|
| GET `/elder` | elder:list | 分页 + 状态/等级/姓名筛选;身份证掩码 |
| POST `/elder` | elder:create | 建档(18 位校验、防重、等级与副本绑定) |
| GET `/elder/:id` | elder:detail | 详情;admin/qc 明文 + 审计 |
| POST `/elder/:id/status` | elder:status-change | 变更状态,change_reason 必填,写日志 |
| GET `/elder/:id/status/log` | elder:detail | 状态日志 |
| POST `/elder/assess-evidence` | elder:create | 上传副本到 MinIO,返回 key |
权限码 `elder:list/create/detail/status-change` 已在 C0 permissions.ts 预留;APIS 数组登记 6 条资源(parent=elder 菜单)。
## Risks / Trade-offs
- [评估结论副本是合规证据,本地 MinIO 单点] → 副本 key 存 elder 表、MinIO 数据卷已挂本机;生产切 COS(异地冗余)。
- [等级唯一来源依赖「有副本」约束,机构可能绕过] → 后端强制校验 assess_evidence_file 与 assess_level 绑定,前端不提供自由填等级入口。
- [明文查看留痕依赖审计拦截器] → `/elder/:id` 明文分支显式写 audit-log。
## Migration Plan
新增迁移建 `sys_elder` + `sys_elder_status_log`(utf8mb4_general_ci,迁移 SQL 手改 collation)。回滚=删除迁移。