From fafc540331b741a3c7c6c03c35b0ff3429f97711 Mon Sep 17 00:00:00 2001 From: awei Date: Tue, 28 Jul 2026 08:57:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?docs(app):=20=E5=9B=9E=E5=A1=AB=E7=B6=AD?= =?UTF-8?q?=E8=AD=B7=E9=A0=85=205=E3=80=8C=E6=B8=85=E9=96=8B=E7=99=BC?= =?UTF-8?q?=E6=AE=98=E7=95=99=20worktree=EF=BC=8F=E8=88=8A=E5=88=86?= =?UTF-8?q?=E6=94=AF=E3=80=8D=EF=BC=8B=E5=AF=AB=E6=98=8E=E4=B8=8B=E6=AC=A1?= =?UTF-8?q?=E4=BB=BB=E5=8B=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 三個 repo 的殘留:本地分支 76→5、worktree 18→3、remote 舊分支 17→0。 重點不是刪,而是刪之前逐條證明內容真的在 main(前兩批「救回」就是因為 有人把未合併的分支當成已合併)。判定不靠 commit message、也不只看 PR 狀態: MERGED 的分支還要比對 `headRefOid`,因為 squash merge 後本地 tip 可能又長出 新 commit,而 PR 頁面不會告訴你。40 條 MERGED 分支全數 tip 相符。 4 條例外逐條判定:3 條已被取代/已救回,1 條(dispatch `determined-shannon`, **從未開過 PR**)帶著 main 沒有的 dropoff repository 測試,已救回為 dispatch PR #50。 Co-Authored-By: Claude Opus 5 --- docs/TODO.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/TODO.md b/docs/TODO.md index ede4fd2..ccfb1f4 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -485,11 +485,49 @@ admin 端 `grep -i rating` 零命中,營運方對爛司機完全無感。 --- +## 🧹 清開發殘留 worktree/舊分支(維護項 5,2026-07-28 完成) + +> 三個 repo 累積的殘留:**76 條本地分支、18 個 worktree**。 +> 這項的重點不是刪,而是**刪之前逐條證明內容真的在 main**—— +> 前兩批「救回」(app PR #48、dispatch PR #49)就是因為有人把未合併的分支當成已合併。 + +**判定方法**(不靠 commit message、不靠「PR 看起來合併了」): +1. `git merge-base --is-ancestor main` → 是 ancestor 就安全。 +2. 非 ancestor 者查對應 PR,**MERGED 還要再比對 `headRefOid`**—— + squash merge 後本地 tip 可能又有新 commit,PR 頁面不會告訴你。 + 全 40 條 MERGED 分支的本地 tip **都等於合併時的 tip**(無漏網)。 +3. 剩下的例外逐條看 diff:**只有 4 條**不是「已合併且 tip 相同」。 + +**4 條例外的判定**: + +| 分支 | 判定 | 依據 | +|---|---|---| +| app `claude/todo-review-priority-54ffe7`(PR #40 CLOSED) | 已救回 | 整合測試+`tool/watch_driver_location.sh` 在 PR #48、功能碼在 PR #41 | +| app `claude/project-planning-docs-803c8e`(PR #37 CLOSED) | 已被取代 | 純文件;T1 車資預估已完成、T2/T3 仍列在下方、T5-2 評分已上線 | +| dispatch `claude/driver-phone-profile`(PR #42 CLOSED) | 已被取代 | 那份 service 測試的每一條都被 main 的 `handler/driver_profile_test.go`(真 DB)覆蓋,含「改電話不重置 O5 審核」;且**「空字串=清除電話」在 main 已改成 400 拒絕**,原測拿到 main 反而會 FAIL | +| dispatch `claude/determined-shannon-17f4ac`(**從未開 PR**) | 🐛 有漏 → 已救回 | 功能碼(`PickUpResult`/`dropoff_lat`/tracking ETA)都在 main,但帶著一份 main 沒有的 `ride_dropoff_integration_test.go` | + +- [x] **救回 dropoff repository 測試**(dispatch PR #50):原檔測的 `GetDropoffCoords` + 在 main 已不存在,故改寫成對現有 API(`Create` → `GetByID`)的等價覆蓋。 + 關鍵是**「未指定目的地 → `DropoffPoint` 必須是 nil」這條 main 完全沒有**—— + 守的是踩過的 `GeoPoint.Scan` 坑:NULL 被當成掃描成功而留下 `(0,0)`, + 導航與計費會把幾內亞灣外海當真目的地且**不報錯**。 + 負向斷言的取值路徑由同檔正向案例校準(同一個 `GetByID → DropoffPoint`), + 不會永遠 PASS。真 PostGIS(testcontainers)實跑 **2/2 PASS**、gofmt/go vet 乾淨。 +- [x] **清除**(三端數字皆為實測 `git worktree list`/`git branch -a`): + 本地分支 **76 → 5**(app 55→2、admin 2→1、dispatch 19→2)、 + worktree **18 → 3**(僅留兩個進行中的工作區)、 + remote 舊分支 **17 → 0**(app 7、dispatch 10;使用者 2026-07-28 同意含 4 條未合併的一併刪, + GitHub 的 PR 頁面仍看得到 diff)。admin 端本來就乾淨。 + +--- + ## 下次任務 -> **✅ B5 評分的模擬器實跑 E2E 已完成(2026-07-27)**,詳見上方「⭐ 乘客評分司機」。 -> 實跑抓到一個後端文案 bug(評分被拒時講遺失物協尋),已修(dispatch PR #46)—— -> 又一次印證「單元測試綠 ≠ 使用者看到的東西是對的」。 +> **✅ 維護項 5「清開發殘留」已完成(2026-07-28)**,詳見上方。 +> 清理過程又撈到一份未合併的測試(dispatch PR #50)—— +> **「從未開過 PR」的分支是最危險的一種殘留**:它不在任何 PR 列表裡, +> 只有逐條比對 diff 才看得到。 > > **➡️ 下次任務:剩下的都被外部資源卡住**,開工前先確認前置條件到位: > 1. **A2 真裝置推播**——需要你先建 Firebase 專案並提供 `google-services.json`(後端 FCM 已上線)。 @@ -499,9 +537,7 @@ admin 端 `grep -i rating` 零命中,營運方對爛司機完全無感。 > 4. **車種供給為零時的選項處理**——等產品拍板要停用、隱藏、還是照選但提示。 > > **不需前置條件、隨時可做的維護項**(2026-07-27 盤點新增): -> 5. **清開發殘留**:三個 repo 累積了十幾個**已合併卻沒刪的 worktree 與舊分支** -> (`git worktree list` 看得到)。它們會讓 `git branch -a` 難讀, -> 也讓下次開 worktree 時撞名。**條件**:純維護,不動產品程式碼。 +> 5. ~~**清開發殘留 worktree/舊分支**~~ ✅ **已完成(2026-07-28)**,見上方專段。 > 6. **清 dev DB 測試殘留**:本機 docker compose 的 DB 堆了大量前幾次 session 的 > 測試司機與訂單——2026-07-27 的 B5 實跑就因為十幾個殘留的「線上」司機擋在派單佇列前, > 白跑了一輪派單逾時才輪到目標司機。**條件**:會寫 DB,動手前要先問過。 @@ -509,6 +545,12 @@ admin 端 `grep -i rating` 零命中,營運方對爛司機完全無感。 > **沒有低分司機的處理流程**(通知/停權/申訴)。 > **條件**:等實際累積評分、營運說得出要對低分司機做什麼再開—— > 做在前面只會做出沒人用的流程。 +> +> **🎯 下次開工第一件事**:第 6 項(清 dev DB 測試殘留)是唯一還能動的維護項, +> 但它**會寫 DB,動手前必須先問過使用者**(`ask-before-db-writes`)。 +> 建議做法:先只讀盤點(`SELECT` 出殘留的線上司機/未結案訂單數量), +> 把要刪什麼列給使用者看,取得同意後才 `DELETE`。 +> 若使用者不想動 DB,第 1–4 項就都要等他提供外部資源/拍板,屆時**不要硬找事做**。 > **🎨 App icon(叫車系統圖示)✅ 已完成(2026-07-15,PR #15)**:品牌綠 LINE green #06C755 + 白色計程車, > 以 `flutter_launcher_icons` 產生 Android(含 adaptive icon)與 iOS 各尺寸,driver/customer 兩 flavor 共用。 From 6977b84828d706445a6171353f2293aa157cdb03 Mon Sep 17 00:00:00 2001 From: awei Date: Tue, 28 Jul 2026 09:14:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs(app):=20=E5=9B=9E=E5=A1=AB=E7=B6=AD?= =?UTF-8?q?=E8=AD=B7=E9=A0=85=206=E3=80=8C=E6=B8=85=20dev=20DB=20=E6=B8=AC?= =?UTF-8?q?=E8=A9=A6=E6=AE=98=E7=95=99=E3=80=8D=EF=BC=8B=E6=9B=B4=E6=AD=A3?= =?UTF-8?q?=E5=AF=AB=E9=8C=AF=E7=9A=84=E6=B4=BE=E5=96=AE=E6=A9=9F=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 清理本身:docker compose down -v 砍掉 dev DB volume,重建後驗證 migration 跑到 000023、admin 重種可登入、業務表全 0;順手清掉維護項 5 遺留的兩個孤兒 volume(228MB)。 兩件比「刪掉了」更重要的事: 1. **更正原待辦寫錯的機制**:舊敘述說殘留的「線上」司機擋在派單佇列前。讀 dispatchRound → Store.NearbyDriverIDs 後確認跨 session 不成立——候選只從 Redis drivers:geo 取且要過心跳鮮度,而 compose 的 redis 沒掛 volume,down 之後派單池是空的 (實測 dbsize 0)。那次白跑是同一個 session 內司機還在送心跳造成的。 2. **盤點到真正會咬下一次的坑**:GoOnline 對 status=OnTrip 的司機直接 return 不改狀態、 GoOffline 回 ErrDriverOnTrip。上次留下 3 個卡在「載客中」的司機,重用時 App 顯示 上線成功但永遠收不到單、也無法離線,且沒有任何錯誤訊息。 Co-Authored-By: Claude Opus 5 --- docs/TODO.md | 56 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/docs/TODO.md b/docs/TODO.md index ccfb1f4..98585fe 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -522,6 +522,48 @@ admin 端 `grep -i rating` 零命中,營運方對爛司機完全無感。 --- +## 🗄️ 清 dev DB 測試殘留(維護項 6,2026-07-28 完成) + +> ⚠️ **先更正原本這條待辦寫錯的機制**:舊敘述說「十幾個殘留的『線上』司機**擋在派單佇列前**」。 +> 讀 `dispatchRound` → `Store.NearbyDriverIDs` 後確認**跨 session 不成立**: +> 派單候選**只從 Redis 的 `drivers:geo` 取**,且每個候選還要 `driver::loc` +> 的 `updated_at` 在心跳鮮度內才算數。compose 的 redis **沒有掛 volume**, +> `docker compose down` 之後派單池是空的(實測 `dbsize` 0、`zcard drivers:geo` 0)。 +> 所以 Postgres 裡的 `status=1` 殘留**本身不會**吃掉派單輪次; +> 2026-07-27 那次白跑,是**同一個 session 內**那些司機還在送位置心跳造成的。 + +**盤點到的真正的坑**(這個才會咬下一次的自己): +`GoOnline` 對 `status=OnTrip` 的司機**直接 return、不改狀態**,`GoOffline` 則回 +`ErrDriverOnTrip`。上次留下 **3 個卡在「載客中」的司機**(id 4 `o5-driver`、11、13)—— +下次重用這些帳號時,**App 會顯示上線成功,但派單要求 `Idle` 所以永遠收不到單,也無法離線**, +沒有任何錯誤訊息。另有 **4 張未結案訂單**(#7 已派單但無司機、#11/#14/#16 已接單) +讓 customer 3/6/9/11 一律拿到「已有進行中訂單」。 + +**清理前的盤點**(只讀):drivers 24(19 待命/3 卡載客中/2 離線)、customers 20、 +rides 27(13 完成/10 取消/**4 未結案**)、ride_events 108、ride_stops 12、 +ride_ratings 2、ride_messages 1、daily_driver_earnings 11、device_tokens 1。 + +- [x] **做法:整個砍掉重練**(使用者 2026-07-28 拍板;`ask-before-db-writes` 已遵守, + 盤點先只讀、把選項與代價列出後才動手)。`docker compose down -v` 刪掉 + `line-fleet-dispatch_postgis_data`。**動手前先核對過不會損失任何設定**: + `fleet_settings` 的每個值都等於 migration 預設(8500/2000/8500/1500/300000/ + lost_item_fee_bps 1000/pet_cleaning_fee_bps 0),admin 帳號由 app 啟動時重種。 +- [x] **驗證重建後仍是可用的 dev DB**(不只是刪掉):`docker compose up -d` → + migration 自動跑到 **000023**、admins 重種 1 筆(`admin`/superadmin)、 + `fleet_settings` 1 筆回到預設值,其餘業務表**全部 0 筆**; + `POST /api/admin/login`(admin/admin)**200 並取得 token**、 + 未帶 token 的 `GET /api/customer/fees` 正確回 **401**。 +- [x] **順手清掉兩個孤兒 volume**(使用者同意):`customer-ride-stops_postgis_data`/ + `driver-phone_postgis_data`,各 114MB、`LINKS=0`,是維護項 5 刪掉的 worktree 留下的。 + 共釋出 **228MB**。 + +**下次做 E2E 前的提醒**:這個 DB 現在是全新的,所以**沒有任何測試帳號**—— +司機/乘客都要重新註冊,司機還要走 O5 車輛審核(admin 核准)才能接單。 +若又要收尾,離開前把 `status=OnTrip` 的司機與未結案訂單處理掉, +否則下一次又會踩上面那個「上線成功卻收不到單」的無聲坑。 + +--- + ## 下次任務 > **✅ 維護項 5「清開發殘留」已完成(2026-07-28)**,詳見上方。 @@ -538,19 +580,17 @@ admin 端 `grep -i rating` 零命中,營運方對爛司機完全無感。 > > **不需前置條件、隨時可做的維護項**(2026-07-27 盤點新增): > 5. ~~**清開發殘留 worktree/舊分支**~~ ✅ **已完成(2026-07-28)**,見上方專段。 -> 6. **清 dev DB 測試殘留**:本機 docker compose 的 DB 堆了大量前幾次 session 的 -> 測試司機與訂單——2026-07-27 的 B5 實跑就因為十幾個殘留的「線上」司機擋在派單佇列前, -> 白跑了一輪派單逾時才輪到目標司機。**條件**:會寫 DB,動手前要先問過。 +> 6. ~~**清 dev DB 測試殘留**~~ ✅ **已完成(2026-07-28)**,見上方專段 +> (**原本寫的機制是錯的**,一併更正)。 > 7. **評分的營運動作**(B5 下游):三端現在都只「看得到」評分, > **沒有低分司機的處理流程**(通知/停權/申訴)。 > **條件**:等實際累積評分、營運說得出要對低分司機做什麼再開—— > 做在前面只會做出沒人用的流程。 > -> **🎯 下次開工第一件事**:第 6 項(清 dev DB 測試殘留)是唯一還能動的維護項, -> 但它**會寫 DB,動手前必須先問過使用者**(`ask-before-db-writes`)。 -> 建議做法:先只讀盤點(`SELECT` 出殘留的線上司機/未結案訂單數量), -> 把要刪什麼列給使用者看,取得同意後才 `DELETE`。 -> 若使用者不想動 DB,第 1–4 項就都要等他提供外部資源/拍板,屆時**不要硬找事做**。 +> **🎯 下次開工第一件事**:**維護項已經清空了**(5、6 都完成,7 要等營運需求)。 +> 第 1–4 項全部需要你提供外部資源或拍板,**沒有前置條件就不要硬找事做**—— +> 開工前先確認:Firebase 專案(A2)/iPhone+Xcode Personal Team(A5 階段 5)/ +> 金流方案(付款)/車種供給為零的產品方向。四者皆無時,正確答案是「這輪沒有可做的事」。 > **🎨 App icon(叫車系統圖示)✅ 已完成(2026-07-15,PR #15)**:品牌綠 LINE green #06C755 + 白色計程車, > 以 `flutter_launcher_icons` 產生 Android(含 adaptive icon)與 iOS 各尺寸,driver/customer 兩 flavor 共用。