spec.md 7.4 KB

Feature Specification: 闪送订单状态变更消息推送

Feature Branch: 028-flash-delivery-push

Created: 2026-09-17

Status: Draft

Input: User description: "闪送订单状态变更消息推送:骑手抢单、已取件、已送达推送给用户端;用户/平台取消推送给骑手端。新任务发布(待抢单)不推送,加小费不推送。"

User Scenarios & Testing (mandatory)

User Story 1 - 寄件用户收到骑手接单通知 (Priority: P1)

寄件用户下单后处于等待状态,骑手抢单成功的瞬间,用户收到一条推送,告知订单已被骑手接单、骑手正在前来取件。

Why this priority: 用户下单后最焦虑的时段是"有没有人接单";接单通知是整个推送体系里价值最高的单条消息,没有它用户只能反复刷新订单页。

Independent Test: 创建一笔待接单的闪送订单,骑手账号执行抢单,验证寄件用户收到"骑手已接单"推送。

Acceptance Scenarios:

  1. Given 订单状态为 WAITING_ACCEPTANCE,When 骑手抢单成功(状态转为 ACCEPTED),Then 寄件用户在短时间内收到推送,内容表明骑手已接单并包含订单标识。
  2. Given 抢单因并发失败(订单已被他人抢走或已取消),When 抢单请求落空,Then 不产生任何推送。

User Story 2 - 寄件用户收到取件与送达通知 (Priority: P1)

履约中段,骑手确认取件、确认送达两个节点,寄件用户分别收到推送,掌握物品在途与签收进度。

Why this priority: 与接单通知共同构成完整的履约进度感知;送达通知同时提示用户可去确认收货。

Independent Test: 对一笔已接单订单依次执行取件(附凭证)、送达(附凭证),验证寄件用户先后收到两条对应推送。

Acceptance Scenarios:

  1. Given 订单状态为 ACCEPTED,When 骑手确认取件成功(状态转为 PICKED_UP),Then 寄件用户收到"骑手已取件"推送。
  2. Given 订单状态为 PICKED_UP,When 骑手确认送达成功(状态转为 DELIVERED),Then 寄件用户收到"已送达"推送。
  3. Given 取件或送达操作因校验失败未改变订单状态,When 操作报错返回,Then 不产生推送。

User Story 3 - 骑手收到订单取消通知 (Priority: P2)

订单被取消时,已接单的骑手收到推送,及时停止履约,避免白跑。

Why this priority: 取消是低频事件,但漏通知会导致骑手空跑、产生纠纷;相比履约进度通知优先级略低。

Independent Test: 对一笔已接单订单分别走用户取消、平台取消两条路径,验证骑手收到取消推送;对未接单订单执行取消,验证不产生骑手推送。

Acceptance Scenarios:

  1. Given 订单已被骑手接单(ACCEPTED/PICKED_UP),When 寄件用户取消订单成功(状态转为 CANCELLED),Then 该骑手收到"订单已取消"推送,内容含订单标识。
  2. Given 订单已被骑手接单,When 平台取消订单成功,Then 该骑手收到取消推送。
  3. Given 订单尚未被任何骑手接单(WAITING_ACCEPTANCE,含过期预约单自动取消),When 订单被取消,Then 不产生骑手推送(无推送对象)。
  4. Given 用户取消请求因状态校验失败,When 取消未生效,Then 不产生推送。

Edge Cases

  • 接收方没有有效的设备推送标识(未登录过 App / 标识为空)时:跳过云端推送,但消息记录仍正常生成,且不影响订单操作结果。
  • 推送服务调用失败或超时:只记录日志,不重试阻断,订单状态流转结果不受影响。
  • 接收方语言设置为越南语/繁中/英语/简中之外或未设置:按平台默认语言回落(与现有订单推送行为一致)。
  • 骑手抢单与用户取消并发(一方成功另一方必然失败):只对实际改变了订单状态的一方产生推送。
  • 平台连续取消多笔订单:每笔独立推送,互不影响。

Requirements (mandatory)

Functional Requirements

  • FR-001: 骑手抢单成功(WAITING_ACCEPTANCE → ACCEPTED)后,系统 MUST 向寄件用户发送"骑手已接单"推送通知。
  • FR-002: 骑手确认取件成功(ACCEPTED → PICKED_UP)后,系统 MUST 向寄件用户发送"骑手已取件"推送通知。
  • FR-003: 骑手确认送达成功(PICKED_UP → DELIVERED)后,系统 MUST 向寄件用户发送"已送达"推送通知。
  • FR-004: 寄件用户取消订单成功(状态转为 CANCELLED)且订单已有接单骑手时,系统 MUST 向该骑手发送"订单已取消"推送通知。
  • FR-005: 平台取消订单成功且订单已有接单骑手时,系统 MUST 向该骑手发送"订单已取消"推送通知。
  • FR-006: 所有推送文案 MUST 支持四种语言(vi、zh、tw、en),按接收方用户的语言设置呈现。
  • FR-007: 每条推送内容 MUST 包含订单标识(订单号),使接收方无需打开 App 搜索即可定位订单。
  • FR-008: 每条推送 MUST 同步生成消息记录(复用现有消息中心机制),用户/骑手可在消息列表中回看。
  • FR-009: 推送环节的任何失败(无设备标识、推送服务异常)MUST NOT 影响订单状态流转本身,也 MUST NOT 向操作方返回错误。
  • FR-010: 以下事件明确不推送:新订单发布(待抢单)不向骑手推送;加小费不产生推送;超时自动完成(DELIVERED → COMPLETED)不推送;过期预约单自动取消不推送。
  • FR-011: 推送 MUST 仅在对应状态变更实际成功后触发;操作失败或未改变状态时不得产生推送。

Key Entities (include if feature involves data)

  • 推送通知(Push Notification): 一次状态变更事件产生的一条通知,属性包括接收方(寄件用户或接单骑手)、事件类型(接单/取件/送达/取消)、标题与正文(按语言)、关联订单标识;复用现有消息记录实体落地,不新增独立数据模型。

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: 任一在推送范围内的事件(抢单、取件、送达、取消)成功发生后,接收方在 10 秒内收到推送(推送服务正常的前提下)。
  • SC-002: 四种语言设置的用户各抽检一批推送,文案语言与用户设置一致的比例为 100%。
  • SC-003: 抽检的全部推送均含订单号,接收方可凭推送内容直接定位订单,达标率 100%。
  • SC-004: 推送服务整体不可用时,抢单/取件/送达/取消接口的成功率与推送上线前持平(推送故障零传导)。

Assumptions

  • 复用项目现有推送通道(App 端云函数推送 + 消息入库),不新建推送基础设施,不新增 Android 通道。
  • 推送在订单状态变更成功后异步触发,不放在订单操作的事务内。
  • 平台取消按需求仅推送骑手端;寄件用户通过订单列表感知取消结果,如需同时通知用户可后续追加需求。
  • 超时自动完成、过期预约单自动取消、新单发布、加小费均在范围外(FR-010)。
  • 推送点击后的客户端跳转(payload 路由到闪送订单详情页)由客户端处理;服务端只保证推送携带订单标识与业务类型。
  • 报文文案沿用现有订单推送的文案风格(简短状态描述 + 订单号后缀)。