Files

9.0 KiB
Raw Permalink Blame History

Context

目前 portal.html 透過 iframe + frame_id + toolFrame 在同一頁面切換多個報表。此模式雖可避免整頁跳轉,但帶來以下問題:

  • 內容生命週期拆成多個 frame除錯與事件追蹤困難
  • 導覽邏輯被 iframe lazy-load、高度同步、active frame 狀態綁死
  • 測試對 DOM/互動契約依賴 iframe 結構,變更成本高
  • 已完成 Vite 模組化的頁面其實已可獨立路由載入,不需要 iframe 承載

此外,drawers 設定在目前環境已不是初始預設值,而是營運中配置(來源:data/page_status.json

  • reports即時報表order=1admin_only=false
  • drawer-2歷史報表order=2admin_only=false
  • drawer查詢工具order=3admin_only=false
  • dev-tools開發工具order=4admin_only=true

對應頁面已分散配置在上述抽屜,例如:

  • 即時報表:/wip-overview/hold-overview/resource/qc-gate
  • 歷史報表:/hold-history/resource-history
  • 查詢工具:/job-query
  • 開發工具admin pages 與部分工具頁(含 tablesexcel-queryquery-tooltmtt-defectmid-section-defect

因此本次改造不只是移除 iframe而是要把「抽屜資訊架構」從「載入技術frame耦合」解耦到「路由與權限治理」。

Goals / Non-Goals

Goals:

  • 移除 portal 內容區的 iframe 依賴與 frame 管理邏輯
  • 保留抽屜分組、admin 權限過濾、健康狀態檢查 UI
  • 將側欄點擊行為改為同視窗路由導頁
  • 維持既有 route path 與頁面業務邏輯不變
  • 更新測試使其驗證新契約link/navigation
  • 在不破壞既有 drawers/pages 資料模型下,支持 Router-based 導覽

Non-Goals:

  • 不在第一階段一次重寫全部 legacy 頁面內容
  • 不調整後端 API 介面或權限模型
  • 不更動 page_status.json 的資料模型(僅調整 portal 消費方式)

Decisions

Decision 1: 抽屜保留後端治理,前端改為 Router-aware 導覽

  • 選擇: get_navigation_config() 仍作為抽屜與頁面來源,前端側欄只消費 route / status / admin_only不再消費 frame_id/toolFrame。
  • 理由:
    • 保留既有營運中的抽屜設定與管理流程
    • 抽屜責任回到 IA分類、排序、權限避免綁定載入技術
    • 降低一次性資料遷移與管理頁調整風險
  • 備選方案:
    • 改由前端硬編抽屜:短期可行,但與管理後台脫鉤,營運成本增加

Decision 2: 導入 SPA Shell + Vue Router分階段替換多入口模式

  • 選擇: 建立 SPA shell 承接抽屜導覽,主要報表頁優先轉為 router view既有可獨立頁先保持可直接訪問。
  • 理由:
    • 符合大型遷移所需的漸進路線
    • 可保留既有 URL 合約並分批改造
  • 備選方案:
    • 一次切成全 SPA改動面過大回歸與 rollback 風險高

Decision 3: Legacy 頁面採先包裝、後重寫策略(已確認)

  • 選擇: job-queryexcel-queryquery-tooltmtt-defect 先以 wrapper route 納入新殼層,再逐頁重寫為標準 Vue 模組。
  • 理由:
    • 先完成抽屜/導航/樣式治理,不被單頁重寫阻塞
    • 可逐步替換,控制每次上線風險
  • 備選方案:
    • 直接重寫四頁:會延後主幹遷移,且依賴資料邏輯盤點完整度

Decision 4: Tailwind 為主樣式系統,保留過渡期雙軌

  • 選擇: 新增 Tailwind 設計 token 與元件規範,新功能優先用 Tailwind舊頁 CSS 分批遷移。
  • 理由:
    • 先建立統一規範,避免繼續累積散落 CSS
    • 遷移節奏可與功能迭代對齊

Risks / Trade-offs

  • [Risk] 切頁不再常駐多頁狀態,使用者感知切換較慢Mitigation: 保持頁面 bundle 切分與快取策略,後續再評估 prefetch。
  • [Risk] 既有測試仍假設 iframe DOM 結構Mitigation: 分階段更新 template/e2e/stress 斷言為 router/navigation 契約。
  • [Risk] 抽屜配置與路由表可能出現不一致Mitigation: 新增導航一致性檢查(缺失 route、權限錯置、排序衝突
  • [Risk] Tailwind 與既有 CSS 共存期造成樣式衝突Mitigation: 設定 migration lint 規則與 page-level ownership限制新增散落 CSS。
  • [Risk] Legacy wrapper 週期拉長導致技術債滯留Mitigation: 在 tasks 中明確列出逐頁重寫里程碑與退出條件。

Migration Plan

  1. 定義抽屜-路由契約(來源、排序、權限、可見性)並建立檢查機制。
  2. 建立 SPA shell 與 Router先接管 portal 導覽與主要報表頁入口。
  3. 移除 iframe 導覽路徑,保留舊 URL 行為與 fallback。
  4. 導入 Tailwind 設計系統並建立共用元件層。
  5. 將四個 legacy 頁面先包裝接入新殼層,再分批重寫。
  6. 完成測試與觀測遷移模板、E2E、壓測、性能基線

Current Baseline Snapshot (2026-02-11)

Effective drawer visibility (derived from current drawers + pages + status + admin_only)

  • Non-admin visible routes:
    • reports: /wip-overview, /resource, /qc-gate
    • drawer-2: /resource-history
    • drawer: /job-query
  • Admin visible routes:
    • reports: /wip-overview, /hold-overview, /resource, /qc-gate
    • drawer-2: /hold-history, /resource-history
    • drawer: /job-query
    • dev-tools: /tables, /admin/pages, /excel-query, /admin/performance, /query-tool, /tmtt-defect, /mid-section-defect

Query/route contracts that must not regress

  • /wip-overview: query filters workorder, lotid, package, type, status
  • /wip-detail: query filters workcenter, workorder, lotid, package, type, status
  • /hold-detail: required query reason (missing reason redirects away by current server/client guard)
  • /resource-history: query params built from date range, granularity, groups/families/machines, production flags

Functional Parity Matrix

Route / Surface Migration Mode Must Preserve
/ portal shell SPA (router host) Drawer grouping/order/visibility, health widget, auth-linked visibility
/wip-overview Vue route view Filter URL sync, status filter behavior, drill-down to detail pages
/wip-detail Vue route view Query-param entry, pagination/filter semantics, back-link query continuity
/hold-overview Vue route view Hold type/reason filter behavior, treemap/matrix interaction
/hold-history Vue route view Date/record type filter semantics, reason pareto interactions
/resource Vue route view Group/status filtering and summary parity
/resource-history Vue route view Query validation, summary/detail/export behavior parity
/qc-gate Vue route view Chart↔table linked filtering and refresh behaviors
/job-query Wrapper first Resource/date query, transaction query, CSV export
/excel-query Wrapper first Upload/column detect/query/export workflow
/query-tool Wrapper first Resolve/history/association/equipment-period workflow
/tmtt-defect Wrapper first Date-range query and CSV export workflow

Data Contract Safety Net

  • 建立「遷移前基線快照」:
    • drawer visibility snapshotadmin / non-admin
    • route response smoke snapshotHTTP status + critical payload keys
    • critical page JSON schema snapshotssummary/detail/pagination key sets
  • 建立「遷移後對等檢查」:
    • key presence parity不可缺欄位
    • type compatibility數值/字串/陣列型別)
    • empty-state semantics空資料行為一致
  • 對 legacy wrapper 頁面增加 wrapper-contract 測試:
    • route reachable
    • primary query path success
    • export path reachable (where applicable)

Go / No-Go Gates (Cutover)

  • G1 Route availability:
    • P0 路由portal + major report routes100% 回應 2xx/3xx
  • G2 Drawer parity:
    • admin/non-admin 可見路由集合與 baseline 差異為 0
  • G3 Workflow parity:
    • parity matrix 中每頁核心流程至少 1 條 smoke path 通過率 100%
  • G4 Client stability:
    • E2E 測試中未捕獲未處理 JS runtime errorcritical path
  • G5 Data contract:
    • critical API payload key/type parity gate 全部通過
  • G6 Performance:
    • route switch latency 與 baseline 比較不得惡化超過既定閾值
  • G7 Rollback readiness:
    • rollback rehearsal 完成且時間達標(可在目標時間內恢復舊路徑)

Rollback / Kill-Switch Strategy

  1. 保留舊入口路徑與必要 fallback直到全量 gate 通過。
  2. 使用可配置切換feature flag / env-based toggle控制新 shell 導航啟用。
  3. 一旦觸發回滾條件G1/G2/G3 任一 critical fail立即切回舊導航路徑。
  4. 回滾後保留觀測資料並建立失敗歸因報告,再進行下一輪修復與 rehearsal。

Open Questions

  • frame_id/tool_src 欄位何時在資料模型層正式退場?
  • legacy wrapper 對使用者是否顯示遷移標記(例如 beta badge
  • 動效方案是否在第一版限定 Vue TransitionGSAP 延後到二階段?