5.8 KiB
服务机构端 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
- 表命名:
qc(质控记录,无前缀,与 settlement/report 一致);补正表ho_record_correction(补正属留痕域,循 ho_ 前缀)。待用户确认。 - 全量质控:定时任务(
@Cron每小时)扫描record_status='submitted'且无 qc 记录的留痕 → 生成一条 qc(qc_result='pending')。非抽检=落库保证。 - qc 生命周期:
pending→passed(放行,写 pass_time)/returned(退回,qc_note 必填);退回后护理员补正 → record 重新 submitted → 新 qc(qc_type='recheck',first_qc_id指向首次)。 - 放行前自检(按序):① 留痕四要素齐(时间/项目/时长/护理员,否则
1004)→ ② 必拍已拍(否则3001)→ ③ 状态=待质控(幂等,已放行提示)→ ④ 放行人 ≠ 录入人(否则4001自审自放行)。 - 五类主动推送 =
GET /qc/pending/list的聚合(跨表查询,非 qc 表落库):异常待处理(abnormal.handle_status=open)、逾期未做(order 过时段无 record 超 24h)、住院仍有派单(elder.treat_status=hosp_pause 且有未完成 order)、计划未制定(elder 待遇生效 5 工作日无 active plan)、留痕待放行(qc pending)。每类带消除条件 + 优先级。 - 异常联动改计划:质控员判断异常需加专项 → 复用
plan.change生成新 plan + 回填record_abnormal.link_plan_change=true。 - 补正:退回后补正 = 新增更正说明(不直接改原记录);不可补正签到时间/定位/照片;补正次数不限、每次留痕;同记录补正 ≥3 次 ⇒ 自动进质控重点。补正落
ho_record_correction。 - 批量放行边界:有异常/未执行项/临时加项/时长异常/补正过的记录一律不可批量放行。
- 主键口径: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。