做 FepPhoto 時,我逐漸把注意力從「網站有哪些頁面」移到「一件事情如何完成」。顧客看到的是會員、預約、優惠券與底片服務入口,門市面對的卻是收件、交易與後續處理。兩邊若各自維護一套資料與判斷,介面再漂亮,也可能讓同一件事出現不同答案。
共用 API,不等於共用權限
顧客網站與門市 POS 共用需要授權的 API,由 Cloudflare Workers 處理授權、計價與訂單。共用的是服務邏輯,不是讓每個入口都能看見所有資料。前端負責呈現與輸入,重要判斷留在伺服器端,才不必讓網站與門市各寫一套價格計算。
D1 保存訂單等結構化紀錄,R2 保存檔案;紀錄與檔案分開,各自承擔不同責任。這也符合官方對 SQL 資料庫與物件儲存的區分,可參考 Cloudflare 儲存選型文件。
1 | 顧客網站 ─┐ |
這張圖只說明責任分工,不包含部署位置、管理入口或實際資料。
先留下交易,再處理同步
門市 POS 的交易先在本機保存,再由背景同步送往服務端。這個順序關注的是:網路暫時不穩時,已完成的操作仍有紀錄可追,而不是讓一次連線失敗直接抹掉現場工作。
但「本機先存」不等於所有功能都能離線,也不代表同步永遠成功。重送、資料衝突與同步失敗仍是需要處理的問題;本機有紀錄,也不能直接視為雲端已確認。這些狀態值得被清楚區分,而不是只顯示一個含糊的成功訊息。
付款與列印,都不能只看畫面
付款狀態以通過驗證的綠界伺服器通知更新,不以顧客瀏覽器跳回網站作為依據。顧客可能關掉分頁,回跳也可能受網路影響;綠界付款結果通知文件 同樣要求驗證通知,並留意重複處理。
列印工作則排入佇列,目的是讓待處理工作不只存在於一次按鈕操作中。佇列不是「一定印得出來」的保證:設備故障與紙張問題仍可能發生,工作送出與實際完成也必須分開理解。
已有架構,與尚未啟用的功能
會員、預約、優惠券與底片流程構成平台的服務脈絡,顧客可從公開網站查看入口與當下可用項目。本文描述的是已確認的架構,不把它包裝成所有情境都驗證完成的保證。
LINE Pay 目前僅有準備工作,尚未啟用,不是已上線的付款方式。 後續完善同步與例外處理,也應視為持續工作,而非完成宣言。這次實作讓我更在意的不是功能清單長度,而是每一步出了問題,事情是否還能被找回、說明與接續。
讀者留言