fix(app): 同一帳號的第二台裝置永遠不知道有進行中的行程(第二十八輪) - #100
Merged
Merged
Conversation
先收上一輪的尾巴:司機端的階段 default **是乾淨的**,但理由不是「App 有防禦」—— 後端 FindActiveByDriver 的 SQL 是 status IN (accepted, pickedUp) 白名單, 所以司機端只可能收到這兩種狀態。這是後端契約保證,哪天白名單加了新狀態, App 這裡要跟著改(已寫進 TODO)。 本輪的洞:_handleWsEvent 對「不認得的行程事件」直接 return,而輪詢在「沒有進行中 訂單」時是停著的(_applyActiveRide 會 _stopPolling)。兩件事湊起來,第二台裝置 永遠不會知道有一趟車正在跑。 這是現在就會踩到的,不需要後端改任何東西:同一帳號登入兩台裝置 → B 台停在叫車 表單 → A 台叫車、司機接單 → 後端 WS Hub 依 (角色, id) 扇出,B 台收得到 ride.accepted → 被丟掉 → B 台永遠是叫車表單,按下去只拿到「已有進行中訂單」。 司機端早就處理過同一件事(DriverController 的 rideAccepted 註解寫明已對真後端實測), 乘客端從來沒有做過。 修法與三條邊界:不認得的行程事件去跟後端對一次帳;**只在 activeRide == null 時** 對帳(已有一張單卻收到別的 rideId = 舊單落隊事件,照舊忽略——這條是既有測試 customer_cancel_notice_test 逼出來的,第一版沒收窄它立刻紅);driver.location 不觸發(每幾秒一則的串流,會把一次對帳變成連續打點)。 驗收:flutter analyze 無 issue、flutter test 444 passed(440+新 4)、57 個測試檔、 flutter build apk --debug --flavor customer 成功。新測試在修改前就是紅的。 反向驗證三個半邊各一次:拿掉對帳 → 主案 FAIL;拿掉 driver.location 排除 → 連續 打點那案 FAIL;拿掉 active == null 收窄 → 本檔新案與既有的 cancel_notice 各紅一案。 過程中修正一個自己的錯誤假設:第一版測試斷言「認得的單不該多打 API」,跑出來紅的, 而錯的是我不是程式——rideAccepted 本來就會 refreshActive 補齊完整資料。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
先收上一輪的尾巴,再開新族。
一、收尾:司機端的階段
default:是乾淨的——但理由不是「App 有防禦」司機端
ActiveRide.fromBackendJson的 phase 是status == pickedUp ? onTrip : enRouteToPickup,看起來跟乘客端一樣有「未知碼落到某個分支」的風險。但後端擋在前面:FindActiveByDriver的 SQL 是status IN (accepted, pickedUp)的白名單。這是後端契約保證,不是 App 的防禦——所以要記住:哪天後端把新狀態加進那個白名單,App 這裡就要跟著改。已寫進 TODO。
二、本輪的族:多裝置同一帳號
根因一句話
_handleWsEvent對「不認得的行程事件」是if (active == null || event.rideId != active.rideId) return;——直接丟掉;而輪詢在「沒有進行中訂單」時是停著的(_applyActiveRide會_stopPolling)。兩件事湊起來,第二台裝置就永遠不會知道有一趟車正在跑。這是現在就會踩到的,不需要後端改任何東西
(角色, id)扇出,B 台收得到ride.accepted;司機端早就處理過同一件事(
DriverController的rideAccepted:另一台裝置接走了這張單 → 重讀 active,註解寫明已對真後端實測)。乘客端從來沒有做過同一件事。三、修法與三條邊界
refreshActive(silent: true)activeRide == null時對帳customer_cancel_notice_test的「別的行程的取消事件不觸發通知」立刻紅driver.location不觸發四、驗收
flutter analyze無 issue、flutter test444 passed(440 +新 4)、57 個測試檔。activeCalls停在 1,事件被丟掉)。driver.location排除 → 「不觸發連續打點」那案 FAIL;active == null收窄 → 本檔新案與既有的customer_cancel_notice_test各紅一案。flutter build apk --debug --flavor customer -t lib/main_customer.dart成功。五、過程中修正的一個自己的錯誤假設
第一版測試斷言「認得的單不該多打 API」——跑出來是紅的,而錯的是我不是程式:
rideAccepted本來就會refreshActive(silent: true)補齊完整資料。已把那一案改成守「沒有把已知單的路徑改壞,尤其不能變成兩次補讀」。六、誠實說明沒做到的
WS 斷線期間發生的事:B 台若在事件送出的當下沒有連線,這次對帳就不會發生。目前靠
onAppResumed的無條件refreshActive自癒——但那需要 App 進過背景再回來,一台一直開在前景的裝置不會走到。要修的話動的是onConnectionChanged(WS 重連成功後補一次對帳),已列進下一輪候選。開工前的例行實查(第十一次)
三個外部卡點依然都不在;開工時三個 repo 的 open PR 皆為 0。
🤖 Generated with Claude Code