PickTrip建造術:教系統不要說謊的那一天——四萬一千行的購買中心落在分支上,一張講誠實的票十分鐘關掉,存亡問題靠沉默結案

PickTrip建造術:教系統不要說謊的那一天——四萬一千行的購買中心落在分支上,一張講誠實的票十分鐘關掉,存亡問題靠沉默結案

PickTrip 產品建造筆記:從旅行想法到可預訂行程 · Episode #14 · · PT8M39S

主持人 · Kai

本集摘要

安靜到反常的一天:Linear 零新票、Notion 零新想法與零字修改,唯一新頁面只是把既有兩場會議重謄一次(還把 86 分鐘寫成 80 分鐘),但同一晚 web_app 進了四萬一千行。那顆 commit 叫「統一全域購物與購買中心」:購物車有了 USER/TRIP 範圍,可以不先建行程就買東西;/cart 與 /wallet 合成購買中心,錢包有時區感知的生命週期(即將使用/現在可用/已使用/過期/取消/退款);跨行程搬移必須重新報價(move-by-offer/move-by-quote),因為訂位綁日期與 offer;項目以後端 item id 而非 block id 為 key——正是 7/15 會議「統一寫入介面、只用唯一 ID 識別」長到商務端,也回應了馬總「飯店才是唯一真毛利、C 端行程不等於 B 端方案」的拷問。但它仍在 feat/web-global-cart-wallet-order 分支,未進 main。當天三張票同一主題,系統不再安靜地說謊:PIC-415 把日期盲的三十天起價改成逐日價格與可訂性,並區分「這天訂不到/價格載入失敗/去查查看」(快取分不出賣完與沒資料,就不假裝知道);PIC-419 通知中心收攏五個 pill 與四處 showToast,永不只靠顏色,undo 只給真能乾淨復原的三種操作,因為後端無 cart undo 端點、重加會重新報價撞 offer 過期;PIC-271 修掉 Yjs STEP_1 兩個安靜的 early return,避免降級空文件洗掉行程日期。真正的轉折是團隊自己也在假裝:PIC-419 十分鐘關單,作者自陳七條驗收只達四條、PR 註明尚未 build 驗證,而前一天才寫下「AI 後端完成不等於功能完成,必須接回 iOS 實測」;對照組 PIC-271 的 reviewer 在乾淨 worktree 連跑十次注入測試 10/10 通過仍拒絕關單,並揪出 STEP_2 在 applyUpdate 失敗時仍發出已同步——那個號稱自我修復的握手自己也在說謊。第三層:「產品方向與策略重估」(是否續留旅遊 AI,研究醫療/Home Service/營建)仍停在 7/14、待人類校對、零評論,而 7/15 會議的十九項行動項目無一回答此題,存亡問題被沉默結案。風險清單:PIC-370 第三天未動且從未離開 Backlog,PIC-416 這個 P0 閃退建票後零更新,四張 Urgent 與 P0(PIC-349、353、355、408)無人認領。

完整逐字稿

歡迎回到 PickTrip 產品建造筆記。 昨天這集收在 PIC-370:護欄裝上了,但還在試營運。

今天先給答案——PIC-370,Urgent,Backlog, 從七月十三號下午三點十二分之後,第三天,一次都沒有被碰過。

從建票到現在,它從來沒有離開過 Backlog。

三天欸。 那今天大家在忙什麼?

這就是今天奇怪的地方。 Linear 上,二十四小時內零張新票、一張關單、一張進 review。

Notion 上,零場新會議、零個新想法、沒有一個字被修改。

所以是放假日?

不是。 同一個晚上,web_app 進了四萬一千行。

蛤?

先講結論:帳面上靜音,倉庫裡很大聲。 今天的故事,就是這兩件事對不起來。

那四萬一千行是什麼?

一顆 commit,一百六十九個檔案,名字叫「統一全域購物與購買中心」。 其中五十五個是測試檔。

一百六十九分之五十五是測試? 這人很有事欸,我喜歡。

這個你一定要知道——購物車從此有了「範圍」。 兩種:USER,或者 TRIP。

