Dabao's Tech Blog
中文
English
日本語
Archives
Label
About
Projects
GitHub
Facebook
Email

Projects

廉價航空快遞重構專案主視覺

這不是單純改版網站,而是把一套已經承載實際營運、累積多年技術債的跨境物流系統,重新整理成能繼續維護、擴充與安全上線的新架構。

廉價航空快遞 是一套跨境代運與物流管理系統。一般使用者看到的是會員委託、貨件查詢、付款與通知;但在後面,系統還要同時處理倉庫收件、出貨估價、刷卡金流、電子發票、舊資料匯入、後台對帳、排程簡訊、營運報表與各種例外狀況。

這類專案的複雜度不在「畫面很多」而已,而是每一筆訂單、付款、發票、出貨資料都會互相影響。只要其中一段流程沒有處理好,就可能造成付款狀態錯誤、後台金額對不上、舊資料匯入不完整,或上線後很難追查的 production bug。

我在這個專案裡的任務,是把原本高度耦合、技術債很高、許多流程仰賴人工經驗判斷的舊系統,重構成一個比較清楚、可測試、可部署,也比較能交接維護的新站。

專案挑戰

這個專案不是從零開始的新系統,而是承接一套已經在營運中的舊站。這代表重構時不能只追求程式碼漂亮,還必須同時保護既有資料、營運流程與第三方服務。

主要挑戰包含:

所以這次重構的核心,不是單純把舊程式搬到新框架,而是把一套難維護、難驗證、難交接的系統,整理成能長期營運的基礎。

我做了什麼

1. 先把混亂的舊架構整理成清楚分層

這舊系統有許多麻煩的地方,版本還在老舊的 PHP 5.6、傳統原生 PHP 寫法:一個頁面可能同時負責接收參數、查資料庫、判斷狀態、輸出 HTML,甚至處理部分業務流程。付款狀態、出貨狀態、訂單金額、發票開立與資料匯入又互相牽動,導致後續每次修改都容易影響其他流程。

整理原本混在一起的頁面、資料查詢和業務流程。把責任拆清楚,讓後續修改付款、出貨、發票或匯入流程時,比較不會牽一髮動全身。

這讓系統從「每次修功能都要猜會不會影響別處」,變成可以比較穩定地維護和擴充。

2. 重整付款、發票與出貨狀態

付款是這個專案風險最高的區塊,因為它同時牽涉會員畫面、金流 callback、訂單狀態、出貨狀態、後台對帳與發票流程。只要其中一個狀態沒有同步,前台看到的付款結果、後台看到的帳務資料和實際金流就可能不一致。

我處理並補強了多個真實上線風險,包含金流回傳、付款狀態同步、會員登入狀態保護、重複付款處理、shipment/order 狀態同步,以及發票批次與後台顯示的一致性。

這些不是單一 bug 修補,而是把 checkout、callback、付款狀態、shipment/order 同步、發票批次與後台顯示重新整理成可驗證、可追蹤、可回歸測試的流程。

3. 讓舊資料可以安全匯入新系統

舊站資料匯入不是把資料複製過來就結束。這次重構同時重新設計了新系統的資料表 Schema,讓會員、委託單、shipment、付款、發票、公告等資料能用更清楚的結構被保存與查詢。

這代表舊資料需要被「翻譯」到新的資料模型裡:舊欄位要對應到新欄位,舊狀態要轉成新系統能理解的狀態,過去不完整或格式不一致的紀錄也要能被保留、修正或標記。對業主來說,這一步的挑戰在於不能只看新系統好不好用,還要確保歷史訂單、付款紀錄與發票資料在新系統裡仍然查得到、對得起來。

真實情況裡,舊資料可能格式不一致、紀錄不完整,甚至 import log 顯示成功,但目標資料實際不存在。

我調整 importer,讓它不只看 log,也會檢查目標資料是否真的存在;當 log 存在但目標資料缺失時,可以重新 upsert。這類設計讓資料匯入變得可重跑、可檢查,也比較不怕上線前後需要補資料。

同時,我也在付款、shipment、會員等級、發票批次、排程簡訊等流程補上 guard,避免取消訂單、未付款資料或歷史匯入資料被錯誤納入正式作業。

4. 補強後台營運與對帳流程

對業主來說,系統不只是前台能下單,後台也要能穩定支援每天的營運工作。因此我也補強了管理端:

我把後台常用的查詢、付款核對、報表檢視與出貨狀態整理得更清楚,讓營運人員可以更快確認每筆委託的處理進度,也比較容易追蹤付款、出貨與文件之間的關係。

這些改動的重點不是堆更多功能,而是讓系統更貼近日常作業:資訊要查得到、狀態要看得懂,遇到例外狀況時也能比較快判斷下一步該怎麼處理。

5. 用測試與 runbook 降低上線風險

重構舊系統最怕的是「看起來完成了,但上線後才發現某個角落壞掉」。所以我把多個 stage / production 發生過的問題轉成 regression test,讓修過的問題未來不容易再退回去。

完整測試已覆蓋超過 500 個 PHPUnit tests,最新紀錄為 518 tests、2010 assertions、74 skipped。

我也整理上線 runbook,包含 production env/config、live symlink、Apache DocumentRoot、國泰 callback / RETURL、legacy DB 匯入、發票批次 dry-run、排程檢查與 stage 開關。這讓上線不只是「工程師記得怎麼做」,而是有文件可以檢查與交接。

為什麼這個專案複雜

如果只是做一個新網站,通常可以先設計功能,再逐步開發。但這個專案更像是在不中斷營運的前提下,替一套老系統換底層結構。

困難點在於:

所以這個重構的價值,不只是「升級到新框架」,而是把過去散落在舊程式、人工操作與 production bug 裡的知識,整理成清楚的模組、測試與文件。

成果

技術摘要

這次重構後的主要技術基線:

架構上,我將 HTTP 入口、前後台 Controller、核心業務 Service、資料存取 Dao、資料庫 migration 與 CLI 排程任務拆開,讓後續維護時可以更容易定位問題,也比較容易新增測試與交接。

我的實作原則

這個專案讓我更確定,重構不是把程式碼改得漂亮而已。真正有價值的重構,是把原本藏在舊系統、人工流程和 production bug 裡的知識,整理成清楚的模組、測試與文件。

對營運系統來說,最重要的不是一次做出最大改版,而是每次修改都能回答三個問題:

  1. 這次改動修正了哪個真實流程?
  2. 哪些資料狀態被保護住了?
  3. 未來誰能用測試或文件確認它沒有壞掉?

這也是我在廉價航空快遞重構中最核心的實作原則。