
歷史菜單缺一張圖片,最直覺的修法是拿現在的圖片補回去。畫面會完整一些,資料也看起來更整齊。
便當系統卻把「畫面補得出來」和「歷史原本就有」拆開處理。菜單變更測試先放入 image_url 為空的歷史紀錄,再讀取管理介面:回應可以帶出符合條件的現有圖片,但重新查資料庫,原欄位仍然是空字串。歷史補圖測試定義
歷史紀錄構成一條證據邊界(Evidence Boundary):今天能改善閱讀方式,不代表有足夠依據,把新推論寫成當時已記錄的事實。

Day 9 已談過菜單生效日期,Day 17 已談過帳務修復。這篇不重做兩套機制,而是用補圖這個較小的改動,釐清「整理現在」與「改寫過去」之間的差別。
resolveHistoricalImageDisplayUrl 的判斷相當保守:補圖實作
例如「風味會議便當」有對應到「風味會議」的規則,但「免費加飯」「手續費減免」「1元」在略過清單裡。這不是要求所有資料都補成同樣完整,而是只接受已被明確定義的顯示相容。
同名歧義另有測試,預期仍回傳空圖片。它否決了「隨便選第一張,總比沒圖好」這個看似合理的修法。
這個案例可以拆成三個問題:
| 問題 | 資料責任 |
|---|---|
| 當時保存了什麼? | 歷史原值,允許空白 |
| 今天能用什麼幫助閱讀? | 有限條件下的顯示補圖 |
| 能否把補圖寫回歷史? | 需要額外的歷史依據,不能由顯示成功推定 |
所以讀取回應中的圖片,不應被當成「當時菜單就保存了這張圖片」的證明。需要追查歷史來源時,必須回到原始紀錄,而不是只看今天的介面。
這也留下實作上的限制:補圖依賴現有對應表和現有菜單。今天能補出的畫面,未必能永久重現成同樣的視覺;若業務要求精確還原某天畫面,就需要另外保存當時素材,不能拿這個便利顯示替代。
Day 9 已談過新增修訂而不覆寫舊紀錄。這裡只回扣一條防線:migration 0011 保留舊識別版本,並用 trigger 阻擋菜單變更紀錄及其 sequence 的直接更新/刪除;這與讀取時補圖,是兩條不同路徑。修訂 migration
本文只核對程式、migration 與測試定義,沒有查詢正式資料庫或重新執行測試。這些證據支持特定路徑的設計與防線,不代表所有歷史表都能抵擋任何管理者 SQL。
AI 擅長找出拼字差異、缺值與可合併欄位。但如果任務只有「把歷史資料統一」,顯示修正與歷史回填就可能被混成一個動作。
這個補圖案例留下三個實用問題:
若目的只是讓管理者辨認餐點,先做有限的顯示補充就可能足夠。若目的是真正修正歷史事實,就要另附來源、影響範圍與核准方式,不能用「畫面變好了」當成完成證據。
系統變成熟後,有些不一致需要被解釋,而不是被消除。保留未知,也是在保留未來重新查證的空間。
這是一套持續開發中的便當訂購系統。文章著重「為什麼」,GitHub 保留實際程式碼、文件與演進紀錄。
GitHub:https://github.com/henryfir456/bento-order-app
下一篇會換一種歷史:程式每次改變了哪些行為,如何靠版本與 Changelog 留下一條能被追查的產品時間線?