跳转到主要内容

FSD m06 · 预诊断与方案(diagnosis)

本册覆盖代码域 internal/domain/diagnosis(无新表——医生输出落 ticket 列,状态变更走 ticket.TransitionInTx 唯一入口)。全局规则见 00-总则 §2。

m06 功能节目录

ID名称路由/入口
F6.01医生工作台(预诊+专家选人 dept 锚)GET /api/diagnosis/pending、GET /api/diagnosis/experts、POST /api/diagnosis/:ticketId
F6.02拒绝与重派POST /api/diagnosis/:ticketId/reject
F6.03患者方案确认GET /pt/plan、POST /pt/plan/confirm

F6.01 医生工作台(预诊+专家选人 dept 锚)

对应 SRS:F-DIAG-001(专家选人为 M10 扩展,SRS 未细化) | 实现落点:internal/domain/diagnosis/service.go:47(PendingList)/:78(Submit)/:229(ExpertOptions)/main.go:259-262(路由) | 操作入口:web /admin/diagnosis 医生待诊页(列表→病历预览 Modal→填意见/选专家→提交)

1 功能定义

医生查看 PREDIAGNOSING 工单待诊列表、在线预览病历(复用 F5.04 代理 blob 前端渲染)、按科室锚定查询 PUBLISHED 专家并选人(或手填)、提交预诊意见/方案/推荐科室/预估天数与费用。提交=写 ticket 列(version CAS)→ 流转 PLAN_CONFIRMING → 患者邮件(plan_ready)同事务 → Commit 后三 key SSE。

2 触发条件与前置状态
  • diag:write(仅 DOCTOR);工单须处于 PREDIAGNOSING(白名单前置校验+事务内兜底双重)。
  • 病历在线预览为纯前端(Modal 内 img/pdf 原生渲染,后端零改动——⚠ DIF-M6 ⑨)。
3 输入与校验
字段类型校验
prediagnosis_summarystring必填语义(医生意见)
planstring治疗方案文本
dept_idint64推荐科室
expert_idint640=手填/存量哨兵;>0 时事务内一查两用(校验归属+上架态,取「姓名(职称)」快照)
expertstring手填推荐专家(’’ 允许;ExpertID>0 时被快照覆盖)
estimate_daysint预估停留天数(0 允许)
estimate_amountfloat64预估总费用(0=未填哨兵 → 定金回落固定额,payment.DepositCents 消费)
estimate_currencystring缺省服务端兜底 USD

GET /api/diagnosis/experts?dept_id=:dept_id<=0 → 空列表;仅 status='PUBLISHED' 专家,ORDER BY sort,id。

4 处理流程
5 输出与结果状态

待诊列表/专家选项 JSON;提交 204;患者收 plan_ready 邮件 + /pt/plan 可见方案(F6.03)。

6 状态流转

PREDIAGNOSING → PLAN_CONFIRMING(A 轴正向边);ticket.hospital_id 自 M4 建单以来首次有写路径(选专家=确认院区,工单已绑院且与专家归属不符 → 409——ValidateExpertSelection 纯函数)。

7 边界与异常
场景行为
专家不存在404 ErrExpertNotFound(⚠ DIF-M10 ③ M10 核查 A3 收口:原 400 改 404 与 ErrOrderNotFound 同形,mapErr 同映)
专家非 PUBLISHED / 归属院区与工单不符409(ValidateExpertSelection)
工单非 PREDIAGNOSING409 ErrInvalidTransition(白名单前置)
version 竞态409(写列 CAS 命中 0 行)
专家快照不可变——专家改名/下架不回写历史方案(医疗记录语义,⚠ DIF-M10 ④)
estimate_amount=0定金回落 config 固定额(M6 单测断言 200.0 兼容证明)
8 权限与数据规则

diag:write(DOCTOR 专属);医生选人端点同挂 diag:write(14 码矩阵不扩——⚠ DIF-M10 ⑤ 权限面不蔓延);dept 锚设计根据=ticket.hospital_id 预诊前恒 0 不可作 JOIN 锚(M10 核查 B3/B5)。


F6.02 拒绝与重派

对应 SRS:F-TICK-002(「医生确认/拒绝」,M6 裁决 4 补齐) | 实现落点:internal/domain/diagnosis/service.go:154(Reject)/main.go:262(路由) | 操作入口:web /admin/diagnosis 待诊详情「拒绝」按钮

1 功能定义

医生拒绝预诊请求:状态机回退边 3(PREDIAGNOSING→PENDING_ASSIGN)+ INBOX 通知顾问重新分配(doctor_rejected 模板,同事务)。零写路径(拒绝只流转不写列)。

2 触发条件与前置状态

diag:write;工单须 PREDIAGNOSING;reason 必填。

3 输入与校验
字段类型校验
reasonstring必填(400);拼入 op_log reason「医生拒绝预诊请求:+reason」
4 处理流程
5 输出与结果状态

204;顾问 INBOX 收到重派待办(payload={ticket_no, reason});工单回到待分配。

6 状态流转

回退边 3(白名单内唯一由 DOCTOR 触发的回退边);lifecycle from/to 记录回退轨迹。

7 边界与异常
场景行为
工单非 PREDIAGNOSING409(白名单前置)
reason 空400
version 竞态409
8 权限与数据规则

diag:write;INBOX recipient=role:CONSULTANT(角色谓词待办)。


F6.03 患者方案确认

对应 SRS:F-DIAG-002 | 实现落点:internal/domain/diagnosis/service.go:190(ConfirmByPatient)/:260(PatientPlan)/main.go:263-264(路由) | 操作入口:app H5 #/pages/progress 方案卡片(查看→确认)

1 功能定义

患者在确认前查看方案(/pt/plan——F-DIAG-002「确认方案前看方案」语义闭环,DIF-M7 ⑤ 补齐)、确认后进入支付(PLAN_CONFIRMING→PENDING_PAYMENT,「进入支付」,支付本身 M6 接续)。

2 触发条件与前置状态

pt JWT;本人最新工单(直查口径 WHERE patient_id=? ORDER BY id DESC LIMIT 1——越权不可能 claims 即身份,⚠ DIF-M6 ⑤);确认须 PLAN_CONFIRMING。

3 输入与校验
端点输入校验
GET /pt/plan无无工单 404;预诊前字段零值/nil(前端按 status 渲染)
POST /pt/plan/confirm无TransitionInTx 白名单(非 PLAN_CONFIRMING 409)
4 处理流程
5 输出与结果状态

方案视图 JSON(含专家快照/预估天数/费用/币种);确认 204;SSE ticket 事件双端刷新。

6 状态流转

PLAN_CONFIRMING → PENDING_PAYMENT(A 轴正向边;actor=PATIENT id,op_log reason「患者在线确认诊疗方案」)。

7 边界与异常
场景行为
无工单404
非 PLAN_CONFIRMING(重复确认/未到阶段)409
回退边 1 触发后(支付失败重谈)工单回 PLAN_CONFIRMING,患者可再次确认
8 权限与数据规则

pt JWT + patient_id 直查(不走权限码);方案文本 prediagnosis_summary/plan 为 NULL 豁免列(「尚未发生」语义)。