專案

一般

配置概況

動作

Bug #1395

已結束

[Branch Bug] 刪除 Charge Group 前未檢查仍被 Connector 使用

是由 陳國瑋 於 2 個月 前加入. 於 約 2 個月 前更新.

狀態:
Closed
優先權:
Normal
被分派者:
開始日期:
2026-07-29
完成日期:
預估工時:

概述

問題描述

目前刪除 Charge Group 時,API 應先確認是否仍有 Connector 的 chargeGroup 指向該 Group。若直接刪除仍被使用的 Group,可能留下失效關聯,並使私人樁的手動排隊、離峰排程與容量計算出現不一致。

本議題由 #1382 driverState/離峰充電需求釐清過程發現,但屬於獨立的 Charge Group 資料完整性問題,不納入 #1382 範圍。

預期行為

  1. 收到刪除 Charge Group request 時,先查詢是否仍有任何 Connector 屬於該 Group。
  2. 若仍有 Connector:
    • 拒絕刪除,Group 資料保持不變。
    • 回傳明確的 domain error,例如 CHARGE_GROUP_IN_USE。
    • 回覆訊息應讓管理者知道必須先移除或重新指派 Connector;可附帶使用中的 Connector 數量。
  3. 若沒有 Connector 使用該 Group,才允許刪除。
  4. 不得透過 cascade、設為 null 或其他隱含方式,讓使用中的 Connector 靜默失去 Charge Group。
  5. API 驗證與刪除應具備一致性,避免檢查後到刪除前被新增 Connector 關聯的競態。

驗收條件

  • Given Charge Group 仍被至少一支 Connector 使用,When 呼叫刪除 API,Then 刪除失敗並回 CHARGE_GROUP_IN_USE,Group 與 Connector 關聯均維持原狀。
  • Given Charge Group 沒有任何 Connector 使用,When 呼叫刪除 API,Then 刪除成功。
  • 補上 service/API regression tests,涵蓋「使用中拒絕」與「未使用可刪除」。
  • 更新 EMS E2E catalog,新增或更新 Charge Group 刪除資料完整性案例。

非本議題範圍

  • #1382 的 driverState、LIFF、離峰 switch 與 WebSocket 行為。
  • Connector 更換或移除 Charge Group 時的離峰模式處理規則;如需調整另行確認。

是由 陳國瑋 於 約 2 個月 前更新

#1395 後端完成/FE 實作交接

後端已合併至 private:b634c30(功能 commit:953126c)。

API contract

1. 刪除前查詢引用數

GET /api/charge-group/connector-count/{chargeGroupId}

成功回應:

{
  "chargeGroupId": "CG001",
  "connectorCount": 2
}

2. 刪除 Charge Group

DELETE /api/charge-group/delete/{chargeGroupId}
  • 未被使用:200 OK,無 response body。
  • Group 不存在:既有 404 Not Found。
  • 仍被 Connector 使用:409 Conflict,body 為:
{
  "errorCode": "CHARGE_GROUP_IN_USE",
  "chargeGroupId": "CG001",
  "connectorCount": 2,
  "message": "此充電群組仍被 2 支 Connector 使用,請先移除或重新指派 Connector"
}

Ryan 的 Branch Admin FE 需求

  1. 使用者點擊刪除前,先呼叫 connector-count API。
  2. connectorCount > 0:不要呼叫 DELETE;顯示不可刪除提示與引用數,請使用者先移除或重新指派 Connector。
  3. connectorCount = 0:依既有 UX 顯示確認框,確認後才呼叫 DELETE;成功才更新/重取列表。
  4. 預查 API 失敗時採 fail-safe:不可繼續刪除,顯示錯誤。
  5. 即使預查為 0,DELETE 仍可能因並行 Connector 指派而回 409;此時顯示後端 message 與 connectorCount、保持列表資料、不自動重試,也不得誤顯示刪除成功。
  6. FE 請以 errorCode === "CHARGE_GROUP_IN_USE" 判斷,不要比對 message 字串。