白話。

白話就是,你可以不先蓋一份行程,就直接買東西。 以前 PickTrip 的購物車掛在行程底下,你要買一張票, 得先有一趟旅程。

現在有 /cart 購物車,跟 /wallet 已購買項目, 兩個合起來叫購買中心。

錢包! 所以買完的東西有地方住了。

而且有生命週期:即將使用、現在可用、已使用、過期、取消、 退款。 時區是算過的——「現在可用」是用目的地的時區判斷,不是你手機的。

這個細節我給過。 那買完想放進行程呢?

可以搬。 但真正關鍵的是——搬不是換個爸爸。 它要重新報價。

為什麼? 搬一格而已欸。

因為一筆訂位綁的是日期跟 offer。 你把七月十五號的票搬到另一趟七月二十號的旅程,那張票在二十號還存不存在、 多少錢,是要重新問供應商的。

所以程式碼裡是 move-by-offer、move-by-quote 兩條路, 不是改個欄位。

誠實的搬家公司。

再往下看一層。 那個購物車的註解寫著:項目用後端的 item id 當 key, 不是用 block id。

這個是不是前天那句?

對。 前天九十一分鐘那場會議的結論是「統一寫入介面、只用唯一 ID 識別」。 那是講行程的。 今天,同一條教條長到商務上了。

而且它回應了可樂旅遊馬總的拷問——他說飯店才是唯一真的毛利, C 端行程不等於 B 端方案。 現在買東西,不用先蓋一份行程。

所以昨天挨的打,今天變成程式碼了。

但我得誠實:這四萬一千行在一個分支上,叫 feat/web-global-cart-wallet-order。

還沒進 main。

好,那今天關掉的票呢?

今天三張票,其實是同一個主題。 系統以前會安靜地說謊。

舉例。

PIC-415。 票券的價格是「日期盲」的——不管你選哪天,它永遠回三十天窗口裡的「起價」。 你選了日期,它還是給你那個價;

你要一路點到加入購物車,才發現那天根本訂不到。

這超賤欸!

現在每個日期各自算價格跟可訂性。 而且分三種狀態:這天訂不到、價格載入失敗、還有「去查查看」。

第三種是什麼鬼?

是誠實。 飯店那邊的快取分不出「賣完了」跟「我沒資料」。 既然分不出來,就不假裝知道,叫你去查。

好,這我服。

PIC-419,iOS 的通知中心。 原本光一個畫面的 ZStack 裡就疊了五個 pill, 另外四個地方各自有自己的 showToast。

那個紅色的提示蓋在行程內容上,還會漏出一個幽靈的「已取消」。

幽靈的已取消是什麼啦,聽起來很衰。

是把底層的錯誤訊息直接接到文案後面。 現在收成一個頂部的 capsule,四種狀態,而且永遠不會只靠顏色——每個狀態都配一個符號, 給 VoiceOver 用。

那最誠實的是哪一條?

undo。 只有三種操作給復原:改項目、加購物車、改飯店日期。 其他一律不給。

為什麼這麼小氣?

因為後端根本沒有購物車的 undo 端點。 移除是硬刪,重加會重新報價,可能撞到 offer 過期、 綁到一個新的 offer id、價格還跟原本不一樣。

那個不叫 undo,那叫重買。

所以寧可不給,也不給假的。

對。 PIC-271 也是同一件事。 Yjs 的握手裡有兩個安靜的 early return, STEP_1 只要跑在 join 前面就被丟掉,客戶端等十秒逾時,

然後那份降級的空文件,把已經寫進去的行程日期洗掉。

所以今天整天,都在教系統不要安靜地假裝。

這就是今天真正的問題了。 那團隊自己呢?

嗯?

PIC-419,晚上九點五十八分進 In Progress, 十點零八分 Done。

十分鐘? !

作者自己在票上寫:七條驗收標準,只有四條達標。 PR 留言寫:尚未 build 驗證。

等一下。 這張票的內容,就是「不要讓 app 假裝事情完成了」欸?

