Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ REST 一定完整,而推播要傳達的資訊只有「有事發生了」。
**2026-07-29 這一批**(詳見 [`docs/TODO.md`](docs/TODO.md) 第四~六輪 debug +「🧾 PR 佇列稽核」):
- **回到前景會對帳**:背景期間 OS 凍結 timer、WS 可能被關掉,回前景時**立刻重連 WS**
並向後端重新確認進行中行程(司機端沒有輪詢,漏掉的事件沒有第二條路補回來)。
- **搶輸的單不再給假行程卡**:後端對「這單已被其他司機接走」回的是 **HTTP 200+文案**,
- **搶輸的單不再給假行程卡**:後端當時對「這單已被其他司機接走」回的是 **HTTP 200+文案**
(**2026-07-30 後端已改為 409**,dispatch PR #64;App 這條防線留著仍無害),
App 原本只看有沒有丟例外,於是沒搶到的司機會拿到一張完整但假的行程卡。
現在接單與放棄的成敗**一律以後端的 `rides/active` 為準**。
- **弱網(連得上但通不了)**:位置回報一次只放一筆在路上、hero 在「已不在派單池」時
Expand Down
15 changes: 11 additions & 4 deletions docs/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -882,8 +882,8 @@ admin 的全域 query 錯誤處理有去重 key 且整個 repo 沒有 `refetchIn
| 同一個 driver id 的多條 WS 連線 | **全部都收到** `ride.assigned` 與 `ride.accepted`(`events.Hub` 依 (角色, id) 扇出,沒有踢舊 session 的機制) |
| 一張單派給幾位司機 | **同一輪同時派給半徑內每一位待命司機**(`dispatchRound` 迴圈 `pushOffer`)——搶單是常態,不是邊角 |
| 沒搶到的司機收到什麼事件 | **零**。`ride.accepted` 只送給接到的那位;逾時取消(`giveUpIfUnaccepted`)也只通知乘客 |
| 沒搶到的司機打 accept | **HTTP 200** `{"message":"手慢了,這單已被其他司機接走"}`——後端用 200+文案表示失敗 |
| 非待命狀態打 accept | 同樣是 200 `{"message":"您目前無法接單(非待命狀態)"}` |
| 沒搶到的司機打 accept | **HTTP 200** `{"message":"手慢了,這單已被其他司機接走"}`——後端用 200+文案表示失敗(**2026-07-30 後端已改成 409**,見下方回填) |
| 非待命狀態打 accept | 同樣是 200 `{"message":"您目前無法接單(非待命狀態)"}`(同上,已改 409) |
| 放棄非「已接」狀態的單 | 同樣是 200 `{"message":"此訂單目前無法放棄"}` |

**因此 App 有一個一直都在的謊**(`acceptOffer` 只看有沒有丟例外):
Expand Down Expand Up @@ -920,8 +920,15 @@ admin 的全域 query 錯誤處理有去重 key 且整個 repo 沒有 `refetchIn
| 略過(ride #14) | 後端 log `司機拒單 driver_id=7 ride_id=14`+Redis 出現 `ride:14:rejected`(修正前後端完全不知情) |

**➡️ 留給後端的(跨 repo,不在本批)**:
1. **接單/放棄失敗回 200+文案**是 API 設計缺陷——App 只能靠再查一次狀態來判成敗。
正解是回 409(`ErrRideTaken`/`ErrRideNotAbandonable`)。
1. ~~**接單/放棄失敗回 200+文案**是 API 設計缺陷~~ ✅ **後端已修(2026-07-30,
dispatch [PR #64](https://github.com/thothawei/fleet-dispatch/pull/64))**:
新增 `ErrRideTaken`/`ErrDriverNotIdle`/`ErrRideStarted`/`ErrRideStateChanged`
四個 sentinel error,一律回 **409**,**文案一字未改**。
實跑量到:重複接單 `409 {"error":"手慢了,這單已被其他司機接走"}`、
已上車後乘客取消 `409 {"error":"行程已開始,無法取消"}`。
**App 這端不需要改**:司機端 `acceptOffer` 會顯示後端文案、接單卡由 `ride.taken` 收掉;
乘客端 `cancelOrder` 本來就把 `ApiException.message` 顯示出來——先前 200 時它反而什麼都不說。
**既有的「逾時才對帳」退路留著仍然無害**(弱網逾時是 `statusCode == null`,與 409 不同條路)。
2. **沒搶到的司機收不到任何事件**:後端可對「本輪收到 offer 但沒接到」的司機補送
`ride.taken`(或把 `ride.assigned` 的 payload 加上 `offer_expires_at`),
App 才能在司機**完全沒動作**時也把卡片收掉。目前只有他按下接單、或
Expand Down
Loading