feat: archive filter strategy change and optimize reject-history filters
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-22
|
||||
@@ -0,0 +1,106 @@
|
||||
## Context
|
||||
|
||||
目前 released 報表頁面的篩選模型混用三種模式:
|
||||
1. 後端動態 options 互篩(`wip-overview` / `wip-detail`)
|
||||
2. 前端用已載入 options 做部分收斂(`resource-history`)
|
||||
3. 查詢驅動或鑽取驅動(`reject-history`、`hold-*` 等)
|
||||
|
||||
這種混用在「探索型」報表(使用者要快速找到可分析的有效組合)會造成明顯成本:
|
||||
- 下拉選單可選但查詢無資料
|
||||
- 上游條件變更後,下游已選值失效但仍保留
|
||||
- 使用者對不同頁面的篩選預期不一致
|
||||
|
||||
本提案聚焦補強兩個探索型頁面:
|
||||
- `reject-history`
|
||||
- `resource-history`
|
||||
|
||||
並建立跨報表可重用的篩選策略基線。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 定義「探索型 vs 監控/鑽取型」頁面的篩選策略分級與適用準則。
|
||||
- 讓 `reject-history` 支援草稿條件驅動的 options 互相收斂,減少無效篩選組合。
|
||||
- 讓 `resource-history` 從部分聯動提升為一致聯動(上游變更時,自動 prune 失效選取值)。
|
||||
- 統一互篩技術細節:debounce、請求去重/過期回應保護、無效值剔除、apply/clear 語意一致。
|
||||
|
||||
**Non-Goals:**
|
||||
- 不在本次將所有 released 頁面全面改為互相篩選。
|
||||
- 不改變報表核心計算邏輯(KPI、統計口徑、圖表定義)。
|
||||
- 不引入新基礎設施(例如 Redis 新部署)作為互篩前置條件。
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: 採用「頁面類型分級」而非全站一刀切
|
||||
- 決策:
|
||||
- 探索型頁面:要求完整互篩(options 受目前草稿條件影響,且自動 prune 失效值)。
|
||||
- 監控/鑽取型頁面:允許維持輕量篩選 + drilldown,不強制完整互篩。
|
||||
- 理由:
|
||||
- 探索型頁面的主要任務是「找可分析組合」,互篩是核心可用性功能。
|
||||
- 監控/鑽取型頁面追求即時性與低操作成本,完整互篩的收益較低。
|
||||
- 替代方案:
|
||||
- 全頁面統一完整互篩:一致性高,但開發與維護成本過高,且對監控頁面價值有限。
|
||||
|
||||
### Decision 2: `reject-history` 採 server-side options 互篩
|
||||
- 決策:
|
||||
- 以 options API 接收草稿條件(時間、workcenter group、package、reason、政策旗標)回傳收斂後候選值。
|
||||
- 前端在草稿變更時 debounce 觸發 options reload;apply 時再執行主查詢。
|
||||
- 理由:
|
||||
- `reject-history` 篩選受政策旗標影響,僅靠前端靜態 options 無法正確反映後端過濾語意。
|
||||
- 替代方案:
|
||||
- 前端本地收斂:無法覆蓋政策條件與後端口徑,容易與實際查詢結果不一致。
|
||||
|
||||
### Decision 3: `resource-history` 維持前端收斂為主,但補齊一致 prune
|
||||
- 決策:
|
||||
- 仍使用已載入 options/resources 作前端收斂,避免每次草稿變更打後端。
|
||||
- 補上 family/machine 與上游條件(群組、flags)一致收斂與失效值自動清理。
|
||||
- 理由:
|
||||
- `resource-history` 現有資料結構已適合前端計算選項,性能與實作成本較平衡。
|
||||
- 替代方案:
|
||||
- 改成全 server-side options:一致性高,但請求頻率與後端負載上升,且未必有必要。
|
||||
|
||||
### Decision 4: 建立可重用互篩行為基線
|
||||
- 決策:
|
||||
- 統一以下行為:
|
||||
- debounce options reload
|
||||
- request token / stale response guard
|
||||
- upstream 變更觸發 downstream prune
|
||||
- clear 時重置至預設並同步 URL
|
||||
- 理由:
|
||||
- 降低跨頁面行為偏差,後續新頁面可直接套用。
|
||||
- 替代方案:
|
||||
- 每頁自行實作:短期快,但長期易分歧與回歸。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] `reject-history` options API 參數變多,查詢複雜度上升
|
||||
→ Mitigation: 使用現有快取索引與必要欄位投影,限制 options 查詢計算範圍。
|
||||
|
||||
- [Risk] 草稿變更觸發 options reload,造成頻繁請求
|
||||
→ Mitigation: debounce + 過期回應丟棄 + 僅在可影響 options 的欄位變更時重載。
|
||||
|
||||
- [Risk] prune 行為可能讓使用者感覺「選項被系統吃掉」
|
||||
→ Mitigation: UI 顯示明確提示(例如選項已失效並自動清除),且 apply/clear 行為一致。
|
||||
|
||||
- [Risk] 互篩策略擴大後,頁面之間仍可能有例外需求
|
||||
→ Mitigation: 先以「頁面分級」定義允許差異的範圍,避免假一致性。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 先提交 spec-level 規範(策略基線 + 兩頁行為變更)。
|
||||
2. `reject-history`:擴充 options API 參數與服務層收斂邏輯,前端接入草稿互篩。
|
||||
3. `resource-history`:補齊前端收斂與 prune 規則,對齊 apply/query 流程。
|
||||
4. 補 route/service/frontend 測試,確認:
|
||||
- options 會隨草稿條件收斂
|
||||
- upstream 變更會清理失效下游值
|
||||
- apply/clear 行為不回歸
|
||||
5. 以 feature flag(若需要)做灰度,確認查詢效能後再全面開啟。
|
||||
|
||||
Rollback:
|
||||
- 後端保留原 options 路徑/參數相容;前端可切回「僅 apply 查詢,不做草稿互篩」模式。
|
||||
|
||||
## Open Questions
|
||||
|
||||
- `reject-history` 的 reason 下拉是否要改為 multi-select(目前設計維持單選)?
|
||||
- `resource-history` 是否需要將 family options 也改為完全 server-side 來源以統一模式?
|
||||
- prune 提示文案是否需要全站共用元件(避免各頁文案不一致)?
|
||||
@@ -0,0 +1,65 @@
|
||||
# Implementation Notes
|
||||
|
||||
## 1) Page classification (exploratory baseline)
|
||||
|
||||
- `reject-history`: exploratory
|
||||
- Requires draft-driven options narrowing for `WORKCENTER_GROUP` / `Package` / `原因`
|
||||
- Requires stale-response protection + invalid-value auto-prune before apply/export
|
||||
- `resource-history`: exploratory
|
||||
- Requires upstream-to-downstream narrowing (`群組/旗標 -> 型號 -> 機台`)
|
||||
- Requires family/machine auto-prune and committed query execution model
|
||||
|
||||
## 2) Frontend responsibilities mapping
|
||||
|
||||
- `frontend/src/reject-history/App.vue`
|
||||
- Holds **draft filters** (`draftFilters`) for options narrowing
|
||||
- Holds **committed filters** (`committedFilters`) for summary/trend/pareto/list/export
|
||||
- Performs debounced options reload and stale response discard
|
||||
- Prunes invalid draft values and applies non-blocking prune hint
|
||||
- `frontend/src/resource-history/App.vue`
|
||||
- Holds draft/committed filter split and URL sync on committed only
|
||||
- Derives family/machine options from loaded resource metadata before first query
|
||||
- Prunes invalid family/machine values on upstream changes
|
||||
- Uses apply/clear semantics with deterministic reset
|
||||
- Shared helper modules for deterministic unit-test coverage:
|
||||
- `frontend/src/core/reject-history-filters.js`
|
||||
- `frontend/src/core/resource-history-filters.js`
|
||||
|
||||
## 3) Debounce & request-guard conventions
|
||||
|
||||
- `reject-history` draft options debounce: `300ms`
|
||||
- Constant: `OPTIONS_DEBOUNCE_MS = 300`
|
||||
- stale-response guard: monotonic request token (`activeOptionsRequestId`)
|
||||
- `reject-history` data queries and list updates
|
||||
- stale-response guard: monotonic request token (`activeDataRequestId`)
|
||||
- `resource-history`
|
||||
- Uses local computed narrowing/prune (no per-change options API call), so no options debounce required
|
||||
- Query execution remains explicit on apply/clear
|
||||
|
||||
## 4) Manual verification checklist (2026-02-22)
|
||||
|
||||
- [x] Reject-history: changing draft `WORKCENTER_GROUP` narrows `Package/原因` options
|
||||
- [x] Reject-history: changing policy toggles narrows options and keeps list/analytics policy alignment
|
||||
- [x] Reject-history: invalid selected values auto-prune and show non-blocking hint
|
||||
- [x] Reject-history: apply/export only use committed valid filters
|
||||
- [x] Resource-history: first load provides usable family/machine candidates before first query
|
||||
- [x] Resource-history: upstream (`群組/設備旗標`) changes prune invalid `型號/機台`
|
||||
- [x] Resource-history: query + URL sync use committed filters only
|
||||
- [x] Resource-history: clear resets deterministic defaults and reloads data
|
||||
|
||||
## 5) Monitoring/drilldown non-goal guard
|
||||
|
||||
- No filter strategy rollout changes were applied to monitoring/drilldown page code paths in this change.
|
||||
- Scope verification: file modifications are limited to reject-history/resource-history flows, related SQL/routes/services, tests, and change artifacts.
|
||||
|
||||
## 6) Release note entry (draft)
|
||||
|
||||
- Title: `Exploratory filter strategy hardening for Reject History and Resource History`
|
||||
- Scope:
|
||||
- Added interdependent draft option narrowing and invalid-selection pruning on `reject-history`
|
||||
- Strengthened upstream-driven family/machine narrowing and prune behavior on `resource-history`
|
||||
- Unified apply/clear semantics and non-blocking prune feedback on both exploratory pages
|
||||
- Non-goals:
|
||||
- No global rollout to all released reports
|
||||
- No KPI/business formula changes
|
||||
- No monitoring/drilldown filtering model migration in this release
|
||||
@@ -0,0 +1,41 @@
|
||||
## Why
|
||||
|
||||
目前已 release 的報表頁面中,篩選行為有明顯差異:有些頁面具備互相影響的動態選項,有些僅做查詢後過濾或單向收斂。這會造成使用者在跨報表分析時的操作落差與誤解,並增加「無結果查詢」與重複嘗試成本,因此需要補強並統一篩選策略。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 建立跨報表的篩選策略分級與適用準則,明確區分:
|
||||
- 探索型報表:需支援多欄位互相影響篩選
|
||||
- 監控/鑽取型報表:保留輕量篩選與 drilldown 為主
|
||||
- 針對探索型頁面補強互相篩選:
|
||||
- `reject-history`:選項 API 支援依目前草稿條件回傳受限選項,降低無效組合
|
||||
- `resource-history`:將現有 machine 單向收斂擴展為上游條件一致收斂並自動剔除失效選取值
|
||||
- 統一前端互篩行為細節:debounce、請求去重/過期保護、無效選取值 prune、apply/clear 一致語意
|
||||
- 補上互篩策略的驗證與回歸測試(前端互動與後端 option API 行為)
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `report-filter-strategy`: 定義報表篩選策略分級、互篩行為基線與一致性驗證規範
|
||||
|
||||
### Modified Capabilities
|
||||
- `reject-history-page`: 篩選選項改為可依草稿條件動態收斂,並維持既有政策旗標語意
|
||||
- `resource-history-page`: 篩選聯動由部分收斂提升為完整上游影響與失效值自動清理
|
||||
|
||||
## Impact
|
||||
|
||||
- **Frontend**
|
||||
- `frontend/src/reject-history/App.vue`
|
||||
- `frontend/src/reject-history/components/FilterPanel.vue`
|
||||
- `frontend/src/resource-history/App.vue`
|
||||
- `frontend/src/resource-history/components/FilterBar.vue`
|
||||
- 視需要新增 shared composable(互篩 option reload / prune)
|
||||
- **Backend**
|
||||
- `src/mes_dashboard/routes/reject_history_routes.py`
|
||||
- `src/mes_dashboard/services/reject_history_service.py`
|
||||
- 視需要新增/擴充 `resource-history` option API 參數解析與服務層
|
||||
- **Tests**
|
||||
- `tests/` 中 reject-history / resource-history 相關 route & service 測試
|
||||
- `frontend/tests/` 補互篩行為測試
|
||||
- **Non-goals**
|
||||
- 本次不要求所有 released 頁面全面改為完整互篩;僅先補強探索型頁面,監控/鑽取型頁面維持現有互動模型
|
||||
@@ -0,0 +1,36 @@
|
||||
## MODIFIED 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, and SHALL provide context-aware option narrowing for exploratory filtering.
|
||||
|
||||
#### 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: Draft filter options are interdependent
|
||||
- **WHEN** user changes draft values for `WORKCENTER_GROUP`, `package`, `reason`, or policy toggles
|
||||
- **THEN** option candidates for reason/workcenter-group/package SHALL reload under the current draft context
|
||||
- **THEN** unavailable combinations SHALL NOT remain in selectable options
|
||||
|
||||
#### Scenario: Policy toggles affect option scope
|
||||
- **WHEN** user changes policy toggles (including excluded-scrap and material-scrap switches)
|
||||
- **THEN** options and query results SHALL use the same policy mode
|
||||
- **THEN** option narrowing SHALL remain consistent with backend exclusion semantics
|
||||
|
||||
#### Scenario: Invalid selected values are pruned
|
||||
- **WHEN** narrowed options no longer contain previously selected values
|
||||
- **THEN** invalid selections SHALL be removed automatically before query commit
|
||||
- **THEN** apply/query SHALL only send valid selected values
|
||||
@@ -0,0 +1,54 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Report pages SHALL declare a filter strategy class
|
||||
Each released report page that exposes filter controls SHALL declare whether it is `exploratory` or `monitoring-drilldown` for filter behavior governance.
|
||||
|
||||
#### Scenario: Exploratory page classification
|
||||
- **WHEN** a page is classified as `exploratory`
|
||||
- **THEN** it SHALL implement interdependent filter options
|
||||
- **THEN** it SHALL prevent invalid cross-dimension combinations from remaining selectable
|
||||
|
||||
#### Scenario: Monitoring/drilldown page classification
|
||||
- **WHEN** a page is classified as `monitoring-drilldown`
|
||||
- **THEN** it MAY keep lightweight filters or chart-driven drilldown
|
||||
- **THEN** it SHALL document why full interdependent options are not required
|
||||
|
||||
### Requirement: Exploratory pages SHALL support draft-driven option narrowing
|
||||
Exploratory pages SHALL update filter option lists according to current draft selections before main query execution.
|
||||
|
||||
#### Scenario: Draft change triggers option reload
|
||||
- **WHEN** user changes any draft filter field that can affect other options
|
||||
- **THEN** the page SHALL debounce option reload requests
|
||||
- **THEN** options returned by the latest request SHALL replace prior candidates
|
||||
|
||||
#### Scenario: Stale option response protection
|
||||
- **WHEN** multiple option reload requests are in-flight
|
||||
- **THEN** only the newest request result SHALL be applied
|
||||
- **THEN** stale responses SHALL be discarded without mutating UI state
|
||||
|
||||
### Requirement: Exploratory pages SHALL prune invalid selected values
|
||||
Exploratory pages SHALL automatically remove selected values that are no longer valid under the latest upstream draft conditions.
|
||||
|
||||
#### Scenario: Upstream change invalidates downstream values
|
||||
- **WHEN** upstream filters change and previously selected downstream values are absent from narrowed options
|
||||
- **THEN** those invalid selected values SHALL be removed automatically
|
||||
- **THEN** the page SHALL keep remaining valid selections unchanged
|
||||
|
||||
#### Scenario: Apply query uses pruned committed filters
|
||||
- **WHEN** user clicks apply/query after pruning occurred
|
||||
- **THEN** the request SHALL use the current valid filter set only
|
||||
- **THEN** no removed invalid values SHALL be sent to API parameters
|
||||
|
||||
### Requirement: Exploratory pages SHALL keep apply and clear semantics consistent
|
||||
Exploratory pages SHALL separate draft option narrowing from committed query execution and provide deterministic clear behavior.
|
||||
|
||||
#### Scenario: Apply commits current filter state
|
||||
- **WHEN** user clicks apply/query
|
||||
- **THEN** all data sections SHALL reload using the same committed filter set
|
||||
- **THEN** URL state SHALL synchronize with committed filters only
|
||||
|
||||
#### Scenario: Clear resets to defaults
|
||||
- **WHEN** user clicks clear
|
||||
- **THEN** filters SHALL reset to documented defaults
|
||||
- **THEN** option candidates SHALL reload for the default state
|
||||
- **THEN** data sections SHALL reload from the default state
|
||||
@@ -0,0 +1,30 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Resource History page SHALL support multi-select filtering
|
||||
The page SHALL provide multi-select dropdown filters for workcenter groups and families, and SHALL support interdependent narrowing with machine options and selected-value pruning.
|
||||
|
||||
#### Scenario: Multi-select dropdown
|
||||
- **WHEN** user clicks a multi-select dropdown trigger
|
||||
- **THEN** a dropdown SHALL display with checkboxes for each option
|
||||
- **THEN** "Select All" and "Clear All" buttons SHALL be available
|
||||
- **THEN** clicking outside the dropdown SHALL close it
|
||||
|
||||
#### Scenario: Filter options loading
|
||||
- **WHEN** the page loads
|
||||
- **THEN** workcenter groups and families SHALL load from `GET /api/resource/history/options`
|
||||
- **THEN** machine candidates SHALL be derivable before first query from loaded option resources
|
||||
|
||||
#### Scenario: Upstream filters narrow downstream options
|
||||
- **WHEN** user changes upstream filters (`workcenterGroups`, `families`, equipment-type flags)
|
||||
- **THEN** machine options SHALL be recomputed to only include matching resources
|
||||
- **THEN** narrowed options SHALL be reflected immediately in filter controls
|
||||
|
||||
#### Scenario: Invalid selected machines are pruned
|
||||
- **WHEN** upstream filters change and selected machines are no longer valid
|
||||
- **THEN** invalid selected machine values SHALL be removed automatically
|
||||
- **THEN** remaining valid selected machine values SHALL be preserved
|
||||
|
||||
#### Scenario: Equipment type checkboxes
|
||||
- **WHEN** user toggles a checkbox (生產設備, 重點設備, 監控設備)
|
||||
- **THEN** the next query SHALL include the corresponding filter parameter
|
||||
- **THEN** option narrowing SHALL also honor the same checkbox conditions
|
||||
@@ -0,0 +1,38 @@
|
||||
## 1. Spec and strategy baseline alignment
|
||||
|
||||
- [x] 1.1 Confirm page classification for this change (`reject-history`=exploratory, `resource-history`=exploratory) and record in implementation notes
|
||||
- [x] 1.2 Verify filter behavior baseline (debounce, stale-response guard, prune, apply/clear semantics) is mapped to concrete frontend responsibilities
|
||||
|
||||
## 2. Reject History interdependent options hardening
|
||||
|
||||
- [x] 2.1 Extend reject-history options route to accept full draft filter context (date range, workcenter_groups, packages, reason, policy toggles)
|
||||
- [x] 2.2 Update reject-history service option query logic to return narrowed reason/workcenter/package candidates under the same policy semantics as list/analytics
|
||||
- [x] 2.3 Update reject-history frontend filter flow to reload options on draft-relevant changes with debounce and stale-response protection
|
||||
- [x] 2.4 Add invalid-selection pruning for reject-history filters after options reload (remove values no longer in candidate set)
|
||||
- [x] 2.5 Ensure apply/query and export requests only use committed valid filters
|
||||
|
||||
## 3. Resource History interdependent filtering hardening
|
||||
|
||||
- [x] 3.1 Refine resource-history option-derivation logic so upstream changes consistently narrow downstream machine options
|
||||
- [x] 3.2 Add/verify family and machine selection pruning when upstream filters or equipment-type flags invalidate selected values
|
||||
- [x] 3.3 Ensure resource-history query execution always uses the pruned committed filter set and preserves URL synchronization behavior
|
||||
- [x] 3.4 Verify first-load filter usability (options and machine candidates usable before first query)
|
||||
|
||||
## 4. Shared UX consistency and guardrails
|
||||
|
||||
- [x] 4.1 Normalize apply/clear semantics and naming within affected pages without altering existing report-specific business logic
|
||||
- [x] 4.2 Add consistent user feedback for auto-pruned selections (non-blocking hint/banner or equivalent)
|
||||
- [x] 4.3 Confirm debounce interval and request-token guard values are documented and consistent with project conventions
|
||||
|
||||
## 5. Tests and validation
|
||||
|
||||
- [x] 5.1 Add/adjust backend tests for reject-history options narrowing and policy-toggle consistency
|
||||
- [x] 5.2 Add/adjust frontend tests for interdependent option reload and prune behavior on reject-history/resource-history
|
||||
- [x] 5.3 Run targeted test set (backend route/service + frontend unit) and resolve regressions
|
||||
- [x] 5.4 Run frontend build validation and verify no behavior regressions on released pages outside this scope
|
||||
|
||||
## 6. Rollout and regression checks
|
||||
|
||||
- [x] 6.1 Perform manual verification checklist for exploratory use cases (cross-dimension narrowing, clear/apply, URL restore)
|
||||
- [x] 6.2 Verify monitoring/drilldown pages remain unchanged in behavior (no accidental full interdependent filtering rollout)
|
||||
- [x] 6.3 Prepare release note entry describing filter strategy hardening scope and non-goals
|
||||
@@ -4,7 +4,7 @@
|
||||
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.
|
||||
The page SHALL provide a filter area for date range and major production dimensions to drive all report sections, and SHALL provide context-aware option narrowing for exploratory filtering.
|
||||
|
||||
#### Scenario: Default filter values
|
||||
- **WHEN** the page is first loaded
|
||||
@@ -23,6 +23,21 @@ The page SHALL provide a filter area for date range and major production dimensi
|
||||
- **THEN** it SHALL include reason filter control
|
||||
- **THEN** it SHALL include `WORKCENTER_GROUP` filter control
|
||||
|
||||
#### Scenario: Draft filter options are interdependent
|
||||
- **WHEN** user changes draft values for `WORKCENTER_GROUP`, `package`, `reason`, or policy toggles
|
||||
- **THEN** option candidates for reason/workcenter-group/package SHALL reload under the current draft context
|
||||
- **THEN** unavailable combinations SHALL NOT remain in selectable options
|
||||
|
||||
#### Scenario: Policy toggles affect option scope
|
||||
- **WHEN** user changes policy toggles (including excluded-scrap and material-scrap switches)
|
||||
- **THEN** options and query results SHALL use the same policy mode
|
||||
- **THEN** option narrowing SHALL remain consistent with backend exclusion semantics
|
||||
|
||||
#### Scenario: Invalid selected values are pruned
|
||||
- **WHEN** narrowed options no longer contain previously selected values
|
||||
- **THEN** invalid selections SHALL be removed automatically before query commit
|
||||
- **THEN** apply/query SHALL only send valid selected values
|
||||
|
||||
### 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.
|
||||
|
||||
@@ -139,4 +154,3 @@ The page SHALL keep the same semantic grouping across desktop and mobile layouts
|
||||
- **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
|
||||
|
||||
|
||||
58
openspec/specs/report-filter-strategy/spec.md
Normal file
58
openspec/specs/report-filter-strategy/spec.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# report-filter-strategy Specification
|
||||
|
||||
## Purpose
|
||||
Define cross-report filter strategy governance, including exploratory-page interdependent filtering baselines.
|
||||
|
||||
## Requirements
|
||||
### Requirement: Report pages SHALL declare a filter strategy class
|
||||
Each released report page that exposes filter controls SHALL declare whether it is `exploratory` or `monitoring-drilldown` for filter behavior governance.
|
||||
|
||||
#### Scenario: Exploratory page classification
|
||||
- **WHEN** a page is classified as `exploratory`
|
||||
- **THEN** it SHALL implement interdependent filter options
|
||||
- **THEN** it SHALL prevent invalid cross-dimension combinations from remaining selectable
|
||||
|
||||
#### Scenario: Monitoring/drilldown page classification
|
||||
- **WHEN** a page is classified as `monitoring-drilldown`
|
||||
- **THEN** it MAY keep lightweight filters or chart-driven drilldown
|
||||
- **THEN** it SHALL document why full interdependent options are not required
|
||||
|
||||
### Requirement: Exploratory pages SHALL support draft-driven option narrowing
|
||||
Exploratory pages SHALL update filter option lists according to current draft selections before main query execution.
|
||||
|
||||
#### Scenario: Draft change triggers option reload
|
||||
- **WHEN** user changes any draft filter field that can affect other options
|
||||
- **THEN** the page SHALL debounce option reload requests
|
||||
- **THEN** options returned by the latest request SHALL replace prior candidates
|
||||
|
||||
#### Scenario: Stale option response protection
|
||||
- **WHEN** multiple option reload requests are in-flight
|
||||
- **THEN** only the newest request result SHALL be applied
|
||||
- **THEN** stale responses SHALL be discarded without mutating UI state
|
||||
|
||||
### Requirement: Exploratory pages SHALL prune invalid selected values
|
||||
Exploratory pages SHALL automatically remove selected values that are no longer valid under the latest upstream draft conditions.
|
||||
|
||||
#### Scenario: Upstream change invalidates downstream values
|
||||
- **WHEN** upstream filters change and previously selected downstream values are absent from narrowed options
|
||||
- **THEN** those invalid selected values SHALL be removed automatically
|
||||
- **THEN** the page SHALL keep remaining valid selections unchanged
|
||||
|
||||
#### Scenario: Apply query uses pruned committed filters
|
||||
- **WHEN** user clicks apply/query after pruning occurred
|
||||
- **THEN** the request SHALL use the current valid filter set only
|
||||
- **THEN** no removed invalid values SHALL be sent to API parameters
|
||||
|
||||
### Requirement: Exploratory pages SHALL keep apply and clear semantics consistent
|
||||
Exploratory pages SHALL separate draft option narrowing from committed query execution and provide deterministic clear behavior.
|
||||
|
||||
#### Scenario: Apply commits current filter state
|
||||
- **WHEN** user clicks apply/query
|
||||
- **THEN** all data sections SHALL reload using the same committed filter set
|
||||
- **THEN** URL state SHALL synchronize with committed filters only
|
||||
|
||||
#### Scenario: Clear resets to defaults
|
||||
- **WHEN** user clicks clear
|
||||
- **THEN** filters SHALL reset to documented defaults
|
||||
- **THEN** option candidates SHALL reload for the default state
|
||||
- **THEN** data sections SHALL reload from the default state
|
||||
@@ -84,8 +84,8 @@ The page SHALL allow users to specify time range and aggregation granularity.
|
||||
- **THEN** summary and detail APIs SHALL be called in parallel
|
||||
- **THEN** all 4 charts, KPI cards, and detail table SHALL update with results
|
||||
|
||||
### Requirement: Resource History page SHALL support multi-select filtering
|
||||
The page SHALL provide multi-select dropdown filters for workcenter groups and families.
|
||||
### Requirement: Resource History page SHALL support multi-select filtering
|
||||
The page SHALL provide multi-select dropdown filters for workcenter groups and families, and SHALL support interdependent narrowing with machine options and selected-value pruning.
|
||||
|
||||
#### Scenario: Multi-select dropdown
|
||||
- **WHEN** user clicks a multi-select dropdown trigger
|
||||
@@ -93,13 +93,25 @@ The page SHALL provide multi-select dropdown filters for workcenter groups and f
|
||||
- **THEN** "Select All" and "Clear All" buttons SHALL be available
|
||||
- **THEN** clicking outside the dropdown SHALL close it
|
||||
|
||||
#### Scenario: Filter options loading
|
||||
- **WHEN** the page loads
|
||||
- **THEN** workcenter groups and families SHALL load from `GET /api/resource/history/options`
|
||||
|
||||
#### Scenario: Equipment type checkboxes
|
||||
- **WHEN** user toggles a checkbox (生產設備, 重點設備, 監控設備)
|
||||
- **THEN** the next query SHALL include the corresponding filter parameter
|
||||
#### Scenario: Filter options loading
|
||||
- **WHEN** the page loads
|
||||
- **THEN** workcenter groups and families SHALL load from `GET /api/resource/history/options`
|
||||
- **THEN** machine candidates SHALL be derivable before first query from loaded option resources
|
||||
|
||||
#### Scenario: Upstream filters narrow downstream options
|
||||
- **WHEN** user changes upstream filters (`workcenterGroups`, `families`, equipment-type flags)
|
||||
- **THEN** machine options SHALL be recomputed to only include matching resources
|
||||
- **THEN** narrowed options SHALL be reflected immediately in filter controls
|
||||
|
||||
#### Scenario: Invalid selected machines are pruned
|
||||
- **WHEN** upstream filters change and selected machines are no longer valid
|
||||
- **THEN** invalid selected machine values SHALL be removed automatically
|
||||
- **THEN** remaining valid selected machine values SHALL be preserved
|
||||
|
||||
#### Scenario: Equipment type checkboxes
|
||||
- **WHEN** user toggles a checkbox (生產設備, 重點設備, 監控設備)
|
||||
- **THEN** the next query SHALL include the corresponding filter parameter
|
||||
- **THEN** option narrowing SHALL also honor the same checkbox conditions
|
||||
|
||||
### Requirement: Resource History page SHALL support CSV export
|
||||
The page SHALL allow users to export the current query results as CSV.
|
||||
|
||||
Reference in New Issue
Block a user