Files
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

1.7 KiB

MODIFIED Requirements

Requirement: EventFetcher SHALL provide unified cached event querying across domains

EventFetcher SHALL encapsulate batch event queries with L1/L2 layered cache and rate limit bucket configuration, supporting domains: history, materials, rejects, holds, jobs, upstream_history, downstream_rejects.

Scenario: Cache miss for event domain query

  • WHEN EventFetcher is called for a domain with container IDs and no cache exists
  • THEN the domain query SHALL execute against Oracle via read_sql_df()
  • THEN the result SHALL be stored in L2 Redis cache with key format evt:{domain}:{sorted_cids_hash}
  • THEN L1 memory cache SHALL also be populated (aligned with core/cache.py LayeredCache pattern)

Scenario: Cache hit for event domain query

  • WHEN EventFetcher is called for a domain and L2 Redis cache contains a valid entry
  • THEN the cached result SHALL be returned without executing Oracle query
  • THEN DB connection pool SHALL NOT be consumed

Scenario: Rate limit bucket per domain

  • WHEN EventFetcher is used from a route handler
  • THEN each domain SHALL have a configurable rate limit bucket aligned with configured_rate_limit() pattern
  • THEN rate limit configuration SHALL be overridable via environment variables

Scenario: downstream_rejects domain query

  • WHEN EventFetcher is called with domain downstream_rejects
  • THEN it SHALL load mid_section_defect/downstream_rejects.sql via SQLLoader.load_with_params() with DESCENDANT_FILTER set to the batched IN clause condition
  • THEN the query SHALL return reject records with WORKCENTER_GROUP classification