Files
DashBoard/openspec/changes/archive/2026-03-03-add-material-trace-page/design.md
egg 777751311c
Some checks failed
full-modernization-gates / frontend-route-governance (push) Has been cancelled
full-modernization-gates / backend-modernization-gates (push) Has been cancelled
released-pages-hardening-gates / released-pages-hardening (push) Has been cancelled
feat: add material trace page for bidirectional LOT/material query
Implement full-stack material trace feature enabling forward (LOT/工單 → 原物料)
and reverse (原物料 → LOT) queries with wildcard support, safeguards (memory guard,
IN-clause batching, Oracle slow-query channel), CSV export, and portal-shell integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:32:41 +08:00

79 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## Context
工程師需要查詢 LOT/工單對應的原物料消耗記錄,以及反向從原物料批號追溯使用該批料的所有 LOT。目前原物料資訊只能在 Query Tool 的 LotDetail "原物料" tab 逐筆查看(透過 `/api/trace/events?domains=["materials"]`),不支援批量輸入或反向查詢。
資料來源 `DWH.DW_MES_LOTMATERIALSHISTORY` 有 1800 萬筆記錄,已建立四個索引:
- IDX1: `CONTAINERID`(正向 LOT 查詢)
- IDX2: `PJ_WORKORDER`(正向工單查詢)
- IDX3: `MATERIALPARTNAME`(料號,本次不使用)
- IDX4: `MATERIALLOTNAME`(反向原物料批號查詢)
站群組WORKCENTER_GROUP對應由 `filter_cache.get_workcenter_mapping()` 提供,從 `DW_MES_SPEC_WORKCENTER_V` 載入,每小時刷新。
## Goals / Non-Goals
**Goals:**
- 提供獨立頁面支援正向LOT ID / 工單 → 原物料)和反向(原物料批號 → LOT雙向查詢
- 正向查詢支援 LOT ID 和工單兩種輸入模式切換
- 支援多筆輸入(換行/逗號分隔)
- 結果含站群組篩選、分頁、CSV 匯出
- 使用既有 Oracle 索引,查詢效率可控
**Non-Goals:**
- 不支援 MATERIALPARTNAME料號反向查詢資料量風險過高同一料號可能數萬筆
- 不需日期範圍篩選(以 LOT/工單/原物料批號為查詢條件即可)
- 不做 Redis 快取或 BatchQueryEngine 分片(查詢範圍由輸入筆數控制,非時間範圍)
- 不做 BOM 對照或原物料品質統計
## Decisions
### D1: 使用 `read_sql_df`pooled connection而非 `read_sql_df_slow`
**決定**: 查詢使用 pooled connection`read_sql_df`),不走 slow query path。
**理由**: 此查詢依賴索引命中,預期回應時間 < 5s不像 reject-history 的全表掃描需要 dedicated connection正向查詢最多幾千筆結果反向查詢設結果上限 10,000
**替代方案**: 使用 `read_sql_df_slow`
**為何不採用**: 佔用 slow query semaphore 會排擠需要長時間執行的查詢reject-historyresource-history)。
### D2: 正向查詢先解析 LOT ID → CONTAINERID
**決定**: LOT ID 輸入模式需要先將 CONTAINERNAME 轉換為 CONTAINERID16-char hex因為 `LOTMATERIALSHISTORY` 的索引是 CONTAINERID使用 `DW_MES_CONTAINER` batch lookup工單模式直接查 `PJ_WORKORDER` 索引不需轉換
**理由**: 使用者輸入的是可讀的 LOT 名稱 GA25060001-A01但資料表索引是 CONTAINERID直接 JOIN 會讓 optimizer 可能選擇低效計畫 batch resolve 再用 IN clause 更可預測
**替代方案**: SQL 內直接 JOIN CONTAINER
**為何不採用**: 對於多筆 LOT 輸入兩步驟resolve + query的執行計畫更穩定 resolve 結果可重用於顯示
### D3: 站群組篩選在後端 enrichment 而非 SQL WHERE
**決定**: SQL 查詢不加 WORKCENTERNAME 過濾查詢結果回來後後端用 `get_workcenter_mapping()` 對每列添加 `WORKCENTER_GROUP` 欄位前端可做篩選若使用者選了站群組篩選後端先 resolve 站群組 WORKCENTERNAME 清單再在 SQL `AND WORKCENTERNAME IN (...)` 過濾
**理由**: 如果不篩選使用者能看到所有站點的資料含站群組欄位)。如果篩選了SQL 層就縮減結果集減少傳輸和分頁壓力
### D4: 反向查詢結果數上限 10,000 筆
**決定**: 反向查詢原物料批號 LOT加入 `FETCH FIRST 10001 ROWS ONLY` 上限若回傳超過 10,000 前端顯示警告結果超過上限請縮小查詢範圍」。
**理由**: 一批常用原物料可能被上千個 LOT 使用無上限的反向查詢可能回傳數萬筆壓垮前端和 Oracle 連線10,000 筆足以覆蓋絕大多數場景
### D5: 前端頁面結構沿用 Vite multi-page 模式
**決定**: 新增 `frontend/material-trace.html` + `frontend/src/material-trace/App.vue` 作為獨立 Vite entry point沿用 reject-history 的單檔 App.vue + 子元件模式
**理由**: 專案的所有查詢頁面reject-historyhold-historyresource-history都是獨立 Vite entry統一架構
### D6: 輸入筆數上限
**決定**: 正向查詢LOT ID / 工單輸入上限 200 反向查詢原物料批號輸入上限 50
**理由**: 正向查詢每筆 LOT 平均產生 10-50 筆原物料記錄200 LOT 最多 10,000 筆結果反向查詢每批原物料可能對應 100-1000 LOT50 批已有碰上 10,000 筆上限的風險
## Risks / Trade-offs
- **[] CONTAINERID resolve 多一次 round-trip** LOT ID 模式需先查 `DW_MES_CONTAINER` 轉換。→ Container 表有 CONTAINERNAME 索引batch IN query 很快< 1s)。
- **[] 站群組 mapping 可能未涵蓋所有 WORKCENTERNAME** `DW_MES_SPEC_WORKCENTER_V` 可能缺少新站點。→ 未映射的站點在結果中站群組欄位顯示空值不影響查詢結果
- **[] 反向查詢結果截斷** 10,000 筆上限可能截斷大量使用的原物料批號結果。→ 前端明確顯示截斷警告引導使用者縮小範圍