From 754a8c663f2ee1ebf2dfcb10e3264c2a9f9ad4e4 Mon Sep 17 00:00:00 2001 From: awei Date: Tue, 28 Jul 2026 14:15:36 +0800 Subject: [PATCH] =?UTF-8?q?docs(app):=20=E5=9B=9E=E5=A1=AB=E7=AC=AC?= =?UTF-8?q?=E4=BA=8C=E8=BC=AA=20debug=E2=80=94=E2=80=94=E5=8D=94=E5=B0=8B?= =?UTF-8?q?=E9=8F=88=E8=B7=AF=E3=80=81admin=20REST=E3=80=81=E6=A8=A1?= =?UTF-8?q?=E6=93=AC=E5=99=A8=20UI=20=E5=AF=A6=E6=A9=9F=E9=96=89=E7=92=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 三段各自寫明「抓到什麼」與「驗過哪些是乾淨的」,後者一樣重要: 不記下來的話下一輪會把同一套對帳整個重做。 1. 遺失物協尋鏈路:抓到 production 首頁沒有協尋入口(PR #55)。 其餘(四段狀態機、雙方 WS、狀態常數、未結案集合、終態清空、守門回應)驗過乾淨。 處理費 2100 分一度看似算錯,查證是 roundNtd 進位成 NT$21,符合整數台幣政策,不是 bug。 2. admin REST 形狀:沒有 active bug;揪出一個型別謊言(PR #28)。 六個篩選參數是實跑證明真的有篩(含三組負向對照),不只比對名稱。 3. 模擬器 UI 實跑:沒有新 bug,但把當天三個「靠讀程式碼修」的修正在真 App 上閉環—— 協尋 banner 即時出現並走完付款、司機放棄通知清掉舊司機卡片、 背景輪詢 40 秒零 SnackBar 而使用者動作仍會報錯。 另記一個旁見:閒置中的 App 不會發現「在 App 外建立」的訂單(不輪詢+ride.accepted 早退)。真實使用不受影響,但下次要測 UI 得從 App 建單或重啟走 REST 還原。 README:測試數 227 → 230、補上第五個 bug 與實機驗證註記。 Co-Authored-By: Claude Opus 5 --- README.md | 6 ++++-- docs/TODO.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b512d74..d65065f 100644 --- a/README.md +++ b/README.md @@ -197,13 +197,15 @@ FCM data 的值一律是字串,App 端 `fleetEventFromPushData()` 會把座標 至此三端齊備:**乘客評 → 司機看得到自己的平均分 → 營運看得出誰評價低**。 詳見 [`docs/TODO.md`](docs/TODO.md)「⭐ 乘客評分司機」。 -**目前**:`flutter analyze` 無 issue、`flutter test` **227 passed**(2026-07-28)。 +**目前**:`flutter analyze` 無 issue、`flutter test` **230 passed**(2026-07-28)。 **2026-07-28 修掉的 4 個 bug**(每個都先寫測試看它 FAIL 才修,詳見 [`docs/TODO.md`](docs/TODO.md)「🐞 2026-07-28 debug」):司機端 8 秒一次的定位探針會把 **業務錯誤**(如完成行程被 409 擋下)一起洗掉;乘客端 15 秒一次的背景輪詢失敗會不停彈 SnackBar;FCM token 輪替失敗會冒出司機看不懂也無事可做的紅色橫幅; -**司機放棄訂單時 App 乘客收不到任何事件**(後端只推 LINE,跨端對帳抓到)。 +**司機放棄訂單時 App 乘客收不到任何事件**(後端只推 LINE,跨端對帳抓到); +**production 首頁沒有遺失物協尋入口**(banner 只寫在非 production 的卡片版首頁,乘客付不了處理費就拿不回東西)。 +三個「畫面沒人讀」類的修正已於同日在 `m6_pixel` 模擬器上**逐一實機閉環驗證**。 ## 規劃中(尚未實作) diff --git a/docs/TODO.md b/docs/TODO.md index aefb08a..c186328 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -618,7 +618,52 @@ admin 的全域 query 錯誤處理有去重 key 且整個 repo 沒有 `refetchIn **下次要重跑對帳**:dev DB 是空的,腳本要重建帳號(司機還要走 O5 審核才能接單)。 腳本邏輯:註冊司機/乘客 → admin 核准車輛 → 上線+回報位置 → 雙方連 `ws://…/ws?token=` → 叫車 → 接單 → 上車 → 完成 → 評分,全程把 REST 與 WS 的原始 payload 印出來比對。 -**沒覆蓋到的**:遺失物協尋鏈路、admin 端的 REST 形狀(只驗過司機/乘客兩端)。 +**沒覆蓋到的**:~~遺失物協尋鏈路、admin 端的 REST 形狀~~ → **兩者都已於同日補完**(見下兩段)。 + +--- + +## 🔎 2026-07-28 第二輪 debug:協尋鏈路、admin REST、模擬器 UI + +### 遺失物協尋鏈路(app PR #55) + +**抓到 1 個 bug**:**production 首頁(地圖版)完全沒有協尋入口**——持久性 banner 只寫在 +卡片版首頁裡,換版時掉了。唯一剩下的入口是完成卡,而它按「再叫一輛」或重開 App 就消失。 +後果:乘客建了協尋單、司機標記「已尋獲」後,**必須付處理費才能拿回東西,卻沒有畫面進得去付**。 +2026-07-15 的 E2E 之所以「驗過」,是因為當時本機無 Maps key 走的是**卡片版**。 +修法:抽成共用 `LostItemBanner` 兩版共用(根因是各抄一份),掛在 sheet 最上方且不受行程狀態影響。 + +**其餘驗過乾淨**:`open→found→paid→returned` 四段狀態機、雙方 WS 事件、5 個狀態常數兩端一致、 +「未結案」集合兩端一致(open/found/paid)、終態後雙方清單自動清空、司機角標由清單長度推導、 +守門回應(404/409/403)皆有中文訊息。 +處理費 2100 分一度看似算錯(20600×10%=2060),查證是 `roundNtd` 把 NT$20.6 進位成 +**NT$21**,符合整數台幣政策——**不是 bug**。 + +### admin 端 REST 形狀(admin PR #28) + +**沒有 active bug**。揪出一個**型別謊言**:`PATCH /admin/drivers/:id/status` 實際回混合大小寫 +且不含評價欄,前端卻宣告回 `Driver` 又不正規化——車輛三欄與評價都是 `undefined`。 +目前呼叫端只 `invalidateQueries` 不看回傳值所以沒出事,但哪天有人拿去 `setQueryData` +就會讓那一列的車種車牌憑空消失。已改走 `normalizeDriver`,測試 mock 換成真後端形狀。 + +**驗過乾淨**:訂單列表 8 鍵、**六個篩選參數實跑證明真的有篩**(負向對照 `status=9`→0、 +不存在關鍵字→0、未來日期→0)、分頁 `total` 正確、訂單詳情 +`events`/`ride`/`track_geojson`/`stops`/`rating`(特地造一筆評過分的訂單才驗到)、 +日/月報表欄位、遺失物 13 鍵、會費帳單 7 鍵(`period` 鍵名正確)。 + +### 模擬器 UI 實跑(`m6_pixel` + customer flavor + docker) + +**這一輪沒有新 bug**,但把當天三個「靠讀程式碼修」的修正在**真 App 上閉環**: + +| 修正 | 真機驗證結果 | +|---|---| +| 協尋入口(PR #55) | 地圖版首頁**即時**(未重啟,靠 WS)長出「遺失物協尋:藍色雨傘/司機已尋獲,待支付處理費」;點進去→付款 NT$21→狀態轉「已付款,等待歸還」→司機歸還後 banner 消失 | +| 司機放棄通知(PR #52/#53) | 司機卡片(車牌/撥號)**被清掉**並顯示「司機取消了行程,正在為您重新派車」+回到配對中 | +| 背景輪詢靜默(PR #52) | 停掉後端 40 秒(跨 2 個輪詢週期)**零 SnackBar**;同一斷線下按「取消叫車」**仍跳出**「無法連線到伺服器,請檢查網路」 | + +**旁見(不是 bug,但下次做 UI 測試要知道)**:用 API 在 App 外建的訂單,**閒置中的 App 不會發現**—— +`_activeRide` 為 null 時不輪詢,且 `ride.accepted` 的處理有 `if (active == null) return` 早退。 +真實使用是 App 自己建單所以不受影響;跨管道(LINE 建單 + App 開著)才會遇到, +要測 UI 就得從 App 建單、或重啟 App 走 REST 還原。 ---