Files
DashBoard/openspec/specs/reject-history-page/spec.md
egg e83d8e1a36 feat(reject-history): fix Pareto datasources, multi-select filtering, and UX enhancements
- Fix dimension Pareto datasources: PJ_TYPE/PRODUCTLINENAME from DW_MES_CONTAINER,
  WORKFLOWNAME from DW_MES_LOTWIPHISTORY via WIPTRACKINGGROUPKEYID, EQUIPMENTNAME
  from LOTREJECTHISTORY only (no WIP fallback), workcenter dimension uses WORKCENTER_GROUP
- Add multi-select Pareto click filtering with chip display and detail list integration
- Add TOP 20 display scope selector for TYPE/WORKFLOW/機台 dimensions
- Pass Pareto selection (dimension + values) through to list/export endpoints
- Enable TRACE_WORKER_ENABLED=true by default in start_server.sh and .env.example
- Archive reject-history-pareto-datasource-fix and reject-history-pareto-ux-enhancements
- Update reject-history-api and reject-history-page specs with new Pareto behaviors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:23:16 +08:00

10 KiB

reject-history-page Specification

Purpose

TBD - created by archiving change reject-history-query-page. Update Purpose after archive.

Requirements

Requirement: Reject History page SHALL provide filterable historical query controls

The page SHALL provide a filter area for date range and major production dimensions to drive all report sections.

Scenario: Default filter values

  • WHEN the page is first loaded
  • THEN start_date and end_date SHALL default to a valid recent range
  • THEN all other dimension filters SHALL default to empty (no restriction)

Scenario: Apply and clear filters

  • WHEN user clicks "查詢"
  • THEN summary, trend, pareto, and list sections SHALL reload with the same filter set
  • WHEN user clicks "清除條件"
  • THEN all filters SHALL reset to defaults and all sections SHALL reload

Scenario: Required core filters are present

  • WHEN the filter panel is rendered
  • THEN it SHALL include start_date/end_date time filter controls
  • THEN it SHALL include reason filter control
  • THEN it SHALL include WORKCENTER_GROUP filter control

Scenario: Header refresh button

  • WHEN the page header is rendered
  • THEN it SHALL include a "重新整理" button in the header-right area
  • WHEN user clicks the refresh button
  • THEN all sections SHALL reload with current filters (equivalent to "查詢")

Requirement: Reject History page SHALL expose yield-exclusion toggle control

The page SHALL let users decide whether to include policy-marked scrap in yield calculations.

Scenario: Default toggle state

  • WHEN the page is first loaded
  • THEN "納入不計良率報廢" toggle SHALL default to OFF
  • THEN requests SHALL be sent with include_excluded_scrap=false

Scenario: Toggle affects all sections

  • WHEN user turns ON/OFF the toggle and clicks "查詢"
  • THEN summary, trend, pareto, and list sections SHALL reload under the selected policy mode
  • THEN export action SHALL use the same toggle state

Scenario: Policy status visibility

  • WHEN data is rendered
  • THEN the UI SHALL show a clear badge/text indicating whether policy-marked scrap is currently excluded or included

Requirement: Reject History page SHALL present KPI cards with split reject/defect semantics

The page SHALL display KPI cards that simultaneously show charge-off reject and non-charge-off defect metrics.

Scenario: KPI cards render core metrics

  • WHEN summary data is loaded
  • THEN cards SHALL include MOVEIN_QTY, REJECT_TOTAL_QTY, DEFECT_QTY, REJECT_RATE_PCT, DEFECT_RATE_PCT, REJECT_SHARE_PCT, AFFECTED_LOT_COUNT, and AFFECTED_WORKORDER_COUNT
  • THEN numbers SHALL use zh-TW formatting

Scenario: Visual distinction for semantic lanes

  • WHEN KPI cards are rendered
  • THEN reject-related cards SHALL use a warm-color visual lane
  • THEN defect-related cards SHALL use a cool-color visual lane
  • THEN page legend/badge text SHALL explicitly indicate charge-off vs non-charge-off meaning

The page SHALL show both quantity trend and rate trend to avoid mixing unit scales.

Scenario: Quantity trend chart

  • WHEN trend data is loaded
  • THEN the quantity trend chart SHALL show REJECT_TOTAL_QTY and DEFECT_QTY over time
  • THEN the chart SHALL use a shared X-axis by date bucket

Scenario: Rate trend chart

  • WHEN trend data is loaded
  • THEN the rate trend chart SHALL show REJECT_RATE_PCT and DEFECT_RATE_PCT over time
  • THEN rate values SHALL be displayed as percentages

Requirement: Reject History page SHALL provide reason Pareto analysis

The page SHALL provide a Pareto view for loss reasons and support downstream filtering.

Scenario: Pareto rendering and ordering

  • WHEN Pareto data is loaded
  • THEN items SHALL be sorted by selected metric descending
  • THEN a cumulative percentage line SHALL be shown

Scenario: Pareto 80% filter is managed in supplementary filters

  • WHEN the page first loads Pareto
  • THEN supplementary filters SHALL include "Pareto 僅顯示累計前 80%" control
  • THEN the control SHALL default to enabled

Scenario: TYPE/WORKFLOW/機台 support display scope selector

  • WHEN Pareto dimension is TYPE, WORKFLOW, or 機台
  • THEN the UI SHALL provide 全部顯示 and 只顯示 TOP 20 options
  • THEN 全部顯示 SHALL still respect the current 80% cumulative filter setting