驗收:UI-022(P1 Planned)。後端已在 Expo isolated DB clone 完成整合測試(3/3)與單元測試(5/5),clone 已清除。

是由 陳國瑋 於 約 2 個月 前更新 · 已被編輯

  • 被分派者 從 陳國瑋 變更為 鍾正剛

是由 陳國瑋 於 約 2 個月 前更新

  • 狀態 從 New 變更為 Resolved

後端修正已完成並合併至 private。

  • merge commit: b634c30
  • 功能 commit: 953126c
  • Expo isolated clone 整合測試:3/3 PASS
  • 單元測試:5/5 PASS
  • package 與 E2E catalog validator:PASS
  • 測試 clone 與連線通道已清除
  • FE API spec/UI-022 已留在前一則公開備註,並已指派 Ryan(鍾正剛)實作。

是由 陳國瑋 於 約 2 個月 前更新

  • 狀態 從 Resolved 變更為 In Progress

是由 鍾正剛 於 約 2 個月 前更新

【FE 開發完成】#1395 Branch Admin 充電群組刪除

branch: fix/redmine-1395-charge-group-delete-in-use(base: private)

一、實作內容

  1. 點擊刪除先呼叫 GET /api/charge-group/connector-count/{id}(需求 1)。
  2. connectorCount > 0:不送 DELETE,直接以警告對話框顯示引用數與後續處理方式(需求 2)。
  3. connectorCount = 0:維持既有 SweetAlert 確認框,確認後才送 DELETE,成功才 invalidate 列表(需求 3)。
  4. 預查失敗(含回應格式非預期)一律 fail-safe 中止刪除,不再當成 0 放行(需求 4)。原本的實作是 fail-open,這次修掉。
  5. 409 以 errorCode === "CHARGE_GROUP_IN_USE" 判斷,顯示後端 message 與 connectorCount,不 invalidate 列表、不重試、不顯示成功(需求 5、6)。

二、順帶修掉的既有缺陷

  1. 409 會同時跳 SweetAlert 與 toast 兩則提示,且 SweetAlert 只顯示「409 Conflict」。原因是 crudHooksFactory 的 useDelete 已內建 onError toast,呼叫端再掛的 per-call onError 不會取代它,兩者都會執行;而 commonAlertError 讀的是 err.response.data.message,但 middleware 掛上的 err.response 是 Response 物件、沒有 .data,所以 fallback 到 "409 Conflict"。現在每條失敗路徑只會出現一則提示:業務阻擋走對話框,其餘錯誤走 toast。
  2. 刪除改用專屬的 useDeleteChargeGroup,不走 crudHooksFactory。原因是 factory 的 onError 會先呼叫 getErrorMessage 讀掉 response body,而 body stream 只能讀一次,呼叫端就再也拿不到 errorCode,無法滿足需求 6。
  3. DELETE 改為檢查 openapi-fetch 回傳的 error。errorMiddleware 在 401 走 signOutToLogin 後是 return response 而非 throw,原本會誤報刪除成功。

三、後續事項(給後端)

  1. GET /api/charge-group/connector-count/{id} 目前在 OpenAPI 沒有宣告 response schema,產生的型別是 {[key: string]: unknown},FE 只能用 as any 取 connectorCount。若方便,麻煩補上 response DTO,FE 再跑一次 openapi:refresh 就能拿到型別。
  2. 已知但這次未處理:crudHooksFactory / error-handler 會讀掉 response body,任何要判斷結構化 domain error 的功能都得像這次一樣繞過 factory。要根治得改共用層(讓 middleware 先把 body 解析好掛在 error 上),影響全站所有 request,不在本票範圍,建議另開票。

四、E2E catalog

UI-022 由 Planned 轉 Active,並補上「預查失敗須 fail-safe」與「任一失敗路徑只能出現一則提示」兩條驗收點。validator PASS。

是由 鍾正剛 於 約 2 個月 前更新

  • 狀態 從 In Progress 變更為 Resolved

是由 陳國瑋 於 約 2 個月 前更新

  • 狀態 從 Resolved 變更為 Closed
動作

匯出至 Atom PDF