專案

一般

配置概況

討論 #1463

是由 陳國瑋 於 27 天 前更新

## 背景 

 主需求:#1422。 

 原始 mockup 在 Dashboard 頂部使用英文 NEEDS ATTENTION,並顯示「目前有 5 個項目需要處理」。其中「Queue 狀態不同步」只是展示假資料,若要正式成立,必須新增狀態比對/scheduler-health 判斷,與已確認的 Dashboard V1 唯讀、簡化範圍不符。 

 本票定義這個摘要區塊的用途與資料邊界。它不是待辦、派工或自動修復系統。 

 ## ATT-DEC-001:改名為「需留意事項」,只顯示明確既有狀態 

 **狀態:已確認(2026-09-03,Ken)** 

 ### 區塊目的 

 「需留意事項」回答: 

 > 目前有哪些已由 Backend 明確確認的異常或未完成狀態,值得管理者優先查看? 

 使用者不必逐一掃描所有 Dashboard 區塊。摘要項目提供類型、數量與簡短原因,並可導向既有管理頁面或 Dashboard 對應區塊。 

 ### 中文命名 

 - 英文 eyebrow「NEEDS ATTENTION」改為「需留意事項」。 
 - 主標題使用「目前有 N 類項目需要留意」。 
 - 不使用「需要處理」,避免暗示每個項目都必須立即人工操作。 
 - N 由 Backend 正式資料彙整;mockup 的 5 只是展示假資料。 

 ### V1 可納入的明確狀態 

 - Charge Point:既有 OCPP connection status 明確為 OFFLINE。 
 - Connector:既有 runtime status 明確為 FAULTED。 
 - Queue:既有 queue status 明確為 BLOCKED。 
 - Dashboard 資料來源:Backend freshness policy 明確判定為 STALE,或目前資料來源 ERROR/PARTIAL。 
 - 結算流程:#1460 四步驟資料中的既有未完成/異常狀態。 

 上述項目只引用既有 authoritative state 或已確認的 Dashboard dataStatus,不建立新的營運門檻。 

 ### V1 不納入 

 - 「Queue 狀態不同步」等需要額外比對推導的新規則。 
 - WAITING 太久、Queue timeout 或 Queue SLA。 
 - Rotation scheduler-health。 
 - 案場契約容量、利用率或容量餘裕告警。 
 - 預測性維護、異常模型或跨案場排名。 
 - 自動建立工單、指派人員、通知升級或逾期追蹤。 
 - Remote Start/Stop、Reset、重算帳務或其他 mutation。 

 若未來需要上述能力,必須另案定義資料來源、判斷公式與責任人,不能直接加入本摘要。 

 ### Backend 要開發的內容 

 - 依 buildingId 彙整符合確認規則的 category count 與 bounded summary items。 
 - 每個項目使用 stable code、count、display parameters、source updatedAt/freshness 與可供 FE 導覽的 target type/identifier。 
 - 不以自由文字作為 FE 判斷條件;中文文字由 FE 或明確 i18n contract 呈現。 
 - 只讀取既有狀態,不寫回 Charge Point、Connector、Queue、Billing/Invoice 或任何業務資料。 
 - 任一來源失敗時依 overview PARTIAL 規則標示,不捏造 0 筆異常。 
 - 去重、排序、顯示上限與各項 deep link 細節仍待後續逐項確認。 

 ### Frontend 要開發的內容 

 - 顯示「需留意事項」與「目前有 N 類項目需要留意」。 
 - 每個摘要項目顯示數量、清楚的中文名稱及一行原因。 
 - 項目只能導覽/定位至既有頁面或 Dashboard 區塊,不在摘要中放置作業按鈕。 
 - 狀態不能只靠紅/黃色;必須有文字、數字與可存取名稱。 
 - Production API 失敗時不得顯示 mock 假數字。 
 - 正常、Empty、Partial、Error 與大量項目 fixture 在後續規則確認後補齊。 

 ### Mockup 同步 

 - NEEDS ATTENTION 改為「需留意事項」。 
 - 「目前有 5 個項目需要處理」改為「目前有 5 個項目需要留意」。 
 - 「Queue 狀態不同步/標示充電,設備已待機」改為既有明確狀態「Queue 阻塞/2 個項目目前為 BLOCKED」。 
 - 其他數字仍是假資料,不代表 A17 production 現況。 

 ## Acceptance Criteria 

 - [ ] 畫面使用「需留意事項」及「需要留意」,不把摘要描述成派工或待辦。 
 - [ ] 每一種正式項目都可追溯到既有 Backend state 或已確認 dataStatus。 
 - [ ] Queue 只使用既有 BLOCKED;不新增 mismatch、waiting timeout 或 SLA 判斷。 
 - [ ] 不顯示案場契約容量/餘裕告警。 
 - [ ] 摘要與 deep link 均為唯讀,不觸發業務 mutation。 
 - [ ] 未取得來源資料時不回傳 0 冒充「沒有異常」。 
 - [ ] mock 數字與 A17 正式驗收資料明確分開。 
 - [ ] Dashboard 在其餘區塊可用時,不因單一摘要來源失敗而整頁失敗。 

 ## ATT-DEC-002:只有目前負載不可信才進入需留意事項 

 **狀態:已確認(2026-09-03,Ken)** 

 ### 納入摘要的條件 

 「需留意事項」只在目前 Live Load read model 出現下列任一明確狀態時,建立一個「即時負載資料不完整」category: 

 - current Live Load freshness = STALE。 
 - current Live Load dataStatus = PARTIAL。 
 - current Live Load dataStatus = ERROR。 

 此 category 直接引用 Backend 已判定的 current source state,不新增時間門檻或前端推測。點擊後定位至 Dashboard 的 Live Load 區塊,不執行修復操作。 

 ### 不納入摘要的情況 

 - currentPowerKw = 0 且 dataStatus = COMPLETE:代表目前已確認沒有充電負載,是正常狀態。 
 - 過去 finalized bucket 為 PARTIAL/ERROR 或 averagePowerKw = null:只在折線圖保留缺口、tooltip 與區塊內說明。 
 - 不因每一個歷史缺口分別建立摘要項目,也不把缺口數量加到頁首總數。 
 - OPEN bucket 只因時間尚未結束,不構成需留意事項;必須同時有 STALE/PARTIAL/ERROR 才納入。 
 - 不因 currentPowerKw 高或接近任何推算容量而建立告警。 

 ### Backend/事件 

 - category stable code 建議為 LIVE_LOAD_DATA_UNRELIABLE;最終 enum 名稱可在實作 plan 固定,但語意不得擴張。 
 - REST overview 依 current Live Load source state 產生相同 category。 
 - WebSocket 在 current freshness/dataStatus 進入或離開上述狀態時,透過既有「需留意事項」replacement event 更新摘要。 
 - 歷史 series 的單一 bucket status 不觸發摘要 event。 
 - source 恢復 COMPLETE/FRESH 後移除此 category。 

 ### Frontend 

 - 顯示名稱:「即時負載資料不完整」。 
 - 說明依 stable reason code 顯示「資料已過期」、「部分充電功率無法取得」或「負載資料計算失敗」。 
 - 點擊後捲動/定位到 Live Load;不新增獨立頁面。 
 - Live Load 區塊本身仍顯示對應的 stale/partial/error 狀態與重新整理操作。 
 - 歷史缺口維持圖表內呈現,不在「需留意事項」重複列出。 

 ### Mock/Fixture 

 - 正常主 mock 維持 current Live Load FRESH/COMPLETE,不加入故障項目。 
 - 最終 Partial fixture 增加 current Live Load PARTIAL 及一筆「即時負載資料不完整」摘要。 
 - 最終歷史缺口 fixture 只顯示圖表 gap,不出現這個摘要,用來驗證兩者差異。 

 ### Acceptance Criteria 

 - [ ] current STALE/PARTIAL/ERROR 只產生一個 Live Load category,不按 bucket 重複建立。 
 - [ ] current 0 + COMPLETE 不產生需留意事項。 
 - [ ] OPEN + COMPLETE 不產生需留意事項。 
 - [ ] finalized 歷史 gap 不進入摘要,也不增加頁首數量。 
 - [ ] category 可導向 Live Load,但不執行 mutation。 
 - [ ] source 恢復 FRESH/COMPLETE 後摘要同步移除。 
 - [ ] REST bootstrap 與 WebSocket replacement 使用相同判定。 

 ## ATT-DEC-003:頁首計算非零類別,各類顯示受影響數量 

 **狀態:已確認(2026-09-03,Ken)** 

 ### 頁首數字 

 - 頁首文案固定為「目前有 N 類項目需要留意」。 
 - N = categoryCount,代表 affectedCount > 0 的 category 數量。 
 - categoryCount 不是所有 affectedCount 的總和,也不宣稱是設備數、事件數或根因數。 
 - 同一個 category 不論 affectedCount 為 1 或 100,都只對 categoryCount 貢獻 1。 
 - affectedCount = 0 的 category 不顯示,也不計入 categoryCount。 

 ### 各類別計數 

 每個 category 分別回傳 affectedCount,並在同一 category 內依穩定識別碼去重: 

 - CP OFFLINE:依 Charge Point ID distinct count。 
 - Connector FAULTED:依 Connector ID distinct count。 
 - Queue BLOCKED:依 Queue entry ID distinct count。 
 - 結算流程:依 Backend 明確回傳的未完成/異常 step code distinct count。 
 - 即時負載資料不完整:屬 section-level category,存在時 affectedCount = 1。 

 同一實體若重複出現在同類別來源資料中,只計一次。 

 ### 跨類別規則 

 - 不跨 category 去重。 
 - 不推導 CP OFFLINE 是否為 Connector FAULTED/STALE 的共同根因。 
 - 同一設備可在不同 category 中各自出現,因為各 category 表達不同、已確認的狀態。 
 - 頁首只顯示 categoryCount,因此不會把跨類別的 affectedCount 相加後誤稱為不同設備總數。 
 - V1 不建立 root-cause graph、parent-child suppression 或事件關聯引擎。 

 ### Backend Contract 

 需留意事項 read model/replacement event 至少包含: 

 - categoryCount。 
 - categories 陣列。 
 - 每個 category:code、affectedCount、display parameters、target type/identifier、updatedAt/dataStatus。 
 - Backend 驗證 categoryCount 等於 affectedCount > 0 的 categories 數量。 
 - categories 不包含 affectedCount = 0 的空項目。 
 - 當摘要來源為 PARTIAL/ERROR 時,不得以 categoryCount = 0 冒充沒有異常;Partial/Error 整體呈現另依後續狀態規則確認。 

 ### Frontend 

 - 頁首依 categoryCount 顯示「目前有 N 類項目需要留意」。 
 - 每張 category card 顯示自己的 affectedCount 及正確單位,例如「1 個 Connector」、「2 個 Queue 項目」。 
 - FE 不加總 affectedCount 產生另一個總數,也不自行跨類別去重。 
 - categoryCount 與 categories 不一致時視為 contract error,不靜默修正。 

 ### Mockup 

 目前三個非零 category: 

 1. 設備故障:affectedCount = 1。 
 2. Queue 阻塞:affectedCount = 2。 
 3. 結算待確認:affectedCount = 2。 

 因此頁首由「目前有 5 個項目需要留意」改為「目前有 3 類項目需要留意」。1/2/2 仍是展示假資料,不代表 A17 現況。 

 ### Acceptance Criteria 

 - [ ] categoryCount 只計算 affectedCount > 0 的 categories。 
 - [ ] 頁首使用「N 類」,不顯示 affectedCount 總和為設備總數。 
 - [ ] 每類 affectedCount 依該類穩定識別碼 distinct。 
 - [ ] 同類重複資料不重複計數;不同類別不做 root-cause 去重。 
 - [ ] Live Load current quality category 存在時 affectedCount 固定為 1。 
 - [ ] FE 不重新計算 categoryCount 或 affectedCount。 
 - [ ] 來源失敗時不以 0 類冒充沒有需留意事項。 
 - [ ] Mock 正確顯示 3 類與各卡 1/2/2。 

 ## ATT-DEC-004:顯示全部非零類別,固定順序並 Responsive 換行 

 **狀態:已確認(2026-09-03,Ken)** 

 ### 顯示範圍 

 - categories array 顯示全部 affectedCount > 0 的已確認 V1 categories。 
 - affectedCount = 0 的 category 不建立空卡片。 
 - 不做 Top N、隱藏項目、「查看全部」、展開區、Drawer、分頁或使用者自訂排序。 
 - V1 allowlist 目前最多五類,因此直接顯示全部比新增第二層互動更簡單。 
 - 頁首 categoryCount 仍代表全部非零 categories,不受 viewport 或換行影響。 

 ### 固定順序 

 Backend/Frontend contract 的 category 順序固定如下: 

 1. CHARGE_POINT_OFFLINE:Charge Point 離線。 
 2. CONNECTOR_FAULTED:Connector 故障。 
 3. LIVE_LOAD_DATA_UNRELIABLE:即時負載資料不完整。 
 4. QUEUE_BLOCKED:Queue 阻塞。 
 5. SETTLEMENT_INCOMPLETE_OR_ERROR:結算流程未完成/異常。 

 - 不依 affectedCount 大小、最近發生時間或顏色動態重排。 
 - affectedCount = 0 的 category 被省略後,其餘 category 保持上述相對順序。 
 - Backend response/replacement event 應依此順序輸出;FE 保留順序並對未知 code 採安全 fallback,不將未知 code 認成既有類別。 
 - 若未來新增 category,必須更新 allowlist、固定順序、顯示名稱、資料來源與測試,不得只靠自由文字插入。 

 ### Responsive Layout 

 - Desktop/寬畫面:CSS Grid 依可用寬度 auto-fit;intro 與所有非零 category cards 可自動換到下一列。 
 - 約 768/1024 px:兩欄,intro 佔滿第一列。 
 - 390 px/小螢幕:單欄,intro 與 cards 垂直排列。 
 - 卡片不得縮到文字難以閱讀,不產生頁面級或區塊水平捲軸。 
 - 換行只改變版面,不改變 category 順序、categoryCount 或 affectedCount。 
 - keyboard focus/螢幕閱讀順序必須與固定 category 順序一致,不用 CSS visual order 製造 DOM 順序差異。 

 ### Mockup 

 - 正常 mock 目前只有 CONNECTOR_FAULTED、QUEUE_BLOCKED、SETTLEMENT_INCOMPLETE_OR_ERROR 三個非零類別,因此只顯示三張 card。 
 - CHARGE_POINT_OFFLINE 與 LIVE_LOAD_DATA_UNRELIABLE 在正常 mock 為零,不建立假異常卡片。 
 - CSS 改為 auto-fit/wrap,Tablet 兩欄、Mobile 單欄,用同一份 DOM 驗證 1~5 類。 
 - 所有 card 數字仍為展示假資料,不代表 A17 現況。 

 ### Acceptance Criteria 

 - [ ] 1~5 個非零 categories 都完整顯示且依固定順序。 
 - [ ] affectedCount = 0 的 category 不顯示,其他類別相對順序不變。 
 - [ ] 不存在 Top N、Drawer、展開或分頁。 
 - [ ] 390/768/1024/1440 px 不出現水平捲軸或不可讀卡片。 
 - [ ] 換行不改變 categoryCount/affectedCount。 
 - [ ] DOM、keyboard 與視覺順序一致。 
 - [ ] Unknown category code 不冒充任一既有狀態。 
 - [ ] 正常 mock 不為了展示版面而捏造 CP Offline 或 Live Load 異常。 


 ## ATT-DEC-005:成功且沒有非零類別時,保留精簡 Empty State 

 **狀態:已確認(2026-09-04,Ken)** 

 ### 適用條件 

 只有下列條件同時成立時,Frontend 才可顯示「目前沒有需留意事項」: 

 - attention aggregate 的 dataStatus = COMPLETE。 
 - categoryCount = 0。 
 - categories = []。 
 - Backend 已完成本次允許清單內資料來源的彙整,而不是因為 request 尚未完成、部分失敗或回傳內容缺漏而得到空陣列。 

 HTTP 200、畫面沒有卡片或 categories 欄位缺漏,本身都不足以推論為 Empty State。 

 ### 顯示方式 

 - 保留「需留意事項」區塊,不將整個區塊隱藏,讓使用者知道系統已完成檢查。 
 - 區塊縮成單一精簡狀態列,不顯示五張 affectedCount = 0 的空卡片。 
 - 主文案固定為「目前沒有需留意事項」。 
 - 輔助文案為「所有已檢查的狀態目前皆正常」,並顯示 Backend 提供的 updatedAt/頁面 generatedAt 所對應更新時間。 
 - 使用中性偏綠的成功樣式與勾選圖示;不可沿用紅色警示邊框、底色或 pulse。 
 - 狀態意義不能只靠顏色,螢幕閱讀器必須能讀到主文案。 
 - Empty State 不建立通知、事件、待辦或任何作業 mutation。 

 ### Backend Contract 

 attention aggregate 至少明確回傳: 

 - dataStatus。 
 - categoryCount。 
 - categories。 
 - updatedAt;若沿用 overview generatedAt,API contract 必須明確定義,不由 FE 使用本機時間假造。 

 COMPLETE + 0 是經 Backend 確認的正常結果;Frontend 不自行掃描其他 Dashboard 區塊推算是否正常。 

 ### 狀態轉換 

 - WebSocket replacement 使最後一個非零 category 消失,且 aggregate 維持 COMPLETE 時,FE 轉成 Empty State。 
 - 後續出現任何非零 category 時,FE 由 Empty State 回到 category cards。 
 - dataStatus = PARTIAL/ERROR 時不得顯示 Empty State,也不得以 categoryCount = 0 宣稱正常;其呈現方式另由下一項決策確認。 
 - 本規則只改變 read-only Dashboard 顯示,不改變 OCPP、Queue、結算或其他作業邏輯。 

 ### Mockup 

 - 預設網址仍顯示三個非零 category 的假資料。 
 - 在 mock 網址後加上 ?attention=empty,可預覽本 Empty State。 
 - query parameter 僅供 FE review,不是正式產品 UI,也不需要在正式 Dashboard 實作狀態切換控制。 
 - Mock 數字及狀態都不代表 A17 現況。 

 ### Acceptance Criteria 

 - [ ] COMPLETE + categoryCount = 0 + categories = [] 時,保留區塊並顯示精簡 Empty State。 
 - [ ] Empty State 不顯示零值 category cards,也不使用紅色警示樣式。 
 - [ ] 使用者可從文字辨識「已檢查且目前沒有需留意事項」,不只靠顏色。 
 - [ ] PARTIAL、ERROR、request loading 或 contract 缺漏不得顯示正常 Empty State。 
 - [ ] 最後一類消失/第一類出現時,UI 可在 Empty State 與 category cards 間正確切換。 
 - [ ] FE 不以 HTTP 200、空白畫面或本機時間自行推論 COMPLETE。 
 - [ ] Empty State 不觸發任何 mutation、通知或作業流程。 

 ## ATT-DEC-006:Partial 顯示已確認結果,Error 不得顯示為零 

 **狀態:已確認(2026-09-04,Ken)** 

 ### PARTIAL:部分來源成功 

 attention aggregate 的 dataStatus = PARTIAL 代表部分來源有可用結果,但整體無法宣稱完整。 

 - 已成功確認的非零 categories 繼續顯示,不因另一個來源失敗而清空。 
 - categoryCount 仍等於目前 categories 陣列中已確認的非零 category 數量;它不是完整案場總數。 
 - categoryCount > 0 時,頁首改為「已確認 N 類項目需要留意」。 
 - 額外顯示黃色狀態提示:「部分狀態暫時無法確認」及「以下為已確認項目,顯示數量可能不完整」。 
 - categoryCount = 0 時,不顯示「0 類」或綠色 Empty State;只顯示「部分狀態暫時無法確認」。 
 - aggregate 的 PARTIAL 提示是資料完整度狀態,不新增第六個 category,也不計入 categoryCount。 
 - 若 current Live Load 本身 STALE/PARTIAL/ERROR,仍依既有 ATT-DEC-002 顯示 allowlist 內的 LIVE_LOAD_DATA_UNRELIABLE;不得把兩者混成自由文字 category。 

 ### ERROR:整體彙整不可用 

 dataStatus = ERROR 代表本次 attention aggregate 沒有足夠可用結果: 

 - categoryCount = null,不得以 0 代替。 
 - categories = [];空陣列必須搭配 ERROR 解讀,不可套用 COMPLETE Empty State。 
 - 保留區塊並顯示「需留意事項暫時無法取得」。 
 - 不顯示綠色勾選、不宣稱案場正常,也不顯示過期 cards 冒充本次結果。 
 - 顯示 Backend 提供的 errorAt;若存在 lastSuccessfulAt,可一併顯示最後成功更新時間。 
 - 不新增區塊專用 Retry;使用者沿用 Dashboard 頁面既有的重新整理功能。 

 ### Backend Contract 

 attention aggregate 的回傳規則: 

 - COMPLETE:categoryCount 為整數,categories 與數量一致;0 時依 ATT-DEC-005 顯示 Empty State。 
 - PARTIAL:categoryCount 為目前已確認 categories 數量,可為 0;Frontend 必須以「已確認」及部分資料提示呈現。 
 - ERROR:categoryCount = null、categories = []。 
 - dataStatus、categoryCount、categories、updatedAt/errorAt/lastSuccessfulAt 均由 Backend 定義;Frontend 不依 HTTP status、空陣列、本機時間或其他 Dashboard 區塊自行猜測。 
 - categories 與 dataStatus 可由 REST bootstrap 或既有 attention replacement 更新;狀態恢復後以最新 Backend 結果取代畫面。 
 - contract 不一致時視為資料錯誤,不靜默改成 COMPLETE 或 Empty State。 

 ### 顯示與作業邊界 

 - Partial/Error 只描述 Dashboard 讀取結果,不建立告警事件、通知、派工或待辦。 
 - 不修改 OCPP、Queue、結算、排程、freshness cutoff 或任何作業邏輯。 
 - 不新增 retry policy;網路重連與 REST fallback 仍沿用 #1424 已確認規則。 

 ### Mockup 

 - 預設網址:顯示三個非零 category。 
 - ?attention=empty:COMPLETE 且無非零 category。 
 - ?attention=partial:保留三個已確認 category,並顯示黃色「數量可能不完整」提示。 
 - ?attention=error:只顯示「需留意事項暫時無法取得」及失敗時間。 
 - query parameter 只供 FE review,不屬於正式產品 UI。 
 - 所有 mock 數字、狀態與時間均為展示假資料,不代表 A17 現況。 

 ### Acceptance Criteria 

 - [ ] PARTIAL 且 categoryCount > 0 時,已確認 cards 保留,標題使用「已確認 N 類」並顯示數量可能不完整。 
 - [ ] PARTIAL 且 categoryCount = 0 時,不顯示 0 類或正常 Empty State。 
 - [ ] PARTIAL 提示不成為 category,也不增加 categoryCount。 
 - [ ] ERROR 時 categoryCount = null、categories = [],顯示不可取得狀態。 
 - [ ] ERROR/PARTIAL 都不得使用綠色正常文案或由 FE 推論 COMPLETE。 
 - [ ] Error State 沿用頁面既有重新整理功能,不新增區塊專用 Retry。 
 - [ ] 狀態恢復後可用 Backend 最新 replacement/snapshot 回到 COMPLETE、Empty 或非零 categories。 
 - [ ] Partial/Error 顯示不觸發任何業務 mutation。 
 ## 待確認事項 

 - [x] 頁首計算非零 category;各類 affectedCount 於類別內 distinct,跨類別不做 root-cause 去重(ATT-DEC-003)。 
 - [x] 使用固定 allowlist 順序,不依 severity、count 或時間動態重排(ATT-DEC-004)。 
 - [x] 顯示全部非零 V1 categories;不設 Top N/上限、Drawer、展開或分頁,版面 responsive 換行(ATT-DEC-004)。 
 - 每一類項目的 deep link 目的地。 
 - [x] COMPLETE + categoryCount = 0 + categories = [] 時保留精簡 Empty State(ATT-DEC-005)。 
 - [x] 只有目前 Live Load STALE/PARTIAL/ERROR 進入本區塊;歷史 bucket 缺口只在圖表呈現(ATT-DEC-002)。 

 ## 需求管理狀態 

 - Parent:#1422 
 - Related:#1424(REST/WebSocket 資料分工)、#1460(結算流程)、#1462(Live Load) 
 - Requirement status:**ATT-DEC-001~006 已確認;剩餘每類 deep status:**ATT-DEC-001~005 已確認;deep link 目的地待確認** 與 Partial/Error State 逐項確認** 
 - Final specification:全部 Dashboard 區塊確認後整併至 #1422 v1.0 文件 
 - Implementation tickets:需求鎖定後才建立 FE/BE/QA child issues 

返回