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

5.8 KiB
Raw Permalink Blame History

服务机构端 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。