跳转到主要内容

FSD m09 · 出行协助(trip)

本册覆盖代码域 internal/domain/trip(单表 trip_record,detail JSON 列承载酒店/交通字段差异)。全局规则见 00-总则 §2(trip 状态机 §2.2)。

m09 功能节目录

ID名称路由/入口
F9.01酒店安排POST /api/trips(kind=HOTEL)、POST /api/trips/:id/transition
F9.02交通安排POST /api/trips(kind=TRANSPORT)、POST /api/trips/:id/transition
F9.03患者只读拉取GET /pt/trips

F9.01 酒店安排

对应 SRS:F-TRIP-001 | 实现落点:internal/domain/trip/service.go:60(Create)/Transition(tripTransitions 白名单)/main.go:319-321(路由) | 操作入口:web 工单详情出行协助区「新增记录」(顾问)

1 功能定义

顾问为工单创建酒店安排记录(推荐合作酒店/距离价格翻译服务说明/预订需求/状态记录):kind='HOTEL',字段差异进 detail JSON 列(服务端透传不校验内部结构——SRS §7「首期人工协助,系统仅做记录,不自动对接 OTA」)。状态机 PLANNED→BOOKED→COMPLETED/CANCELLED。

2 触发条件与前置状态

trip:write(CONSULTANT);工单存在(防挂空单——Create 归属校验 404)。

3 输入与校验
字段类型校验
ticket_idint64工单存在性(404 ErrTicketNotFound)
kindenumHOTEL / TRANSPORT(值域见 entity; kind 白名单校验)
titlestring记录标题
scheduled_atdatetime 可空预定时间
detailJSON明细对象(服务端不校验内部结构——零字段级查询 MVP)
notestring 可空备注

JSONBytes 类型:Scan/Marshal 双实现(json.RawMessage 无 sql.Scanner——活体 SELECT * 即 500 的「双处登记」教训型修正,⚠ DIF-M8 ⑧)。

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

记录 JSON(id/ticket_id/kind/title/status/scheduled_at/detail/note/version…——json tag snake_case,DIF-M8 ⑧ 整形);患者端 /pt/trips 可见(F9.03)。

6 状态流转

PLANNED → {BOOKED, CANCELLED};BOOKED → {COMPLETED, CANCELLED};CANCELLED/COMPLETED 终态不可迁(tripTransitions 白名单+守卫测试锁定);lifecycle entity_type=‘trip’(无专属 trip_log 表——双日志轨兑现六原则,DIF-M7 ①)。

7 边界与异常
场景行为
工单不存在404
白名单外流转(如 PLANNED→COMPLETED)409 ErrInvalidTripTransition
并发流转409(status 谓词 CAS)
OTA 对接不做(SRS §7 明示人工协助——枚举与 detail 结构为未来演进留位)
8 权限与数据规则

trip:write 创建与流转;ticket:read 工单聚合读(web 详情);detail JSON 原生存储无注入面(JSONBytes 序列化边界)。


F9.02 交通安排

对应 SRS:F-TRIP-002 | 实现落点:同 F9.01(kind='TRANSPORT' 同一 Create/Transition 路径) | 操作入口:web 工单详情出行协助区「新增记录」

1 功能定义

顾问创建交通安排记录(机场接送/就医期间交通/信息同步):与 F9.01 完全同构,仅 kind='TRANSPORT';detail JSON 承载航班号/接送点等字段差异。

2 触发条件与前置状态

同 F9.01(trip:write + 工单存在)。

3 输入与校验

同 F9.01(kind 值域差异)。

4 处理流程

同 F9.01 §4。

5 输出与结果状态

同 F9.01;工单时间线出行节点内嵌展示。

6 状态流转

同 F9.01。

7 边界与异常

同 F9.01(kind 与状态机正交——状态机不区分酒店/交通)。

8 权限与数据规则

同 F9.01。


F9.03 患者只读拉取(/pt/trips)

对应 SRS:F-TRIP(患者可见信息同步) | 实现落点:internal/domain/trip/service.go:113(ListByPatient)/main.go:322(路由) | 操作入口:app H5 #/pages/progress 出行信息区

1 功能定义

患者拉取本人最新工单的出行协助记录(只读):直查口径沿 DIF-M6 ⑤(patient_id→最新工单→ListByTicket)。无 SSE 推送(患者拉取式——DIF-M7 ⑦ 明确不做清单:SSE 注册表守卫不扩面)。

2 触发条件与前置状态

pt JWT;无工单返回空列表(非 404——进度页语义)。

3 输入与校验

无入参(patient_id=claims.Sub)。

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

记录数组(同 F9.01 JSON 形态)。

6 状态流转

只读;患者不可创建/流转出行记录。

7 边界与异常
场景行为
无工单200 空列表
SSE 实时性无——打开进度页时拉取(拉取式口径)
多工单最新一单的记录(一人一单 MVP 语义)
8 权限与数据规则

pt JWT + patient_id 直查(不走权限码);记录全量可见(无字段级脱敏——出行信息非敏感 PII)。