Files
DashBoard/openspec/changes/archive/2026-02-13-reject-history-query-page/proposal.md

61 lines
4.5 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.

## Why
目前專案僅在 `query-tool` 提供偏即時/點查型的報廢資訊,缺少可追蹤趨勢與績效的「報廢歷史」專用報表。資料評估也顯示 `DW_MES_LOTREJECTHISTORY` 同一 `HISTORYMAINLINEID` 會對應多筆原因紀錄,若直接加總 `MOVEINQTY` 會造成分母重複、報廢率失真;同時既有查詢對 reject/defect 命名語義不一致,容易誤解指標。另 IT 新開放 `ERP_PJ_WIP_SCRAP_REASONS_EXCLUDE`,其中 `ENABLE_FLAG='Y'` 代表「不納入良率計算」報廢原因,提案需把此政策納入計算流程。現在應在既有 portal-shell + Vite + route contract 架構下,建立一個語義明確且可治理的歷史報表頁。
## What Changes
- 新增 `報廢歷史查詢` 頁面路由 `/reject-history`,採用既有 pure Vite + portal-shell native route 模式,納入抽屜導航與頁面治理。
- 新增後端 `reject-history` API 群組(摘要 KPI、日/週趨勢、原因 Pareto、明細、匯出提供前端報表所需資料。
- 新增 `reject-history` service + SQL 模組,建立一致指標定義並明確拆分兩條指標線:
- 扣帳報廢:`REJECT_TOTAL_QTY = REJECTQTY + STANDBYQTY + QTYTOPROCESS + INPROCESSQTY + PROCESSEDQTY`
- 不扣帳報廢:`DEFECT_QTY = DEFECTQTY`
- 以事件層級去重規則處理分母(`MOVEIN_QTY``HISTORYMAINLINEID` 為主鍵去重),避免多原因拆單導致比率失真。
- 納入 `ERP_PJ_WIP_SCRAP_REASONS_EXCLUDE` 政策(`ENABLE_FLAG='Y'`
- 預設排除「不納入良率計算」報廢原因
- 提供可選開關讓使用者決定是否納入該類報廢
- 新增排除清單全表快取(每日一次)機制,採共享快取優先策略,降低每次查詢重複讀表成本。
- 明確定義 UI/API/匯出欄位語義避免沿用「defect=五欄合計」這類歷史命名混淆,確保報表對外語意一致。
- 不變更既有 `query-tool` 現有頁面行為與既有 API 回應欄位(此變更先聚焦新頁能力)。
## Capabilities
### New Capabilities
- `reject-history-page`: 新增報廢歷史查詢頁面提供篩選、KPI、趨勢、原因分析、明細查詢與匯出。
- `reject-history-api`: 新增報廢歷史 API 能力與資料聚合邏輯支援報表層的摘要、趨勢、Pareto、明細資料來源。
- `reject-metric-semantics`: 新增 reject/defect 指標語義規範,要求五個 reject 欄位合計與 `DEFECTQTY` 必須分開呈現、分開計算、分開命名。
- `reject-yield-exclusion-policy`: 新增「不納入良率計算」政策能力,依 `ERP_PJ_WIP_SCRAP_REASONS_EXCLUDE.ENABLE_FLAG='Y'` 控制預設排除,並支援使用者切換是否納入。
### Modified Capabilities
- `unified-shell-route-coverage`: 新增 `/reject-history` 後,路由契約清單與前後端契約對照規則需同步更新。
- `vue-vite-page-architecture`: 新頁面需納入 Vite entry/output 與 Flask static HTML 服務規範,保持既有純 Vite 頁治理一致性。
- `field-name-consistency`: reject/defect 相關欄位在 UI、API、匯出命名需維持一致語義避免跨頁面誤用。
## Impact
- 前端:
- 新增 `frontend/src/reject-history/``App.vue``main.js`/`index.html`、components、composables、style
- 更新 `frontend/src/portal-shell/nativeModuleRegistry.js`
- 更新 `frontend/src/portal-shell/routeContracts.js`
- 更新 `frontend/vite.config.js`
- 後端:
- 新增 `src/mes_dashboard/routes/reject_history_routes.py`
- 新增 `src/mes_dashboard/services/reject_history_service.py`
- 新增 `src/mes_dashboard/services/scrap_reason_exclusion_cache.py`
- 新增 `src/mes_dashboard/sql/reject_history/*.sql`
- 更新 `src/mes_dashboard/routes/__init__.py`
- 更新 `src/mes_dashboard/app.py``/reject-history` 靜態頁 route
- 導航/治理:
- 更新 `data/page_status.json`drawer 與頁面可見性)
- 更新 shell route contract 對應治理資產與測試基準
- 測試:
- 新增 `tests/test_reject_history_service.py`
- 新增 `tests/test_reject_history_routes.py`
- 新增 `tests/test_scrap_reason_exclusion_cache.py`
- 補充 route coverage / contract parity / e2e smoke
- 資料語義:
- 報表需同時呈現 `REJECT_TOTAL_QTY`(扣帳報廢)與 `DEFECT_QTY`(不扣帳報廢)
- `ENABLE_FLAG='Y'` 報廢原因預設不納入良率計算,且可由使用者選擇改為納入
- 不以單一欄位混用兩種語義,避免誤判製程損失
- 依賴:
- 不新增第三方套件,沿用現有 Flask + Vue + Vite + SQLLoader + QueryBuilder 架構