touyun-elderly-care/docs/superpowers/specs/2026-10-15-服务机构端-C4质控闸门-design.md
liuyun 7d183d39c9 docs: 服务机构端 C4 质控闸门设计文档
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-15 01:17:45 +08:00

63 lines
5.8 KiB
Markdown
Raw Permalink 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.

# 服务机构端 C4 质控闸门 · 设计文档
> 本文是 C4 质控闸门的设计背景,规范权威见 `openspec/changes/svc-org-c4-qc/`(proposal + specs + design + tasks)与 PRD。
## Context
C0–C3 已落地:elder(十态)、plan/plan_item、order(八态)、ho_record 四表(履约留痕,record_status=submitted)、abnormal(异常上报 + 扑空)、staff、svc_org。C4 新增**质控闸门**:对每条已提交留痕做全量质控(放行/退回)、五类主动推送聚合、异常处理台 + 异常联动改计划、补正。质控放行是「先质控再上报」铁律的代码落地。
## Goals / Non-Goals
**Goals**:`qc` 表 + `ho_record_correction` 补正表;全量质控(定时任务扫描 submitted 留痕生成 qc);放行/退回(4001 禁止自审自放行 + 放行前自检);五类主动推送后台聚合;异常处理台 + 异常联动改计划;补正(原记录保留 + 更正说明);admin 质控中心页(B4)。
**Non-Goals**:上报池(report,二期)、真推送通知(APP/站内信,APP 期)、护理员 APP 补正录入(本期只做后端接口 + admin 查看)、家属端。
## Decisions
1. **表命名**:`qc`(质控记录,无前缀,与 settlement/report 一致);补正表 `ho_record_correction`(补正属留痕域,循 ho_ 前缀)。**待用户确认。**
2. **全量质控**:定时任务(`@Cron` 每小时)扫描 `record_status='submitted'` 且无 qc 记录的留痕 → 生成一条 qc(`qc_result='pending'`)。非抽检=落库保证。
3. **qc 生命周期**:`pending` → `passed`(放行,写 pass_time)/ `returned`(退回,qc_note 必填);退回后护理员补正 → record 重新 submitted → 新 qc(`qc_type='recheck'`,`first_qc_id` 指向首次)。
4. **放行前自检(按序)**:① 留痕四要素齐(时间/项目/时长/护理员,否则 `1004`)→ ② 必拍已拍(否则 `3001`)→ ③ 状态=待质控(幂等,已放行提示)→ ④ **放行人 ≠ 录入人**(否则 `4001` 自审自放行)。
5. **五类主动推送** = `GET /qc/pending/list` 的聚合(跨表查询,非 qc 表落库):异常待处理(abnormal.handle_status=open)、逾期未做(order 过时段无 record 超 24h)、住院仍有派单(elder.treat_status=hosp_pause 且有未完成 order)、计划未制定(elder 待遇生效 5 工作日无 active plan)、留痕待放行(qc pending)。每类带消除条件 + 优先级。
6. **异常联动改计划**:质控员判断异常需加专项 → 复用 `plan.change` 生成新 plan + 回填 `record_abnormal.link_plan_change=true`。
7. **补正**:退回后补正 = 新增更正说明(不直接改原记录);不可补正签到时间/定位/照片;补正次数不限、每次留痕;同记录补正 ≥3 次 ⇒ 自动进质控重点。补正落 `ho_record_correction`。
8. **批量放行边界**:有异常/未执行项/临时加项/时长异常/补正过的记录一律不可批量放行。
9. **主键口径**:UUID v7 VarChar(36)(循代码库)。
## 数据模型(DDL 概览)
通用:UUID v7、`tenant_code`、`@map` snake_case、utf8mb4_general_ci。qc 入 SOFT_DELETE;ho_record_correction 为子表(带 tenant_code、无 deleted_at、不入 SOFT_DELETE,循先例)。
- **qc**:`id`、`tenant_code`、`record_id`、`qc_type`(normal/recheck)、`push_reason`(五类,nullable——仅主动推送线索用)、`qc_result`(pending/passed/returned)、`qc_note`(退回原因,退回必填)、`qc_staff_id`、`qc_time`、`pass_time`、`first_qc_id`(recheck 指向首次)。索引 (tenant_code, record_id)、(tenant_code, qc_result)。
- **ho_record_correction**:`id`、`tenant_code`、`record_id`、`qc_id`(触发补正的退回 qc)、`correction_note`、`corrected_by`、`corrected_at`。索引 (record_id)。
## 接口(`@Controller('qc')`)
- `GET /qc/pending/list` — 待质控列表:五类主动推送聚合(每类计数 + 消除条件)+ 待放行队列(record 待质控,全量)。
- `GET /qc/detail` — 质控详情:留痕全文 + 照片 + 异常 + 补正历史。
- `POST /qc/pass` — 放行:按序自检(1004/3001/幂等/4001)→ qc_result=passed + pass_time。
- `POST /qc/return` — 退回:qc_note 必填 → qc_result=returned。
- `POST /qc/exception/link` — 异常联动改计划:生成新 plan(复用 plan.change)+ abnormal.link_plan_change=true。
- `POST /qc/correct` — 补正:record_id + correction_note → 写 ho_record_correction,record 重新 submitted(触发 recheck)。
- `POST /qc/batch-pass` — 批量放行:排除异常/未执行项/临时加项/时长异常/补正过。
权限码:qc.pendingList/detail/pass/return/exceptionLink/correct/batchPass。错误码域 46(QC_*);规则号 1004/3001/4001 写 message(循 R3 口径)。角色:qc 看全部、leader 本组、admin 兼 qc 可审。
## 硬锁与校验
- **L4**:留痕缺必填要素 → 放行 1004 拒绝。
- **自审自放行**:`record.created_by === qc_staff_id` → 4001 拒绝。
- **必拍未拍** → 3001 拒绝(放行时复检)。
- **五类推送消除条件**:异常已处理/工单有记录或取消/住院工单已取消/已有 active plan/留痕已放行。
## Risks / Trade-offs
- [定时任务 vs 同步生成] → 定时任务兜底(全量保证),代价=质控有延迟(≤1 小时);可后续改 checkout 同步。
- [补正 vs 直接编辑] → 补正=新增说明(不可无痕修改),合规。
- [自审自放行 4001] → 单人机构必须再配一个审的人,这是铁律底线(PRD 明确)。
- [五类推送聚合性能] → 跨 5 表聚合,机构规模小可接受;必要时加物化/缓存。
## Migration Plan
新增 2 表(qc + ho_record_correction)。utf8mb4_general_ci 手改。迁移链已损坏:用 `migrate diff --from-schema-datasource` + 手工迁移目录 + `migrate deploy`。