Scenario: Pareto click filtering supports multi-select

  • WHEN user clicks Pareto bars or table rows
  • THEN clicked items SHALL become active selected chips
  • THEN multiple selected items SHALL be supported at the same time
  • THEN detail list SHALL reload using current selected Pareto items as additional filter criteria

Scenario: Re-click clears selected item only

  • WHEN user clicks an already selected Pareto item
  • THEN only that item SHALL be removed from selection
  • THEN remaining selected items SHALL stay active

Requirement: Reject History page SHALL show paginated detail rows

The page SHALL provide a paginated detail table for investigation and traceability.

Scenario: Detail columns

  • WHEN list data is loaded
  • THEN each row SHALL include date, workcenter group, workcenter, product dimensions, reason/category, MOVEIN_QTY, REJECT_TOTAL_QTY, DEFECT_QTY, and component reject columns

Scenario: Pagination behavior

  • WHEN total records exceed per-page size
  • THEN Prev/Next and page summary SHALL be shown
  • THEN changing any filter SHALL reset page to 1

Requirement: Reject History page SHALL support CSV export from current filter context

The page SHALL allow users to export records using the exact active filters.

Scenario: Export with all active filters

  • WHEN user clicks "匯出 CSV"
  • THEN export request SHALL include current primary filters, supplementary filters, trend-date filters, metric filters, and Pareto-selected items
  • THEN downloaded file SHALL contain exactly the same rows currently represented by the detail list filter context

Scenario: Export remains UTF-8 Excel compatible

  • WHEN CSV export is downloaded
  • THEN the file SHALL be encoded in UTF-8 with BOM
  • THEN Chinese headers and values SHALL render correctly in common spreadsheet tools

Requirement: Reject History page SHALL provide robust feedback states

The page SHALL provide loading, empty, and error states without breaking interactions.

Scenario: Initial loading

  • WHEN first query is running
  • THEN a loading overlay or skeleton SHALL be visible until required data sections are ready

Scenario: API failure

  • WHEN any section API fails
  • THEN a visible error banner SHALL be shown
  • THEN already loaded sections SHALL remain interactive

Scenario: Empty dataset

  • WHEN query returns no rows
  • THEN chart and table areas SHALL show explicit empty-state messages

Requirement: Reject History page SHALL maintain responsive visual hierarchy

The page SHALL keep the same semantic grouping across desktop and mobile layouts.

Scenario: Desktop layout

  • WHEN viewport is desktop width
  • THEN KPI cards SHALL render in multi-column layout
  • THEN trend and pareto sections SHALL render as two-column analytical panels

Scenario: Mobile layout

  • WHEN viewport width is below responsive breakpoint
  • THEN cards and chart panels SHALL stack in a single column
  • THEN filter controls SHALL remain operable without horizontal overflow

Requirement: Reject History page SHALL display a loading overlay during initial data load

The page SHALL show a full-screen loading overlay with spinner during the first data load to provide clear feedback.

Scenario: Loading overlay on initial mount

  • WHEN the page first mounts and loadAllData begins
  • THEN a loading overlay with spinner SHALL be displayed over the page content
  • WHEN all initial API responses complete
  • THEN the overlay SHALL be hidden

Scenario: Subsequent queries do not show overlay

  • WHEN the user triggers a re-query after initial load
  • THEN no full-screen overlay SHALL appear (inline loading states are sufficient)

Requirement: Detail table rows SHALL highlight on hover

The detail table and pareto table rows SHALL visually respond to mouse hover for improved readability.

Scenario: Row hover in detail table

  • WHEN user hovers over a row in the detail table
  • THEN the row background SHALL change to a subtle highlight color

Scenario: Row hover in pareto table

  • WHEN user hovers over a row in the pareto summary table
  • THEN the row background SHALL change to a subtle highlight color

Requirement: Pagination controls SHALL use Chinese labels

The detail list pagination SHALL display controls in Chinese to match the rest of the page language.

Scenario: Pagination button labels

  • WHEN the pagination controls are rendered
  • THEN the previous-page button SHALL display "上一頁"
  • THEN the next-page button SHALL display "下一頁"
  • THEN the page info text SHALL use Chinese formatting (e.g., "第 1 / 5 頁 · 共 250 筆")

Requirement: Reject History page SHALL be structured as modular sub-components

The page template SHALL delegate sections to focused sub-components, following the hold-history architecture pattern.

Scenario: Component decomposition

  • WHEN the page source is examined
  • THEN the filter panel SHALL be a separate FilterPanel.vue component
  • THEN the KPI summary cards SHALL be a separate SummaryCards.vue component
  • THEN the trend chart SHALL be a separate TrendChart.vue component
  • THEN the pareto section (chart + table) SHALL be a separate ParetoSection.vue component
  • THEN the detail table with pagination SHALL be a separate DetailTable.vue component

Scenario: App.vue acts as orchestrator

  • WHEN the page runs
  • THEN App.vue SHALL hold all reactive state and API logic
  • THEN sub-components SHALL receive data via props and communicate via events

Requirement: Frontend API timeout

The reject-history page SHALL use a 360-second API timeout (up from 60 seconds) for all Oracle-backed API calls.

Scenario: Large date range query completes

  • WHEN a user queries reject history for a long date range
  • THEN the frontend does not abort the request for at least 360 seconds