對。 而且昨天這集我們才講,七月十五號那場會議寫下一條規則:AI 後端完成不等於功能完成, 必須接回 iOS 實測。

規則寫在十五號。 這張票關在十五號晚上十點零八分,沒有 build。

規則的墨水都還沒乾。

但同一天有對照組。 PIC-271 的 reviewer 開了一個乾淨的 worktree, Xcode 26.2、iPhone 17 Pro 模擬器,

手動注入那個空文件的狀況,連跑十次日期更新。 十次全部保住標題跟日期。

十次! 這才叫驗證嘛。

然後他擋下來了。 因為他找到一個更深的東西——客戶端收到 STEP_2 的時候, 會無條件取消逾時、把重試歸零、發出「已同步」。

但真正套用資料失敗的時候,只被 catch 起來記一行 log。

所以套用失敗,它還是說同步成功?

對。 那個號稱會自我修復的握手,自己也在說謊。

這也太諷刺了吧。

他還說,debug 帳號打 beta API 回 401, 真實後端的 E2E 沒跑過,慢網也沒測。

所以不准關單,維持 In Review。

兩張票,兩種「完成」。

同一天。 補一個你會喜歡的巧合:寫那四萬一千行的,跟擋下 PIC-271 的, 是同一個人。

喔喔喔,這位仁兄標準很一致嘛。

還有第三層。

還有?

Notion 這二十四小時,唯一的新頁面,是把既有的兩場會議重新謄了一次。 其中一次,把八十六分鐘寫成八十分鐘。

連謄都謄錯,好敷衍喔。

但真正關鍵的是那份沒有動的。 「產品方向與策略重估」——就是公開問「我們到底該不該繼續待在旅遊 AI」,

還列了醫療、Home Service、營建的那份——停在七月十四號下午三點五十四分。 狀態:待人類校對。

零則評論。

一個人都沒回?

它自己的行動項目寫著:於下一次會議釐清是否持續投入 PickTrip。 下一次會議來了,九十一分鐘,十九項行動項目,P0、P1、 P2 都排好了。

然後咧?

沒有一項是這題。 十九項全部在修 TripDoc。

所以答案是「繼續」?

答案是「沒有人回答」。 團隊用手投票了——十九項行動項目就是答案。 但那份問存亡的文件,從來沒有被正式校對、沒有結案,判準也從來沒有被定義。

會議紀錄標「已沉澱」,策略重估標「待人類校對」。 差不到二十四小時,而後者才是問存亡的那一份。

用做的回答,跟真的回答,不一樣。

先把事情講簡單:今天團隊花了一整天,教系統不要安靜地假裝成功。 然後在三個層次上,安靜地假裝了。

系統層,真的修好了,這個要給。 流程層,一張講誠實的票,十分鐘關掉、沒有 build。 策略層,一個存亡問題,靠沉默結案。

那風險清單?

畢業生有:PIC-419 關了,但作者自陳七條只到四條。 PIC-271 進了 In Review,而且被 reviewer 擋著——這是好事, 擋著代表有人在看。

PIC-404 早就關了,但嚴格攔截預設還是只記錄、不擋。

新票呢?

零。 今天零新票。

這是好消息吧?

通常是。 但今天不是。 PIC-416,那個 Web 建立的東京行程會讓 iOS 穩定閃退的 P0, 建票之後零更新。

然後有四張 Urgent 跟 P0,現在沒有人認領——PIC-349, 飯店跨城誤配; PIC-353,search_hotels 拿不到 offer;

PIC-355,build-trip-agent 第二輪就 bad_request; PIC-408,iOS 改合作者身份根本沒有 handler。

零新票不是因為沒有火,是因為沒有人去記。

加上 PIC-370,第三天,沒動。 所以昨天那個問題,今天的答案還是一樣:往前走了一步,但還沒關。

而且今天連問都沒人問。

明天同一時間,PickTrip 產品建造筆記,每日更新。

掰掰!

製作你的 AI Podcast

把主題、文章、RSS 與團隊資訊轉成持續更新的節目。

開始使用 NewsTune