Files
DashBoard/docs/reject_history_performance.md

6.9 KiB
Raw Blame History

Reject 歷史績效表設計說明

目標

使用 DW_MES_LOTREJECTHISTORY 為主,輔以其他維度表,建立可直接用於報表的 reject 歷史績效表(按日彙總),解決原始資料直接查詢時的績效與一致性問題。

使用資料表

  • DWH.DW_MES_LOTREJECTHISTORY: 不良/報廢事實表(主來源)
  • DWH.DW_MES_CONTAINER: 補齊 PJ_TYPEPRODUCTLINENAMEMFGORDERNAME
  • DWH.DW_MES_SPEC_WORKCENTER_V: 對應 WORKCENTER_GROUP 與排序欄位
  • DWH.ERP_PJ_WIP_SCRAP_REASONS_EXCLUDE: 良率排除政策表(ENABLE_FLAG='Y' 代表不納入良率計算)

資料評估重點2026-02-13近 30 天樣本)

  • DW_MES_LOTREJECTHISTORY230,074 筆;HISTORYMAINLINEID75,683 個。
  • HISTORYMAINLINEID 多筆情況明顯(30,784 個主事件,平均每主事件 6.02 筆),代表同主事件會拆成多個 LOSSREASONNAME
  • 若直接加總 MOVEINQTY,分母會被重複計算。近 30 天樣本中:
    • NAIVE_MOVEIN = 44,836,693,831
    • DEDUP_MOVEIN = 35,658,750,247
    • 膨脹比 1.2574(約高估 25.74%
  • 指標定義依業務規則分開處理:
    • REJECT_TOTAL_QTY = REJECTQTY + STANDBYQTY + QTYTOPROCESS + INPROCESSQTY + PROCESSEDQTY(扣帳報廢)
    • DEFECT_QTY = DEFECTQTY(不扣帳報廢)
  • DW_MES_SPEC_WORKCENTER_V 若直接以 WORK_CENTER join 會放大筆數;需先彙整為唯一 WORK_CENTER -> GROUP/SEQUENCE 對照表再 join。

績效表欄位與計算邏輯

  • 粒度:日 + 工站群組 + 工站 + 站點規格 + 設備 + 產品維度 + 不良原因
  • 核心指標:
    • REJECT_EVENT_ROWS: 原始 reject 紀錄筆數
    • AFFECTED_LOT_COUNT: 受影響 lot 數distinct CONTAINERID
    • MOVEIN_QTY: 以 HISTORYMAINLINEID 去重後的投入量
    • REJECT_QTY: 原始 REJECTQTY 加總(五欄之一)
    • REJECT_TOTAL_QTY: 五個 reject 相關欄位加總(扣帳報廢)
    • DEFECT_QTY: DEFECTQTY 加總(不扣帳報廢)
    • REJECT_RATE_PCT = REJECT_TOTAL_QTY / MOVEIN_QTY * 100
    • DEFECT_RATE_PCT = DEFECT_QTY / MOVEIN_QTY * 100
    • REJECT_SHARE_PCT = REJECT_TOTAL_QTY / (REJECT_TOTAL_QTY + DEFECT_QTY) * 100

排除政策與前端開關

  • 預設模式:排除 ERP_PJ_WIP_SCRAP_REASONS_EXCLUDEENABLE_FLAG='Y' 的報廢原因。
  • 可切換模式:提供 include_excluded_scrap=true|false 讓使用者決定是否納入。
  • 前端頁面提供「納入不計良率報廢」開關,並同步影響 summary/trend/pareto/list/export。
  • 排除原因清單採全表快取預設每日刷新一次Redis 優先、記憶體 fallback

API 與欄位契約

  • GET /api/reject-history/options
    • 回傳 workcenter_groupsreasons 與政策 meta
  • GET /api/reject-history/summary
    • 回傳 MOVEIN_QTYREJECT_TOTAL_QTYDEFECT_QTYREJECT_RATE_PCTDEFECT_RATE_PCTREJECT_SHARE_PCTAFFECTED_LOT_COUNTAFFECTED_WORKORDER_COUNT
  • GET /api/reject-history/trend
    • 回傳趨勢 items[],每筆含 bucket_dateREJECT_TOTAL_QTYDEFECT_QTYREJECT_RATE_PCTDEFECT_RATE_PCT
  • GET /api/reject-history/reason-pareto
    • 支援 metric_mode=reject_total|defect
    • 支援 pareto_scope=top80|all(預設 top80
  • GET /api/reject-history/list
    • 分頁回傳 items[]pagination
    • 明細保留五個 reject 欄位(REJECT_QTYSTANDBY_QTYQTYTOPROCESS_QTYINPROCESS_QTYPROCESSED_QTY)與 DEFECT_QTY
  • GET /api/reject-history/export
    • CSV 欄位與 list 語義一致,含 REJECT_TOTAL_QTYDEFECT_QTY

前端視覺與互動

  • 主要區塊:
    • Header語義 badge + 更新時間)
    • 篩選區(時間、原因、WORKCENTER_GROUP、政策開關、Pareto 前 80% 開關)
    • KPI8 張卡Reject 暖色語義 / Defect 冷色語義)
    • 趨勢圖(報廢量與報廢率分圖)
    • Pareto柱狀 + 累積線)與明細表
  • 互動規則:
    • Pareto 點選原因後,會套用為 active filter chip 並重查
    • 再次點選同原因會取消篩選
    • 預設僅顯示累計前 80%,可切換顯示完整 Pareto
    • 匯出 CSV 使用目前畫面相同篩選條件

