Files
DashBoard/openspec/specs/wip-overview-page/spec.md
egg a2653b8139 feat(wip): migrate WIP trio pages from Jinja2 to Vue 3 + Vite
Migrate /wip-overview, /wip-detail, and /hold-detail (1,941 lines vanilla JS)
to Vue 3 SFC architecture. Extract shared CSS/constants/components to
wip-shared/. Switch Pareto charts to vue-echarts with autoresize. Replace
Jinja2 template injection with frontend URL params + constant classification
for Hold Detail. Add 10-min auto-refresh + AbortController to Hold Detail.
Remove three Jinja2 templates, update Flask routes to send_from_directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 16:39:20 +08:00

5.3 KiB
Raw Blame History

Purpose

Define stable requirements for wip-overview-page.

Requirements

Requirement: Overview page SHALL display WIP summary statistics

The page SHALL fetch and display total lot count and total quantity as summary cards.

Scenario: Summary cards rendering

  • WHEN the page loads
  • THEN the page SHALL call GET /api/wip/overview/summary
  • THEN summary cards SHALL display Total Lots and Total QTY with zh-TW number formatting
  • THEN values SHALL animate with a scale transition when updated

Scenario: Data update timestamp

  • WHEN summary data is loaded
  • THEN the header SHALL display the dataUpdateDate from the API response

Requirement: Overview page SHALL display WIP status breakdown cards

The page SHALL display four clickable status cards (RUN, QUEUE, 品質異常, 非品質異常) with lot and quantity counts.

Scenario: Status cards rendering

  • WHEN summary data is loaded
  • THEN four status cards SHALL be displayed with color coding (green=RUN, yellow=QUEUE, red=品質異常, orange=非品質異常)
  • THEN each card SHALL show lot count and quantity

Scenario: Status card click filters matrix

  • WHEN user clicks a status card
  • THEN the matrix table SHALL reload with the selected status filter
  • THEN the clicked card SHALL show an active visual state
  • THEN non-active cards SHALL dim to 50% opacity
  • THEN clicking the same card again SHALL deactivate the filter and restore all cards

Requirement: Overview page SHALL display Workcenter × Package matrix

The page SHALL display a cross-tabulation table of workcenters vs packages.

Scenario: Matrix table rendering

  • WHEN matrix data is loaded from GET /api/wip/overview/matrix
  • THEN the table SHALL display workcenters as rows and packages as columns (limited to top 15)
  • THEN the first column (Workcenter) SHALL be sticky on horizontal scroll
  • THEN a Total row and Total column SHALL be displayed

Scenario: Matrix workcenter drill-down

  • WHEN user clicks a workcenter name in the matrix
  • THEN the page SHALL navigate to /wip-detail?workcenter={name}
  • THEN active filter values (workorder, lotid, package, type) SHALL be passed as URL parameters

Requirement: Overview page SHALL display Hold Pareto analysis

The page SHALL display Pareto charts and tables for quality and non-quality hold reasons.

Scenario: Pareto chart rendering

  • WHEN hold data is loaded from GET /api/wip/overview/hold
  • THEN hold items SHALL be split into quality and non-quality groups
  • THEN each group SHALL display an ECharts dual-axis Pareto chart (bar=QTY, line=cumulative %)
  • THEN items SHALL be sorted by QTY descending

Scenario: Pareto chart drill-down

  • WHEN user clicks a bar in the Pareto chart
  • THEN the page SHALL navigate to /hold-detail?reason={reason}
  • WHEN Pareto data is rendered
  • THEN a table SHALL display below each chart with Hold Reason, Lots, QTY, and cumulative %
  • THEN reason names SHALL be clickable links to /hold-detail?reason={reason}

Scenario: Empty hold data

  • WHEN a hold type has no items
  • THEN the chart area SHALL display a "目前無資料" message
  • THEN the chart SHALL be cleared

Requirement: Overview page SHALL support autocomplete filtering

The page SHALL provide autocomplete-enabled filter inputs for WORKORDER, LOT ID, PACKAGE, and TYPE.

  • WHEN user types 2+ characters in a filter input
  • THEN the page SHALL call GET /api/wip/meta/search with debounce (300ms)
  • THEN suggestions SHALL appear in a dropdown below the input
  • THEN cross-filter parameters SHALL be included (other active filter values)

Scenario: Apply and clear filters

  • WHEN user clicks "套用篩選" or presses Enter in a filter input
  • THEN all three API calls (summary, matrix, hold) SHALL reload with the filter values
  • WHEN user clicks "清除篩選"
  • THEN all filter inputs SHALL be cleared and data SHALL reload without filters

Scenario: Active filter display

  • WHEN filters are applied
  • THEN active filters SHALL be displayed as removable tags (e.g., "WO: {value} ×")
  • THEN clicking a tag's remove button SHALL clear that filter and reload data

Requirement: Overview page SHALL auto-refresh and handle request cancellation

The page SHALL automatically refresh data and prevent stale request pile-up.

Scenario: Auto-refresh interval

  • WHEN the page is loaded
  • THEN data SHALL auto-refresh every 10 minutes
  • THEN auto-refresh SHALL be skipped when the tab is hidden (document.hidden)

Scenario: Visibility change refresh

  • WHEN the tab becomes visible after being hidden
  • THEN data SHALL refresh immediately

Scenario: Request cancellation

  • WHEN a new data load is triggered while a previous request is in-flight
  • THEN the previous request SHALL be cancelled via AbortController
  • THEN the cancelled request SHALL NOT update the UI

Scenario: Manual refresh

  • WHEN user clicks the "重新整理" button
  • THEN data SHALL reload and the auto-refresh timer SHALL reset