Files
DashBoard/openspec/changes/archive/2026-02-24-full-line-defect-trace/design.md
egg f14591c7dc feat(mid-section-defect): full-line bidirectional defect trace center with dual query mode
Transform /mid-section-defect from TMTT-only backward analysis into a full-line
bidirectional defect traceability center supporting all detection stations.

Key changes:
- Parameterized station detection: any workcenter group as detection station
- Bidirectional tracing: backward (upstream attribution) + forward (downstream reject rates)
- Dual query mode: date range OR LOT/工單/WAFER container-based seed resolution
- Multi-select filters for upstream station, equipment model (RESOURCEFAMILYNAME), and loss reasons
- Progressive 3-stage trace pipeline (seed-resolve → lineage → events) with streaming UI
- Equipment model lookup via resource cache instead of SPECNAME
- Session caching, auto-refresh, searchable MultiSelect with fuzzy matching
- Remove legacy tmtt-defect module (fully superseded)
- Archive openspec change artifacts

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

5.2 KiB
Raw Blame History

Context

/mid-section-defect currently runs a 3-stage backward-only pipeline hardcoded to TMTT (測試) station:

  1. tmtt_detection.sql — fetch defective lots at TMTT station
  2. LineageEngine.resolve_full_genealogy() — find ancestor container IDs
  3. upstream_history.sql — get WIP records at upstream stations → attribute defects to machines

The detection SQL has LIKE '%TMTT%' hardcoded on line 38. All internal naming uses TMTT_ prefix. The page serves one direction (backward) for one station.

This change generalizes to any of the 12 workcenter groups as detection station, adds forward tracing direction, and removes the superseded /tmtt-defect page.

Goals / Non-Goals

Goals:

  • Parameterize detection station: replace TMTT hardcode with {{ STATION_FILTER }} built from workcenter_groups.py patterns
  • Add forward tracing pipeline: detection rejects → forward lineage → downstream WIP + rejects → forward attribution
  • Direction-aware UI: FilterBar station dropdown + direction toggle, KPI/charts/detail switch by direction
  • Backward compatibility: station=測試, direction=backward produces identical results (renamed columns)
  • Remove /tmtt-defect page and all associated code

Non-Goals:

  • No changes to LineageEngine internals (already supports both resolve_full_genealogy and resolve_forward_tree)
  • No changes to reject-history or query-tool pages
  • No new caching strategy (reuse existing L1/L2 cache with station+direction in key)
  • No multi-station or multi-direction in a single query

Decisions

D1: Parameterized SQL via template substitution (not dynamic SQL builder)

Use SQLLoader.load_with_params() with {{ STATION_FILTER }} placeholder — the same pattern already used by upstream_history.sql's {{ ANCESTOR_FILTER }}. The filter is built in Python from WORKCENTER_GROUPS[station]['patterns'] as OR-LIKE clauses with bind parameters.

Alternative considered: Dynamic SQL builder class. Rejected — adds abstraction for a simple OR-LIKE pattern; template substitution is established in the codebase.

D2: Separate station_detection.sql instead of modifying tmtt_detection.sql

Create new station_detection.sql as a generalized copy. The old tmtt_detection.sql will be deleted when /tmtt-defect is removed. Clean separation avoids merge conflicts with any in-flight tmtt-defect work.

Alternative considered: Modify in-place. Rejected — the old file is deleted anyway and renaming avoids ambiguity.

D3: Forward attribution uses TRACKINQTY as denominator

Forward reject rate = REJECT_TOTAL_QTY / TRACKINQTY × 100 at each downstream station. TRACKINQTY comes from upstream_history.sql (needs adding to SELECT). This gives a per-station defect rate for lots that survived the detection station.

Alternative considered: Use lot count as denominator. Rejected — TRACKINQTY accounts for partial quantities (split/merge lots) and gives a more accurate rate.

D4: Direction dispatch at service layer, not route layer

query_analysis() gains station and direction params and dispatches to _run_backward_pipeline() or _run_forward_pipeline() internally. Routes just pass through. This keeps route handlers thin and testable.

D5: Forward pipeline reuses upstream_history.sql for WIP records

Both directions need WIP records at various stations. The existing upstream_history.sql (with added TRACKINQTY) serves both — just with different container ID sets (ancestors for backward, descendants for forward).

D6: New downstream_rejects event domain in EventFetcher

Forward tracing needs reject records at downstream stations. Add downstream_rejects as a new domain in EventFetcher._build_domain_sql(), loading downstream_rejects.sql with batched IN clause. This follows the established domain pattern.

D7: Frontend direction toggle — button group, not dropdown

Two discrete states (backward/forward) fit a toggle button group better than a dropdown. Matches the existing btn-primary pattern in the page's CSS.

D8: Remove /tmtt-defect entirely

The generalized traceability center with station=測試 + lossReasons=[276_腳型不良, 277_印字不良] reproduces all tmtt-defect functionality. Remove: frontend/src/tmtt-defect/, backend routes/services/SQL, test files, and nativeModuleRegistry.js registration.

Risks / Trade-offs

  • Forward pipeline performance for early stations — Selecting station=切割 (order=0), direction=forward could produce a very large descendant tree (all lots flow downstream). → Mitigation: The existing resolve_forward_tree() already handles large sets; add a result count warning in UI if > 5000 tracked lots.

  • TRACKINQTY NULL values — Some WIP records may have NULL TRACKINQTY. → Mitigation: COALESCE to 0 in SQL; skip lots with zero input in attribution to avoid division by zero.

  • TMTT removal breaks bookmarks — Users with /tmtt-defect bookmarks get 404. → Mitigation: Low risk — page was in dev status, not released. No redirect needed.

  • Rename TMTT_ → DETECTION_ in API response keys — Frontend consumers (CSV export, chart keys) reference these field names. → Mitigation: All consumers are within this page's code; rename consistently in one pass.