Skip to content

[Refactor] GAS 重構準備度決策 — 路線 A + Phase 0 行為測試前置 #129

Description

@cheerc

背景

團隊四人(Lead / Impl1 / Impl2 / Reviewer)對 classroombooking 重構準備度進行正反辯論後,做出以下決策。

團隊決策(2026-06-23 全員共識)

安全網評估

  • 905 個測試數量充足但類型偏差嚴重 — wiring/contract 測試佔比過高,行為測試(輸入→輸出正確性)缺失
  • Impl2 精確分類:wiring tests ~7 files 在重構中會全部紅掉變 noise,真正有保護力的 behavior tests ~8 files 只覆蓋 utility 層
  • Reviewer 評估:review 信心 40-50%,code review 對執行順序/this 綁定/全域時序 regression 抓到率 <10%
  • 結論:直接啟動重構的風險不可接受

路線決定

  • 路線 A — GAS 內模組化(IIFE 封裝 + include() 拆分):最小風險、可增量驗證、wiring tests 最有價值
  • ❌ 路線 B(前端 bundler):A 完成前不做(A 完成後自然形成 B 前提)
  • ❌ 路線 C(完全遷離 GAS):需 operator 決定 + 重寫 auth/CORS/hosting,目前不適合

執行計畫

Phase 0(重構前必做)— 行為測試安全網

Tier 測試項目 Issue
阻斷 saveDataToServerloadDataFromServer round-trip 行為 TBD
阻斷 handleScheduleListClick 四分支覆蓋(rename/delete/copy/settings) TBD
阻斷 Filter pipeline 端到端(applyTagFilters → render) TBD
阻斷 init() event binding 完整性清單 TBD
阻斷 Coverage ratchet(vitest.config.js ≥55%) TBD
高風險 Undo/Redo state integrity(dirty flag 正確性) 待評估
高風險 Lock management 行為(多 tab concurrency) 待評估
高風險 ensureDataIds idempotency 待評估

Phase 1(Phase 0 完成後)— 路線 A 重構

  1. JavaScript.html 7 個職責域分離(每域 = 1 PR)
  2. God Object App → composition pattern(注入依賴取代全域引用)
  3. 每個 PR 附「拆前 vs 拆後 wiring test 對照」

Phase 2(未來評估)— 路線 B 考量

重構目標模式

// IIFE 封裝 + 顯式依賴注入(取代全域 scope 污染)
// StateManager.js.html
<script>
(function(App) {
  const StateManager = {
    getActiveSchedule() { return App.schedules[App.activeScheduleId]; },
    setDirty(val) { App.isDirty = val; },
  };
  App.StateManager = StateManager;
})(App);
</script>

GAS HTML Inline 主要障礙(團隊識別)

  1. 無 module systeminclude() = 文字拼接,全域 scope 污染
  2. 隱式依賴 + 雙路徑引用 — 模組既用 app.xxx(參數)又用全域 AppConfig.xxx
  3. 載入順序 = 隱式 API 契約 — Config → Elements → Api → Modals → History → UI → Interaction → JavaScript
  4. Template scriptlet<?= ?> server-side 注入,bundler 不相容
  5. dev/release 共用 Sheets 資料庫 — mutating 操作失敗 = 真實資料損壞

Related

🤖 opened by: lead (cb-team-lead)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions