建設、物業與租賃公司做企業系統外包,常把需求寫成「把 Excel 改成系統,再串會計、門禁與簡訊」。這句話看似明確,實際上沒有回答資料以哪套系統為準、失敗後能否重送、舊資料要搬多少,以及舊系統何時停用。這些邊界若沒在發包前說清楚,上線時就會出現重複帳款、狀態不同步或只能繼續人工對表的情況。

舊系統改版不只是重新做畫面,而是一次營運交接。需求書應同時描述新流程、資料移轉、外部串接與退場計畫,並讓驗收可以追到每筆資料從哪裡來、由誰修改、失敗時回到哪個待辦。

先畫系統地圖,再列功能清單

可以從一個實際流程開始,例如房客報修:房客送出問題後,哪套系統產生案件編號,誰負責分派,承包商能看到哪些資料,完工照片存在哪裡,費用是否送入會計,最後由誰關閉案件。每一個箭頭都代表資料交換與責任邊界。

系統地圖至少列出正式、測試與開發環境;每個內外部 API 的負責單位、用途、驗證方式、版本、資料欄位與可存取角色;也要標示敏感資料流向。若外部供應商只能提供批次檔案而非即時 API,也應如實寫入,不要用「可串接」模糊帶過。

OWASP 的 API9:2023 Improper Inventory Management 指出,舊 API 版本、過期文件與缺少退場策略會形成風險;其防範建議包含盤點 API 主機、環境、存取者、版本、整合服務與敏感資料流。對發包方而言,這也是交接清單:如果驗收後仍不知道有哪些端點與版本正在運作,就很難安全維護或更換供應商。

每個寫入動作都要回答「重送會怎樣」

外部系統逾時,不代表請求一定失敗;可能資料已寫入,只是回應沒有抵達。若使用者或排程直接再送一次,可能建立兩筆繳費、兩張工單或重複通知。

MDN 對 Idempotent 的說明是:相同請求執行一次或多次,對伺服器的預期效果相同;文件也指出 PUTDELETE 具冪等語意,而 POSTPATCH 不保證如此。實作仍要由伺服器維持該語意,因此需求不能只寫「失敗自動重試」。

發包規格應逐項定義唯一識別碼、重複判斷、重試條件與人工處理。例如繳費通知可用外部交易識別碼去重,報修建立可由前端先產生請求識別碼;已處理與處理中的重複請求要有可辨識回應。驗收時刻意模擬逾時、重送與亂序,確認不會重複寫入,且操作人員能從紀錄查明結果。

資料移轉要能核對,也要能回復

移轉範圍要以資料類別和期間定義,而不是一句「舊資料全部匯入」。先盤點住戶、物件、合約、帳款、報修、附件與操作紀錄,決定哪些進新系統、哪些只讀封存、哪些依法或依公司政策處理。不要把真實敏感資料直接交給測試環境,測試樣本應去識別化並控制存取。

正式移轉前可至少安排一次演練,產出來源筆數、成功筆數、未匯入原因與關鍵金額或狀態的核對結果。也要寫明切換期間新增資料如何補入、誰簽核、何時可以回復舊系統。資料驗收通過後,才進入停寫與退場,不要讓新舊兩邊長期都能修改同一筆主資料。

舊系統退場是專案範圍,不是上線後再處理

新系統上線後,舊帳號、測試端點與暫時轉接程式若持續存在,就可能變成無人管理的入口。退場清單應包含停止寫入時間、只讀查詢期限、資料匯出格式、帳號與金鑰撤銷、DNS 或排程調整、備份位置、保存責任,以及最終關閉的簽核人。

文件也要跟著交付:資料字典、API 規格、錯誤碼、權限矩陣、部署與回復程序、外部服務清單、版本紀錄及已知限制。原始碼是否交付只是其中一項;沒有環境與資料文件,即使拿到程式碼也未必能順利接手。

案例:流程狀態比首頁儀表板更重要

「房客服務 App」把合約、報修、繳費與續約四件事放在同一個租賃管理流程,房客能追蹤報修進度,房東端同步看到待辦。若拿它作為需求案例,應進一步追問每個狀態由誰改、繳費與報修是否來自外部服務、同步失敗如何呈現,而不只是仿做四個入口。

「馳安 FleetOps 車隊管理」則集中車輛履歷、維修成本與證件到期提醒。它顯示同一個資產可能累積多種時間序列資料;從 Excel 移轉時,不能只搬車輛主檔,還要保留維修事件與文件關聯,否則後續分析失去脈絡。案例可協助理解資料關係,但不應據此假設另一家公司有相同流程或成果。

把交接條件寫進驗收

企業系統外包的驗收,不應停在主要畫面可以操作。至少要完成一次資料移轉核對、主要 API 的正常與失敗情境、重複請求測試、權限檢查、備份回復演練,以及文件與帳號移交。最後再依退場清單關閉舊入口。

當系統地圖、資料主責、重試規則與退場責任都能被檢查,企業才真正擁有新系統的營運能力。這比堆更多功能重要,也能讓未來改版、換廠商或新增串接時,不必再次從猜測開始。