上门预约系统若把 push 发送写在状态事务里,通道超时会导致状态回滚或半成功。宜事务内只改 appointment 行,通知走 outbox 异步。
结论
状态真相在 appointments 表;notifier 读 event 推送,失败可重试。
func(s*Service)Dispatch(ctx context.Context,idstring,workerIDstring)error{returns.db.Tx(ctx,func(tx*sql.Tx)error{iferr:=tx.SetStatus(id,"dispatched",workerID);err!=nil{returnerr}returntx.InsertOutbox("AppointmentDispatched",id)})}Tx 内改 status + outbox;notifier 失败可重试。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
一、用户端轮询与 etag
GET /appointments/{id} 返回 status + updated_at,客户端 If-None-Match 减流量。关键节点 push 仅作提醒。
GET appointment etag 减流量。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
二、时间窗 slot 模型
slot 表 (worker_id, start, end, status)。改约释放旧 slot、锁定新 slot 同一事务。
UPDATEslotsSETstatus='free'WHEREid=?;UPDATEslotsSETstatus='booked'WHEREid=?;slot booked/free 同事务。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
三、迟到计算
compare now() with window_end,写 delay_minutes 字段供客服与 export。
delay_minutes 写库。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
四、验收附件
complete API 接受 media_ids,异步 virus scan 后挂 appointment。
media 异步 scan 后挂载。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
五、测试单
is_test flag,报表默认排除。
is_test 过滤。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
六、光合同城边界
国内综合版含预约状态机基础;复杂 SLA 引擎单列。
复杂 SLA 单列。
实施时建议固定 golden 样本单号,在预发与生产各留用户端、后台、导出三处截图;列名或状态枚举变更走书面版本号,避免财务周结时才发现对不上历史单。
七、slot 库存与并发
高并发改约场景下 slot 行宜乐观锁或 select for update,避免同一时段被两人同时预约。压测宜模拟改约高峰,而不只测下单峰值。预约窗口跨越 DST 变更时,存储 UTC 时间,展示按用户时区。师傅拒单后 slot 释放与 outbox 发取消通知同一事务,用户端看到「已取消」而非永久「待服务」。
延迟字段 delay_minutes 供 BI 与客服报表。export 含 worker_id、window_start、window_end、completed_at,财务按完成时间周结。is_test 预约默认不进营收报表,但宜在 QA 环境保留查询入口。
八、小结
拆通知与状态,用 outbox 保一致。试跑 dispatched→in_service→completed,用户端每步可见。拒单回退 booked 并释放 slot,outbox 发取消通知。导出宜含 worker_id、window、completed_at 供结算核对。上线后每月用同一 appointment_id 回归,确认用户端进度仍随师傅节点更新;列名变更 bump 版本并留财务 sample,避免周结对不上历史单。QA 环境保留 is_test 查询入口,便于复现进度不同步类缺陷而不污染正式报表。改约高峰前宜做 slot 并发压测,避免双 booking 与超卖时段,并留审计日志备查。