交付檔案

  • 建表 + 刷新 SQLdocs/reject_history_performance.sql
  • 可被應用層直接載入的查詢 SQLsrc/mes_dashboard/sql/reject_history/performance_daily.sql

上線與回滾策略

  • 上線策略:
    • 先維持 data/page_status.json/reject-historydev
    • 完成 UAT 後再改為 released
  • 回滾策略:
    • /reject-history 狀態切回 dev 或移除導航入口
    • 保留 API 與既有頁面,不影響既有報表
  • 快取策略:
    • 排除政策表每日全表刷新(預設 86400 秒)
    • Redis 異常時退回記憶體快取,不阻斷查詢

驗證紀錄2026-02-13

  • 後端/整合測試:
    • pytest -q tests/test_reject_history_service.py tests/test_scrap_reason_exclusion_cache.py tests/test_reject_history_routes.py tests/test_reject_history_shell_coverage.py tests/test_portal_shell_wave_b_native_smoke.py::test_reject_history_native_smoke_query_sections_and_export tests/test_app_factory.py::AppFactoryTests::test_routes_registered
    • 結果:22 passed
  • 前端建置:
    • cd frontend && npm run build
    • 結果:成功產出 reject-history.html/js/css,並完成 dist 複製流程

建議排程

  • 每日跑前一日增量:
    • :start_date = TRUNC(SYSDATE - 1)
    • :end_date = TRUNC(SYSDATE - 1)
  • 每月第一天補跑前 31 天,避免補數漏失。

Cache-SQL RolloutDuckDB

  • 階段順序:batch-pareto -> view -> export-cached
  • 預設全開:
    • REJECT_CACHE_SQL_ENABLED=true
    • REJECT_CACHE_SQL_BATCH_PARETO_ENABLED=true
    • REJECT_CACHE_SQL_VIEW_ENABLED=true
    • REJECT_CACHE_SQL_EXPORT_ENABLED=true
  • 回退策略(預設回退 legacy
    • REJECT_CACHE_SQL_FALLBACK_LEGACY_ENABLED=true
    • 可用 endpoint 級旗標單獨控制 *_FALLBACK_LEGACY_ENABLED
  • 灰度建議:
    • 先只開 batch-pareto,觀察 pareto_source 與 fallback reason
    • 再開 view,確認 detail.pagination 與舊版一致
    • 最後開 export-cached,確認 CSV 欄位/筆數與 view detail 篩選範圍一致

驗證清單(前端提示與匯出一致性)

  • 前端「柏拉圖顯示限制80%/Top20」僅影響畫面顯示不影響明細與匯出範圍。
  • 使用相同 query_id + filters 比對:
    • GET /api/reject-history/viewdetail.pagination.total
    • GET /api/reject-history/export-cached 的匯出總筆數
    • 兩者應一致display-only truncation 不得裁掉 export row
  • 若觸發 cache-SQL fail-fast*_FALLBACK_LEGACY_ENABLED=false),前端需提示使用者重試或縮小條件。

已知環境備註

  • tests/test_navigation_contract.py 需要 docs/migration/portal-no-iframe/baseline_drawer_visibility.json。目前工作區缺少此 baseline 檔案,屬既有環境缺口,與本次 reject-history 開發內容無直接耦合。