Files
DashBoard/openspec/specs/query-tool-lot-trace/spec.md
egg 5b358d71c1 feat(query-tool): rewrite frontend with ECharts tree, multi-select, and modular composables
Replace the monolithic useQueryToolData composable and nested Vue component tree
with a modular architecture: useLotResolve, useLotLineage, useLotDetail, and
useEquipmentQuery. Introduce ECharts TreeChart (LR orthogonal layout) for lot
lineage visualization with multi-select support, subtree expansion, zoom/pan,
and serial number normalization. Add unified LineageEngine backend with split
descendant traversal and leaf serial number queries. Archive the query-tool-rewrite
openspec change and sync delta specs to main.

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

8.0 KiB

ADDED Requirements

Requirement: Query-tool page SHALL use tab-based layout separating LOT tracing from equipment queries

The query-tool page SHALL present two top-level tabs: "LOT 追蹤" and "設備查詢", each with independent state and UI.

Scenario: Tab switching preserves state

  • WHEN the user switches from LOT tab to Equipment tab and back
  • THEN the LOT tab SHALL retain its resolved lots, lineage tree state, and selected lot detail
  • THEN the Equipment tab SHALL retain its query results independently

Scenario: URL state reflects active tab

  • WHEN the user is on a specific tab
  • THEN the URL SHALL include a tab parameter (e.g., ?tab=lot or ?tab=equipment)
  • THEN reloading the page SHALL restore the active tab

Requirement: QueryBar SHALL resolve LOT/Serial/WorkOrder inputs

The query bar SHALL accept multi-value input (newline or comma-separated) with input type selection and resolve via POST /api/query-tool/resolve.

Scenario: Successful LOT resolution

  • WHEN the user enters lot IDs and clicks resolve
  • THEN the system SHALL call POST /api/query-tool/resolve with input_type and values
  • THEN resolved lots SHALL appear as root nodes in the lineage tree
  • THEN not-found values SHALL be displayed as warnings below the tree

Scenario: Work order expansion

  • WHEN the user enters work order IDs (max 10)
  • THEN each work order MAY expand to 100+ lots
  • THEN all expanded lots SHALL appear as root nodes in the lineage tree

Scenario: Input validation

  • WHEN the user submits empty input or exceeds limits (50 lot IDs, 50 serial numbers, 10 work orders)
  • THEN the system SHALL display a validation error without making an API call

Requirement: LineageTree SHALL display as a decomposition tree with progressive growth animation

After resolve completes, the lineage tree SHALL auto-fire lineage API calls for each resolved lot with concurrency control, rendering an animated tree that grows as results arrive.

Scenario: Auto-fire lineage after resolve

  • WHEN lot resolution completes with N resolved lots
  • THEN the system SHALL automatically call POST /api/trace/lineage for each lot
  • THEN concurrent lineage requests SHALL be limited to 3 at a time
  • THEN the lineage tree SHALL render root nodes immediately (resolved lots)

Scenario: Progressive tree growth animation

  • WHEN a lineage API response returns for a lot
  • THEN ancestor nodes SHALL animate into the tree (slide-in + fade, staggered 30-50ms per sibling)
  • THEN the animation SHALL give the visual impression of a tree "growing" its branches

Scenario: Tree node expand/collapse

  • WHEN the user clicks a tree node with children (ancestors)
  • THEN children SHALL toggle between expanded and collapsed state
  • THEN expand/collapse SHALL be a client-side operation (no additional API call)

Scenario: Expand-all and collapse-all

  • WHEN the user clicks "全部展開"
  • THEN all tree nodes at all levels SHALL expand with staggered animation
  • WHEN the user clicks "收合"
  • THEN all tree nodes SHALL collapse to show only root nodes

Scenario: Merge relationships visually distinct

  • WHEN the lineage data includes merge relationships
  • THEN merge nodes SHALL display a distinct icon and/or color to differentiate from direct ancestor relationships

Scenario: Leaf nodes without expand affordance

  • WHEN a tree node has no ancestors (leaf/terminal node)
  • THEN it SHALL NOT display an expand button or clickable expand area

