專案

一般

配置概況

討論 #1486

是由 陳國瑋 於 27 天 前更新

## 目的 

 定義 Backend Admin Dashboard「即時關鍵指標」區塊的顯示內容、資料來源、計算邊界、更新方式與異常狀態。V1 僅呈現既有資料,不新增預測、告警、派工或任何作業邏輯。 

 ## Mock 現況(全部為展示假資料) 

 目前工作版有六張 KPI card: 

 1. Charge Point 在線。 
 2. Connector 可服務。 
 3. 正在充電。 
 4. 等待供電。 
 5. 今日累積電量。 
 6. 上月電費。 本月預估電費。 

 上述數值仍為展示假資料;「上月電費」的金額語意已由 KPI-DEC-001 確認,其餘 KPI 的名稱與公式仍須逐項確認。 上述名稱、公式與數值尚未全部確認,不能直接視為最終需求或 A17 現況。 

 ## 已知約束 

 - Dashboard 必須適用所有案場;A17 只作第一個資料與效能驗證基準。 
 - CP connection、Connector runtime、Queue state 必須分層,不能互相覆寫。 
 - null 代表未知,不得以 0 冒充。 
 - 案場日期與「今日」以 building timezone 計算。 
 - V1 read-only,不調整 OCPP、Queue、rotation、結算或排程行為。 
 - V1 已明確移除「本月預估電費」及 forecast;第六張改用 KPI-DEC-001 定義的「上月電費」。 「本月預估電費」目前沒有已確認的 forecast 公式、資料完整度與誤差語意;在確認前不得進入 final specification。 
 - KPI 的即時更新應沿用 #1424 已確認的 REST bootstrap/WebSocket replacement 架構,不為每張卡建立獨立連線。 

 ## KPI-DEC-001:第六張 KPI 顯示「上月電費」 改為「上月電費」,金額語意待確認 

 **狀態:已確認(2026-09-04,Ken)** **狀態:項目已確認、計算定義待確認(2026-09-04,Ken)** 

 ### 這張卡要讓使用者知道什麼 已確認 

 - 顯示指定案場「上一個完整日曆月」的門牌帳單應收總額。 移除 mock 原有「本月預估電費」。 
 - 「上月」以該案場的 building timezone 判定;例如案場當地時間已進入 9 月,目標期間就是 8 月。 第六張 KPI 不改成「今日已完成充電 Sessions」,改為「上月電費」。 
 - 金額代表所有門牌月結算資料 `e_bill_settlement.cost_predict` 的合計,不是已收款金額,也不是 Connector 請款金額。 V1 不新增當月費用 forecast 或其他預測邏輯。 
 - `paid`、`pending` 等 bill status 不改變當月應收金額,因此均納入合計。 
 - 只有該月每一筆門牌帳單的 `calculation_status` 都是 `COMPLETE` 時才顯示金額。 
 - 只要仍有 `PENDING_DATA` 或 `ERROR`,金額顯示 `—`,並清楚顯示完成筆數,例如「8 月結算未完成・10 / 11 筆」。 
 - 不顯示已完成資料的部分合計,也不自動退回更早月份,避免讓不完整或過期金額看起來像完整結果。 
 - 整張卡可導向 Dashboard 同頁 `#billing` 結算流程區塊,方便查看是哪個步驟尚未完成;卡片本身不執行任何帳務操作。 Mock 先顯示「上月電費/—/金額來源定義中」,避免在公式確認前沿用 8,920 元假裝已有定義。 

 ### 為何選 `e_bill_settlement.cost_predict` 

 目前程式碼與 程式碼與 schema 有三種不同金額: 事實 

 目前存在三種不同金額語意: 

 1. `e_bill_settlement.cost_predict`:每門牌月結算應收金額,包含用量費與 e_bill_settlement.cost_predict:每門牌月結算金額,包含用量費與 private/public basic charge。 charge,另有 bill_status 與 calculation_status。 
 2. `e_connector_settlement.fee`:每個 e_connector_settlement.fee:每個 Connector/idTag 的服務費,不等同住戶門牌帳單總額。 的月應收費用,不等同門牌帳單合計。 
 3. `InvoiceReportDataDto.totalFee`:Connector InvoiceReportDataDto.totalFee:由 Connector settlement fee 的請款報表合計,也不是門牌帳單總額。 加總的請款報表金額,另有 invoice status 與 calculation_status。 

 「上月電費」採第 1 種語意。此 KPI 不把 `bill_status` 當成收款報表,也不混用第 2、3 種金額。 因此「上月電費」不能只憑欄位名稱選任一 SUM,必須先確認要顯示應收、已收,或 Connector 請款金額。 

 ### Backend 要開發的內容 A17 唯讀彙總基準(2026-09-04 查詢) 

 前一日曆月為 2026/08: 

 - 以 Overview API 的 `generatedAt` 轉換為指定 building timezone,求得上一個完整日曆月的 `periodYear`/`periodMonth`。 e_bill_settlement:11 筆,cost_predict 合計 9,533.63 元。 
 - 僅查詢指定 `buildingId` 與該期間的 `e_bill_settlement`,不可跨案場彙總。 其中 COMPLETE 10 筆/8,983.75 元,ERROR 1 筆/549.88 元。 
 - 回傳 `periodYear`、`periodMonth`、`amount`、`currencyCode`、`completedBillCount`、`totalBillCount`、`dataStatus` 與 `updatedAt`。V1 的 `currencyCode` 為 `TWD`,但 FE 不自行寫死幣別格式。 
 - 至少有一筆帳單且全部 `calculation_status e_connector_settlement:12 筆,fee 合計 2,262.15 元;其中 1 筆 calculation_status = COMPLETE` 時,`dataStatus = COMPLETE`,`amount` 為所有 `cost_predict` 合計。 ERROR。 
 - 任一筆為 `PENDING_DATA` 時回 `dataStatus e_bill_invoice_status:status = PARTIAL`、`amount draft,calculation_status = null`;任一筆為 `ERROR` 時同樣不得回傳部分金額,並透過 source status 保留錯誤語意。 
 - 不依 `bill_status` 過濾 paid/pending,不改用 `e_connector_settlement.fee` 或 Invoice totalFee。 
 - 不回退查詢更早月份,不觸發重算、覆核、付款、Invoice 更新或其他 mutation。 
 - 本 KPI 隨 Dashboard REST snapshot/既有 refresh 更新;沿用 #1460 的 V1 邊界,不增加帳務 WebSocket。 ERROR。 

 > 完全沒有上月帳單資料時的共用 Empty 文案,將與其餘 KPI 的 Empty/Partial/Error 規格一起確認;在確認前不得把 0 筆解讀為 0 元。 以上只包含案場彙總,未記錄門牌、住戶或交易明細。它證明 2026/08 尚不能直接當成完整、最終電費顯示。 

 ### Frontend 要開發的內容 尚待確認的核心語意 

 - 標題固定為「上月電費」,月份與金額只格式化 Backend 回傳值,不以瀏覽器時區自行推算。 上月「應收電費」:所有門牌帳單應收合計,不因 paid/pending 改變。 
 - `COMPLETE` 時依 `currencyCode` 顯示完整金額;真正合計為 0 才能顯示 0。 上月「已收電費」:只加總 paid,會隨付款狀態變動。 
 - `PARTIAL`/計算錯誤時顯示 `—` 與「{月份} 月結算未完成・{completedBillCount} / {totalBillCount} 筆」,不可顯示部分合計。 
 - 卡片使用可鍵盤操作的同頁連結導向 `#billing`,具可見 focus 樣式及清楚的 accessible name。 
 - 不新增 forecast 說明、收款比例、帳務按鈕、Drawer 或 KPI 專用明細 API。 上月「Connector 請款金額」:加總 connector fee,不包含相同的門牌基本費結構。 

 ### A17 驗收基準(2026-09-04 唯讀查詢) 必須先選定其中一種,才能定義 COMPLETE/PARTIAL/ERROR、0/null、期間欄位與 deep link。 

 - 前一日曆月為 2026/08,`e_bill_settlement` 共 11 筆:10 筆 COMPLETE、1 筆 ERROR。 
 - 因資料未全部完成,卡片必須顯示 `—` 與「8 月結算未完成・10 / 11 筆」。 
 - 不得顯示 COMPLETE 部分合計 8,983.75 元,也不得把含 ERROR 資料的 9,533.63 元顯示成完整結果。 
 - 待 11 筆全部完成後,才依當時正式資料重新加總並顯示金額;驗收不把 mock 金額寫死為固定值。 

 ### Acceptance Criteria 

 - [ ] 上月由 building timezone 與 generatedAt 決定,跨年時可正確得到前一年 12 月。 
 - [ ] 金額只使用指定 building/period 的 `e_bill_settlement.cost_predict`,paid/pending 均納入。 
 - [ ] 全部帳單計算完成前 `amount = null`,FE 顯示 `—`、期間與完成筆數,不顯示部分合計。 
 - [ ] 不因本月資料存在而改顯示本月,也不因上月未完成而退回更早月份。 
 - [ ] Card 可使用滑鼠及鍵盤跳到同頁結算流程,且不送出帳務 mutation。 
 - [ ] A17 2026/08 的 10 / 11 未完成情境符合上述顯示。 

 ## 待確認事項 

 - [x] 第六張移除「本月預估電費」,改為「上月電費」;採前一完整日曆月的門牌帳單應收總額,且全部計算完成才顯示金額(KPI-DEC-001)。 第六張移除「本月預估電費」,改為「上月電費」;精確金額語意另行確認(KPI-DEC-001)。 
 - [ ] 「上月電費」採應收、已收或 Connector 請款金額。 
 - Charge Point 在線的 connection/freshness 定義。 
 - [ ] Connector 可服務的 status allowlist 與 unknown 處理。 
 - [ ] 正在充電與等待供電的精確來源/distinct 規則。 
 - [ ] 今日累積電量的日期、有效資料與 今日累積電量及今日 Sessions 的日期、有效資料與 Partial 規則。 
 - [ ] 其餘即時 哪些 KPI 的 使用 WebSocket replacement/REST refresh 分工。 replacement、哪些只隨 REST refresh。 
 - [ ] KPI 共用 Empty/Partial/Error、responsive、accessibility 與 deep link 規則。 link。 

 ## 需求管理狀態 

 - Parent:#1422 
 - Related:#1424(REST/WebSocket)、#1460(結算流程)、#1461(30 日充電用量)、#1463(需留意事項) 
 - Requirement status:討論中;KPI-DEC-001「上月電費」的期間、金額來源、完整性與 deep link 已確認,其餘五張 KPI 待逐項確認 status:討論中;第六張選用「上月電費」已確認,金額語意待確認 
 - Final specification:所有 Dashboard 區塊確認後整併至 #1422 
 - Implementation tickets:需求鎖定後才建立 FE/BE/QA child issues 

返回