Files
DashBoard/openspec/changes/archive/2026-02-08-residual-hardening-round4/design.md

3.2 KiB
Raw Blame History

Context

round-3 後主流程已穩定,但仍有 3 類技術債:

  • Resource 快取在同一 process 內同時保存 DataFrame 與完整 records 複本,導致記憶體放大。
  • Resource 與 Realtime Equipment 的 Oracle 查詢存在跨服務重複字串,日後修改容易偏移。
  • 部分服務邊界型別註記與魔術數字未系統化,維護成本偏高。

約束條件:

  • resource / wip 維持全表快取策略,不改資料來源與刷新頻率。
  • 對外 API 欄位與前端行為不變。
  • 保持單一 port 架構與既有運維契約。

Goals / Non-Goals

Goals:

  • 降低 Resource 快取在 process 內的重複資料表示,保留查詢輸出相容性。
  • 讓跨服務 Oracle 查詢片段由單一來源維護。
  • 讓關鍵 service/cache 模組具備一致的型別註記與具名常數。

Non-Goals:

  • 不改動資料庫 schema 或 SQL 查詢結果欄位。
  • 不重寫整體 cache 架構Redis + process cache 維持)。
  • 不引入新基礎設施或外部依賴。

Decisions

  1. Resource derived index 改為「row-position index」而非保存完整 records 複本
  • 現況index 中保留 records 與多組 bucket records與 DataFrame 內容重複。
  • 決策index 只保留 row positions整數索引與必要 metadata需要輸出 dict 時由 DataFrame 按需轉換。
  • 取捨:單次輸出會增加少量轉換成本,但可顯著降低常駐記憶體重複。
  1. 建立共用 Oracle 查詢常數模組
  • 現況:resource_cache.pyrealtime_equipment_cache.py 各自維護 base SQL。
  • 決策:抽出 services/sql_fragments.py(或等效模組)管理共用 query 文本與 table/view 名稱。
  • 取捨:增加一層間接引用,但查詢語意一致性與變更可控性更高。
  1. 型別與常數治理採「先核心邊界,後擴散」
  • 現況:部分函式已使用 Optional / PEP604 混搭,且魔術數字散落於 cache/service。
  • 決策先統一這輪觸及檔案中的型別風格與高頻常數TTL、size、window、limits
  • 取捨:不追求一次全專案清零,以避免大範圍 noise先建立可持續擴展基線。

Risks / Trade-offs

  • [Risk] row-position index 與 DataFrame 版本不同步 → Mitigation每次 cache invalidate 時同步重建 index並保留版本檢查。
  • [Risk] 惰性轉換導致查詢端 latency 波動 → Mitigation保留 process cache並對高頻路徑做小批量輸出優化。
  • [Risk] SQL 共用常數抽離造成引用錯誤 → Mitigation補齊單元測試驗證 query 文本與既有欄位契約一致。
  • [Risk] 型別/常數清理引發行為改變 → Mitigation僅做等價重構保留原值並用回歸測試覆蓋。

Migration Plan

  1. 先重構 Resource index 表示,確保 API 輸出不變。
  2. 抽離 SQL 共用片段並替換兩個快取服務引用。
  3. 清理該範圍型別與常數,補測試。
  4. 更新 README / README.mdj 與 OpenSpec tasks跑 backend/fronted 目標測試集。

Rollback

  • 若出現相容性問題,可回退至原 index records 表示與舊 SQL 內嵌寫法(單檔回退即可)。

Open Questions

  • 是否要在下一輪把相同治理擴展到 wip_service.py 的其餘常數與型別(本輪先限定 residual 範圍)。