昨天預告了:這個系統裡有一台真的被拔掉的狀態機。今天講訂單的「狀態」為什麼是五個欄位、零個狀態機。
教科書會教你給訂單畫一張漂亮的狀態機:建立 → 待付款 → 已付款 → 備貨 → 出貨 → 完成。當年的系統不是這樣——訂單的「狀態」是五個各自獨立的欄位:付款狀態、開發票狀態、退款狀態、物流狀態、客服標記——每一個都跟著事實更新,沒有轉移限制。

先講數學再講人。數學:這五件事各自獨立演進——付款完成不影響發票開不開得出來,退款可以發生在物流的任何階段。塞進單一狀態機,狀態數是五個維度的笛卡兒積,幾百個組合裡大半沒有業務意義,但每個都要你回答「誰能轉到誰」。正交的東西就該正交地存。
人:這台狀態機不是紙上談兵——選標系統的同仁真的做過轉移限制,然後發現主播們想改就改。改狀態被擋下來的每一次,對他們都是阻力而不是保護,最後狀態機被拔掉了。這個故事我認為是健康的認輸,但值得收一個更精確的教訓:狀態機適合你能控制的流程,不適合你只是在記錄的現實。 系統裡有兩種東西——硬不變量(不能超賣、錢要對),用資料庫層的約束守死,誰來都不能繞;軟狀態(人的作業進度),只記錄、不強制,因為主播、廠商、客服的現實你本來就管不了。當年最後的形狀恰好正確:超賣守死、狀態自由。很多系統犯的是相反的錯——把人的流程綁死,把錢的約束放鬆。
工程師對狀態機有種天然的迷戀——它精確、可證明、畫在白板上很漂亮。但選標系統那台狀態機的下場提醒我:模型的職責是服務現實,不是糾正現實。 主播不是不守規矩,是他們的工作本來就充滿例外:貨臨時到、價格臨時改、客人臨時換——每一個例外都合理,合起來就是「想改就改」。在這種現實上蓋轉移規則,擋下的全是正當操作。正確的花費方式是把「強制」的預算全部投給錢和庫存,把「記錄」留給其他一切——約束是稀缺資源,要花在違約成本最高的地方。
交易主線到此走完。明天開錢的篇章:第三方金流,教科書的三個坑。
本文改寫自我的部落格系列《Re:從零開始做直播代購電商平台》,本篇完整版:https://blog.aidan.tw/blog/rezero-cart-order/