整合檢核清單 · 2026-08-17 · ← 路線圖 · 主規劃
路線圖每階段一行的「完成條件」,在這頁展開成逐項檢核: 每一項都寫明拿什麼證據、怎麼驗。標了「硬門檻」的項目沒過, 該階段不得往下走。門檻天數標「建議值」者可再議,但改了要回寫這頁。
muxue 下線(A0):125 驗收全綠後,94 停用 lk/callhub/mu/analysis 的 vhost 與 systemd 服務⏸ 8/17 使用者指示暫緩,先不下線
驗證apache2ctl -S 已無四站;各網域從外部 curl 由 125 回應(或正確 301/關站頁);94 的四站 access log 停用後 7 天零新請求
研究目錄搬出 web root(A1):13 目錄+9 散裝 finlab html 移至 /home/ying/lab/(清單見該處 README.md)✓ 2026-08-17 · commit 7912a0e
驗證已完成:搬後主站 smoke test 通過、舊路徑 404。⚠️ 原 15 目錄清單中 dictation_client、ai-images 搬前實查有正式引用(dictation_download.php+tests、ai_gallery/aigen 控制台),保留不搬——「已驗證孤立」的清單會過時,搬前再驗這步救了兩個活模組
crm 貼圖搬 salary(A5①)+ line_chat config 改指✓ 2026-08-17 · commit 7aaea38
驗證已完成:line_chat/config.php sticker 網址改 salary.kng.tw,貼圖檔已就位
crm 301 轉址(A5②):crm.kng.tw 縮成純 301 vhost 指向 salary.kng.tw✓ 2026-08-17
驗證已完成:貼圖路徑 301→salary 同路徑 200、其他路徑→salary 首頁、HTTP 單跳直達 https;acme-challenge 保留;access log 續留供觀察期。原設定備份 .bak-20260817。觀察期滿最早 2026-09-17 進 A5③
crm 清場(A5③):清除站台目錄✓ 2026-08-17 · 使用者裁示免觀察期直接關
驗證已完成:清前實查近 14 天非貼圖流量只剩 bot 掃描、gemini-proxy 零命中、無 cron/systemd 依賴;全量 tar 備份 /var/backups/crm.kng.tw-final-20260817.tar.gz(1.8G);301 vhost 留存(LINE 歷史貼圖網址烙死,轉址零維護成本),清後貼圖 301→200 複驗通過
page_stats 修四個盲區:erp 改讀 apache 直出 log、call/callhub/kn 接入、死來源清除、Laravel 站走路由模式✓ 2026-08-17 · commit ce46b31
驗證已實跑一輪全來源有數字;順手修到既有時序 bug(類型 B 檔每日 00:00 被輪替、00:10 grep 現行檔撲空→改 .log+.log.1 都讀)。平日數字對 vhost 日均的複驗等 8/18(週一)資料出來再看
各站 access log 輪替拉到 90 天✓ 2026-08-17
驗證已完成:apache2 預設 14→90、業務站 access 30→90、kn 14→90;ERP apache access log 原本完全沒被輪替(glob 深度對不上,單檔已累積 63M/36M)→ 新增 90 天輪替;logrotate 乾跑無錯。一個月後抽查最舊檔日期確實在累積(待驗)
shadow 估奶排程停用✓ 2026-08-17 · goalu.tasks 45/46 status=0
驗證已完成:daily:pre-sql、estimate:compare 停用;影子表凍結觀察一個月結後清
快贏三項✓ 2026-08-17:flux 完全除役/:6048 誤殺後恢復/報表站登入收斂
驗證①flux:vhost+cert 下線後實查發現兩個活排程餵電訪管線 → predict:customer-success 與 call:data-alert 移植為 salary tools/(依賴隔離 tools/ml/、模型快取 /var/lib/salary-ml/、掛 CronTracker;dry-run 2100 筆分布與 flux 版一致、池告警輸出逐字相同)→ cron 切換(root 07:00/07:30)→ 目錄 tar 備份 117M 後移除 ②:6048(Livewire 薪資)一度以「7 天流量=0」下線,使用者指正:每月算薪一次仍在用——已恢復 vhost+埠+監控項;🔴 教訓:月頻應用看週窗必誤殺,下線判準要涵蓋使用週期(薪資=月結) ③報表站:session.php/session1.php 收斂為 session-auth 薄轉接、unified-auth 退役;🔴 教訓:引用計數 regex 沒抓雙引號差點讓費用報表裸奔——退役前必實測行為。🔴 8/17 晚事故+已修:session-auth 檔頭 function_exists 防重複 guard 被 PHP 頂層函式 hoisting 自我觸發永遠早退,其後 session_start 是與生俱來的死碼(以前靠舊 session.php 自己 start 掩護)→ 收斂後全站 $_SESSION 空、報表全 302「點了沒反應」;已把 session_start/auth.php 載入移到 guard 之前、shim 自帶 start、isLoggedIn 語意還原(emp_type 不再是登入必要條件、global $db、catch Throwable),四情境(無 emp_type/白名單內外/未登入)實測通過
階段出口web root 目錄清單=正式業務站台清單(成文對照,一目一歸屬);page_stats 全站報表連續產出 ≥7 天且無盲區
四個寄生網域拆出獨立目錄:cf/call/ny26/sales.kng.tw 各自 DocumentRoot 移出 html/salary;cpt proxy 理清
驗證apache2ctl -S 四站指向新目錄;每站 smoke test(登入+一個主功能);html/salary 內不再被其他網域引用
硬門檻寫入權矩陣成文並進版控:每張核心表 ×(唯一 writer、允許讀者、同步方向)✓ 2026-08-18 · 矩陣文件
驗證已完成:erp_docs/write-permission-matrix.md 涵蓋 198 張活表(近 90 天有寫入),標出 W/R/SP/EVENT/TRIGGER 與同步方向;掃描器在 tools/db-matrix/,sudo ./rebuild.sh 可完整重生(已端到端驗過),禁止手改產出的 .md。抽查 hum_msar/hcust/trades 三張表三方比對——⚠️ CBM 不索引 SQL 字面值,第二方改用掃描器輸出的實際寫入點(檔:行),比符號圖更硬
結果47 張表有 2 個以上 app writer(hcust/hcust_trd 各 7 個);david@% 與 tom@% 實為 ALL ON *.*(全機非只 goalu);hcust 上掛 6 個 AFTER UPDATE trigger,任一站改客戶就連鎖寫 hcust_trd/call_data
雷盤點漏掉第 17 個 writer:Windows 桌面 client(sys_log 為證,近 90 天 214 筆/8 台電腦/16 人,含 frmhcust 客戶維護與 frmhum_msar 薪資)——這是 david@% 那個 % 的理由,也是「david 零連線」出口條件的真正阻擋點。停用前要先用 sys_log 確認歸零,看 processlist 不準
david 共用帳號拆分:11 站各換專屬最小權限帳號,照矩陣授權
驗證逐站 SHOW GRANTS 對矩陣;灰度期以 information_schema.processlist 觀察 david 連線趨零;先 REVOKE 寫入權再停用,降權後觀察 ≥7 天無異常才收帳號
雷MariaDB 別建同名 user@localhost 影子帳號(會遮蔽 wildcard 帳號);帳號切換逐站做、一站一 commit,可單站回退
services.json 服務目錄+CI 護欄(守門回歸、禁跨域寫表)
驗證negative test——故意提交一筆跨域寫表的程式,CI 必須紅;services.json 涵蓋現存全部站台(對照階段 0 的成文清單)
kng/notify 套件收斂:寄信 6→1、簡訊 3→1、push 2→1
驗證grep 舊實作呼叫點歸零;發送仍走 send_message_batch() 慣例、trades tr_id=60 補登與 change_resources 同步不得因收斂而丟失(抽發一則測試訊息核對)
design token 獨立發版(Tailwind 4 @theme)✓ 2026-08-17 · kng-design v0.1.0
驗證已完成(v0.2.0):/var/www/kng-design=官方 Claude Design「嘉南羊乳 主控台 Design System」的發行版(claude.ai/design/p/5325442c…,byte-exact vendor+PROVENANCE 記 etag)——冷灰藍抗疲勞紙面、皇藍 #02419a、五套語意色階(WCAG AA)、Noto Sans TC+JetBrains Mono、內建 dark mode、.ds-* 元件 1:1 對映 Flux。tailwind.css 橋接讓既有 blade 不改 markup 換裝。首發消費者:Livewire 薪資站(topbar+rail 官方殼,截圖驗證)。⚠️ v0.1 自創方向(乳白×黃銅×襯線)作廢——改 token 一律先改 Claude Design 原稿再同步
階段出口任一站的 DB 帳號都能在矩陣裡指出對應行;david 帳號連續 7 天零新連線後停用;矩陣+services.json 進版控
▼ 重建型工地,開工前先過「通用檢核」的開工三問 ▼
硬門檻scaffold 隔離五件套:/next/* 路徑分流、專屬 DB 帳號只授權新世代表、票據式登入(不共用 APP_KEY)、獨立 FPM pool/cache/queue、CI 舊表攔檢
驗證SHOW GRANTS FOR erpnext_app 無任何舊表;在新殼實測 SELECT 舊表要噴權限錯誤;舊 ERP 的 session cookie 打新殼路徑必須無效;FPM pool 與 queue worker 各自獨立可重啟互不影響
CI 舊表攔檢 negative test
驗證故意提交一段引用 hcust_dorder 的程式,CI 必須紅——護欄沒被觸發過等於沒有護欄
AI 地基 day-one:Pest 測試安全網、CLAUDE.md 慣例、服務目錄掛載
驗證composer test 綠且進 CI;CLAUDE.md 含 DB 帳號邊界、命令 API 慣例、金絲雀跑法三件事
ERP-一「基礎資料」上線:customers、weekly_orders CRUD、地址簿、marea 奶區、hum 員工、定價
驗證每頁在新殼完成一次真實新增→修改,回舊 ERP 對應頁面看到同一筆資料(同庫立即一致);內勤實際改用新頁面操作日常
命令 API /next/api/v1 三性質:冪等、狀態機、審計
驗證同 idempotency key 重放兩次只落一筆;非法狀態轉移被拒(測至少一組);審計 log 含 actor+前後值;這組測試進 CI 長駐
舊 ERP 凍結生效(流程面):只修 bug,新功能一律進新殼
驗證凍結公告後,舊 repo git log 只有 bugfix;出現例外要有成文豁免理由
硬門檻營運金絲雀測試組建立並全綠:下單、估奶、路條、異動、帳務彙總五場景,用去識別資料集
驗證金額與瓶數 exact match,不設容差;連續 7 天(建議值)每日跑全綠才算建成——這組是階段 3~5 每次切流量的共同前置
階段出口第一批頁面在新殼上線且被真實使用(access log 為證);金絲雀連續全綠;隔離五件套全數驗過
每搬一塊(forms → ny26 → shop → www API)都過同一組五關,順序不可跳:①寫入改走命令 API ②新舊雙寫上線 ③對帳告警先行 ④兩個月結綠燈 ⑤關舊路
驗證①該塊功能正常後,把該站 DB 帳號對應表的寫入權 REVOKE 掉再跑一輪——還能動才證明真的走 API 了
硬門檻對帳 job+告警建好才准切流量:每日新舊筆數 × 金額對帳
驗證告警演練——故意注入一筆差異,告警要在下一個對帳週期內送達(LINE/cron_alerts);演練紀錄成文。沒演練過的告警視同不存在
硬門檻連續兩個完整月結對帳綠燈才切換
驗證兩個月結節點的對帳報告存檔;期間任何差異都有成文解釋;金絲雀(階段 2 建的)同步全綠
金流契約迴歸:linepay/newebpay callback 簽名與回傳 key 不變(crm_order_api 三入口是金流契約)
驗證composer test:sms 綠;callback 失敗分支仍走 logPaymentCallbackFailure();測試環境實打一筆金流 sandbox 完整流程
shop 併庫「先程式後資料」:程式先改讀 goalu,綠燈跨一個月結後才搬資料
驗證程式切換後 shop 舊庫查詢歸零(processlist/general log 抽查);資料搬遷前後 row count+金額彙總一致
綠燈後退役外圍站訂單舊邏輯:舊寫入路徑關閉,不是留著「以防萬一」
驗證舊路徑回 410+觸擊 log;跨一次月結零觸擊才刪碼
階段出口訂單/會員資料的 writer 清單(processlist+audit log 實抓,非推論)只剩 ERP 新殼帳號
雙算單寫上線:舊 DailyPre 維持唯一正式寫入,新殼估奶只寫 staging
驗證正式表 writer 監控只有舊程式帳號;staging 逐筆比對報告每日產出
硬門檻比對達標才 cutover:瓶數 × 金額 × 客戶數逐筆,連續 14 天(建議值,需含至少一次月結節點)零差異或差異全數成文可解釋
驗證比對報告存檔;cutover 時停舊排程(goalu.tasks 對應任務 status=0)、記 cutover epoch;回退開關先演練一次(切回舊、再切回新,各跑一日比對)
ERP-三「配送執行」跟進:DvDvm 日計、DvReport 路條(多為唯讀消費端)
驗證挑一個配送日,新舊路條全區並排比對一致(含團戶、下午奶梯次等邊角)
舊表讀者地圖成文:hcust_dorder、hcust_dv… 每表列出還在讀的站台/頁面
驗證CBM 引用+grep 交叉;地圖進版控,之後每搬一個讀者就更新
雷判表死活用 information_schema.TABLES.UPDATE_TIME;tr_date/str_date 是業務日期會有未來值,不可當寫入時戳
讀者逐個搬到新表:每搬一個,該頁面輸出與搬前一致
驗證搬遷前後同參數輸出 diff=0(抓具代表性的三種查詢條件)
硬門檻停 SyncOld 前讀者必須歸零:一組一組停,不整批
驗證該舊表 UPDATE_TIME 之外的讀證據歸零(讀者地圖清空+access log);停用後跨一個月結無人回報資料異常,引用該表的程式此時才算真死碼
dorder 真死區隔離(10–15 檔,可提早並行):410+觸擊 log
驗證跨一次完整月結零觸擊才刪;刪除 commit 附觸擊 log 證據
階段出口估奶正式表 writer=新殼(監控為證);至少一組 SyncOld 停用且跨月結無回報;讀者地圖與現實一致
SSO 共用入口上線:一套帳號進所有模組(報表站雙登入在此徹底消滅)
驗證使用者實走:登入一次、跨三個模組不再要密碼;舊入口逐一 301 到新入口
模組硬邊界:route group+service 層,禁互讀 model;BI 走唯讀帳號
驗證negative test——模組 A 直接 use 模組 B 的 model,CI 要攔;報表/BI 模組帳號 SHOW GRANTS 無任何寫入權
各模組逐一遷入並驗收:電訪(含 PBX monitor)、報表 93 支(留 legacy 區者成文列冊)、FLUX 十頁 BI、庫存、invoice 行政表單
驗證每模組:主流程 smoke test+舊站流量歸零後才關;93 支報表逐支標「遷入/legacy 保留/退役」三態,無漏網
硬門檻人資模組四配套缺一不可:專屬 DB 帳號/獨立 route+middleware/附件出 web root/匯出審計
驗證逐項實測:非人資帳號打人資 route 被拒;curl 直打附件路徑必須 404;匯出動作在審計 log 可查到 actor+時間+範圍。出過一次跨模組事故即升級獨立站(既定裁示)
硬門檻兩套薪資同月比對合一:Livewire 版 vs html/salary 舊版——使用者 8/17 裁示:Livewire 薪資(/var/www/salary,:6048,每月算薪使用中)為人資模組第一個整合標的
驗證同一個月全員逐欄 diff=0(差異逐筆解釋並裁決孰對)才切換;切換後舊版唯讀封存一季再下線。⚠️ 它是月頻應用:驗證窗至少涵蓋一次完整月結薪資計算。進度2026-08-17 Livewire 版轉換完成:Laravel 13+Vite/Tailwind 4+Pest、最小權限 DB 帳號+匯出審計上線、算薪 stored procedure 入版控+93 golden master(順手修 salary_dv 冪等 bug+3 倍提速並部署正式庫);9 月算薪實戰驗收+10 月保固後收案,細節見 /var/www/salary/docs/
行動入口 m.kng.tw 上線:erp-next 行動區+PWA,依角色出模組
驗證手機實測可安裝(manifest+service worker);業務員與配送員帳號各只見自己的模組;離線開啟不白屏
吸收三個來源站:sales.kng.tw 業務功能逐頁 → delivery 日誌 → kn 軌跡/積分/獎金(過渡期三站照跑)
驗證每頁吸收後來源頁 301 到 m;三站 vhost log 各自歸零連續一個月(建議值)才退役——外勤是日用系統,流量歸零=使用者真的搬完了
LINE 站收尾(條件觸發):www/api/linebot 殘留確認被涵蓋、通知全走 kng/notify
驗證舊通知路徑觸擊 log 歸零;trades tr_id=60 補登在新路徑仍完整(抽查一批發送紀錄)
階段出口對外 DNS/vhost 清單=終態 6 部署(對外站、ERP、對內站、m、LINE、PBX);kn/delivery/sales.kng.tw 流量歸零後下線
硬門檻開工前置:階段 2–5 出口檢核全過、全域無其他重建工地進行中
驗證逐階段出口檢核勾稽本頁;trades 是帳務心臟,前面沒收乾淨不動它
TradeService+DailyRenew 搬遷:trades 三方寫入場景各有比對測試(人工調整、重估覆蓋、系統異動)
驗證雙算比對同階段 4 模式;以「跑過完整月結」驗收,不以測試綠為驗收;00:10 daily:renew 寫 hcust/customers 的行為前後一致
死碼五關分批刪:HTTP 流量、任務表、CBM 引用、資料證據、業務確認
驗證每批刪除 commit 附五關證據;ERP 排程在 goalu.tasks(31 筆,非 Kernel),任務表這關不可用 Kernel.php 代替
終態驗收:每個切片過完成定義四件——舊入口關、舊 writer 停、同步縮、可刪除
驗證切片清單逐一勾稽;任何一件未過的切片不算完成,留在清單上
舊 ERP 整包退役:strangler 的終點是殺死宿主
驗證vhost 關、repo 封存、DB 帳號回收;衡量整條路線成敗的最後一題:舊 ERP 是否真的歸零,而不是留下第二套 ERP
終點存活 6 部署、goalu 唯一寫入者=ERP、舊 ERP 退役
開工三問——上一個重建工地的出口檢核全過了嗎?這件事是維護軌(可並行)還是重建軌(要排隊)?金絲雀現在是綠的嗎?
切流量四問——對帳告警演練過了嗎?回退開關演練過了嗎?切換單位夠小嗎?下一次月結誰盯對帳報告?
驗收原則——動到訂單路徑或 ERP 的變更,以「跑過完整月結」為驗收,不以「測試綠了」為驗收;negative test 沒紅過的護欄視同不存在。