Scenario: Lineage cache prevents duplicate fetches

  • WHEN lineage data has already been fetched for a lot
  • THEN subsequent interactions SHALL use cached data without re-fetching
  • WHEN a new resolve query is executed
  • THEN the lineage cache SHALL be cleared

Requirement: Left-right master-detail layout SHALL show tree and LOT detail side by side

The LOT tracing tab SHALL use a left-right split layout with the lineage tree on the left and LOT detail on the right.

Scenario: LOT selection from tree

  • WHEN the user clicks any node in the lineage tree (root lot or ancestor)
  • THEN the right panel SHALL load detail for that node's container ID
  • THEN the selected node SHALL be visually highlighted in the tree

Scenario: Right panel sub-tabs

  • WHEN a LOT is selected
  • THEN the right panel SHALL display sub-tabs: 歷程 (History), 物料 (Materials), 退貨 (Rejects), Hold, Split, Job
  • THEN each sub-tab SHALL load data on-demand when activated (not pre-fetched)

Scenario: Responsive behavior

  • WHEN the viewport width is below 1024px
  • THEN the layout SHALL stack vertically (tree above, detail below)

Requirement: LOT History sub-tab SHALL display production history with workcenter filter

The History sub-tab SHALL show production history data from GET /api/query-tool/lot-history with workcenter group filtering.

Scenario: History table display

  • WHEN the user selects the History sub-tab for a LOT
  • THEN the system SHALL call GET /api/query-tool/lot-history?container_id=X
  • THEN results SHALL display in a table with sticky headers and horizontal scroll

Scenario: Workcenter group filter

  • WHEN the user selects workcenter groups from the filter dropdown
  • THEN the history query SHALL include the selected groups as filter parameters
  • THEN the history table SHALL refresh with filtered results

Requirement: LOT Production Timeline SHALL visualize station progression over time

The History sub-tab SHALL include a timeline visualization showing the lot's journey through production stations.

Scenario: Timeline rendering

  • WHEN lot history data is loaded
  • THEN a horizontal Gantt-style timeline SHALL render with time on the X-axis
  • THEN each workcenter/station SHALL appear as a track with a colored bar from track-in to track-out time

Scenario: Workcenter filter affects timeline

  • WHEN the user filters by workcenter groups
  • THEN the timeline SHALL show only stations matching the selected groups
  • THEN filtered-out stations SHALL be hidden (not grayed out)

Scenario: Timeline event markers

  • WHEN hold events or material consumption events exist within the timeline range
  • THEN they SHALL be displayed as markers on the timeline with tooltip details on hover

Requirement: LOT Association sub-tabs SHALL load data on-demand

Each association sub-tab (Materials, Rejects, Holds, Splits, Jobs) SHALL fetch data independently when activated.

Scenario: Association data loading

  • WHEN the user activates a sub-tab (e.g., Materials)
  • THEN the system SHALL call GET /api/query-tool/lot-associations?container_id=X&type=materials
  • THEN results SHALL display in a table with dynamic columns

Scenario: Sub-tab data caching within session

  • WHEN the user switches between sub-tabs for the same LOT
  • THEN previously loaded sub-tab data SHALL be preserved (not re-fetched)
  • WHEN the user selects a different LOT
  • THEN all sub-tab caches SHALL be cleared

Requirement: Each sub-tab SHALL support independent CSV export

Every detail sub-tab SHALL have its own export button.

Scenario: Per-tab export

  • WHEN the user clicks export on the Materials sub-tab
  • THEN the system SHALL call POST /api/query-tool/export-csv with export_type: "lot_materials" and the current container_id
  • THEN a CSV file SHALL download with the appropriate filename

Scenario: Export disabled when no data

  • WHEN a sub-tab has no data loaded or the data is empty
  • THEN the export button SHALL be disabled

Requirement: Legacy dead code SHALL be removed

The legacy frontend/src/query-tool/main.js (448L vanilla JS) and frontend/src/query-tool/style.css SHALL be deleted.

Scenario: Dead code removal

  • WHEN the rewrite is complete
  • THEN frontend/src/query-tool/main.js SHALL contain only the Vite entry point (createApp + mount)
  • THEN frontend/src/query-tool/style.css SHALL be deleted (all styling via Tailwind)