專案

一般

配置概況

動作

Feature #1398

進行中

Feature #1397: [功能開發] LIFF DriverState、離峰充電與 Remote Operation 狀態契約重構

[Backend] 實作 DriverState、離峰排程與 Remote Operation lifecycle

是由 陳國瑋5 天 前加入. 於 約 20 小時 前更新.

狀態:
In Progress
優先權:
Normal
被分派者:
開始日期:
2026-08-02
完成日期:
完成百分比:

0%

預估工時:
(總計: 0.00 小時)

概述

h2. 目標

依父項 #1397 及其英文/繁體中文規格附件,完成 Branch/HQ 後端的 DriverState、長期離峰充電排程與 RemoteStart/RemoteStop operation lifecycle。附件內容為本子任務的需求與驗收基準。

h2. 實作範圍

  • 由 Branch 作為 DriverState 與 actions 的唯一業務狀態來源;HQ 僅做契約一致的 passthrough/推播。
  • 正確區分 PUBLIC/PRIVATE Connector,以及 MANUAL/OFF_PEAK 操作來源。
  • 支援 OFF_PEAK_WAITING、QUEUED、PREPARING、CHARGING、FINISHING 等狀態與對應 semantic actions。
  • PREPARING 僅代表已有持久化且尚未終結的 RemoteStart;不得直接以 raw OCPP PREPARING 推導。
  • FINISHING 代表已有持久化且尚未終結的 RemoteStop。
  • 擴充既有 e_remote_transaction_log,保存 business operation lifecycle、source、request actor、deadline、transaction correlation、終結結果等必要資料。
  • e_connector_priority 保存來源與 requestedBy;Priority 真正建立前,已開啟離峰的私樁回 OFF_PEAK_WAITING,建立後回 QUEUED。
  • 保存離峰設定 enabledBy,以及本離峰時段 current-window suppression;StopTransaction 後以中性原因 TRANSACTION_ENDED_FOR_CURRENT_WINDOW 結束本輪,但不關閉長期離峰模式。
  • RemoteStart/RemoteStop 處理 Accepted、Rejected、timeout、有限 retry、late event reconciliation,並可在服務重啟後還原未完成 operation。
  • Command API 執行 authoritative authorization/business guard,針對不允許、衝突、重複 operation 回傳結構化 403/409 與 operationId;避免 API 與 MQ consumer 重複維護授權判斷。
  • 產出完整 OpenAPI DTO/enum/action contract,並透過 RabbitMQ/WebSocket 將最新 snapshot 推送至 HQ/LIFF。
  • 加入必要 schema migration、單元/整合測試、重啟恢復測試及 regression cases;依專案規範維護 E2E catalog。

h2. 驗收重點

  • 公樁不進入私樁離峰排程,保留公樁預留 slot 行為。
  • 私樁離峰開啟後,即使尚未建立 e_connector_priority,也立即可由 OFF_PEAK_WAITING 的 action 取消排隊;Priority 建立後轉 QUEUED。
  • CloudLink/Fortune 在「先插槍、尚未按開始」時,不會因 raw PREPARING 誤顯示為正在啟動。
  • RemoteStart/RemoteStop 失敗或逾時時,DriverState 能顯示可理解的暫態結果,再回復正確的 READY/OFF_PEAK_WAITING/QUEUED 狀態,而非讓使用者只看到可重複按下的開始按鈕。
  • 服務重啟、重複 request、late OCPP event 不會造成重複開始/停止或狀態倒退。
  • API、MQ event、WebSocket snapshot 與 OpenAPI contract 一致。

h2. 不含範圍

  • 不修改 LIFF/FE source code;前端串接由另一張子任務處理。
  • Charge Group 刪除 guard 另見 #1395
  • PUBLIC slot 設定 guard 與 runtime slots==0 防線另見 #1396

檔案

redmine-1398-backend-implementation-plan.md (23.7 KB) redmine-1398-backend-implementation-plan.md Backend implementation plan draft; awaiting Ken approval. 陳國瑋, 2026-07-31 04:15
redmine-1398-backend-implementation-plan-zh-TW.md (23.5 KB) redmine-1398-backend-implementation-plan-zh-TW.md 繁體中文 Backend implementation plan;等待 Ken 核准。 陳國瑋, 2026-07-31 04:19

子任務 1 (1 進行中0 已結束)

Bug #1403: [Backend Bug] Semantic command dispatch 成功後因 transaction snapshot 誤回 409Resolved陳國瑋2026-08-02動作

是由 陳國瑋3 天 前更新

  • 狀態New 變更為 In Progress
  • 開始日期2026-07-29 變更為 2026-07-31

已依 #1397 中英文需求附件啟動 #1398。完成 git pull、建立 feature/redmine-1398-driver-state-offpeak-backend 與本地 ticket 快照;目前進行需求衝突確認及現況程式碼/DB/E2E impact review,尚未開始 coding。

是由 陳國瑋3 天 前更新

#1397 需求附件已於 2026-07-31 修訂並重新上傳:

  • 英文附件 #1102:redmine-1397-driver-state-offpeak-requirements-rev-20260731.md
  • 繁中附件 #1103:redmine-1397-driver-state-offpeak-requirements-zh-TW-rev-20260731.md

本 BE ticket 依修訂契約實作:driverState 僅提供 actions[];統一語意 command API;START_CHARGING/STOP_CHARGING 成功 dispatch 回 202 與 operationId;同步取消/離峰命令回 200;operationResult 僅推送目標使用者;初始快照只含未完成 activeOperation、不重播 terminal result;RemoteStop deadline 30 秒;RemoteStart 沿用各廠牌既有等待時間,deadline 後另有 30 秒事件對帳寬限。

是由 陳國瑋3 天 前更新

需求確認 Gate 已通過:Ken 確認 #1397 附件 #1102/#1103 為本 ticket 正式需求基準。現在進入 implementation plan 階段;Plan 核准前不修改業務程式碼。

是由 陳國瑋3 天 前更新

Implementation plan 已完成並附上,狀態為 Awaiting Ken approval;尚未修改業務程式碼。

Plan 明列 schema、Branch/HQ semantic command API、DriverState actions[]、RemoteStart/Stop lifecycle、離峰 actor/queue source/current-window suppression、targeted WebSocket、測試與 E2E impact。

是由 陳國瑋3 天 前更新

已補上與英文附件 #1104 內容對等的繁體中文 Backend implementation plan;兩版均為 Awaiting Ken approval,尚未修改業務程式碼。

是由 陳國瑋3 天 前更新

Implementation Plan Gate 已通過:Ken 已核准英文附件 #1104 與繁中附件 #1105。已依 SOP 執行 git pull --ff-only origin private,feature branch HEAD 與 origin/private 同為 9a27ab4;現在進入階段 3 實作與單元測試。

是由 陳國瑋3 天 前更新

2026-07-31 Backend 部署/測試進度更新

#1398 Backend 已部署至:

  • Ken Branch/Charge Point 測試環境
  • docker1 HQ staging

本輪安全 Smoke/Contract 共 6 案,全部 PASS:

  1. Branch/HQ api-docs 與 container health。
  2. Branch direct connector snapshot:public CP001-002 回 READY、actions-only driverState、activeOperation=null。
  3. HQ 透過 LINE/building binding 取得相同 snapshot。
  4. 公樁 DISABLE_OFF_PEAK 由 semantic command API 回 409 OFF_PEAK_PRIVATE_ONLY 與最新 driverState。
  5. 上述拒絕不建立 e_remote_transaction_log 或 e_connector_priority。
  6. HQ WebSocket initial fetch 回 101,第一個 frame 為 AVAILABLE/READY/START_CHARGING snapshot。

完整實車/LIFF E2E 尚未執行,現階段整體維持 PARTIAL。Ken 已決定先等待 #1399 Frontend 完成;之後依父項 #1397 附件 #1106(redmine-1397-liff-manual-e2e-test-plan-zh-TW.md)執行 16 個 LIFF 人工 E2E 案例,覆蓋公/私樁、手動/離峰、queue、operation lifecycle、WebSocket、多使用者與重啟恢復。

本地測試報告已同步標記此暫停點;此 note 不代表 #1398 已完成完整 E2E 或可結案。

是由 陳國瑋3 天 前更新

h3. 2026-07-31 OpenAPI response schema 修正

FE 回報 HQ POST /api/connector/commands 的 200/202/403/409 response body 在 OpenAPI 只標為通用 object,導致 yarn openapi:refresh 無法產生具體型別。

原因:endpoint 需要用 ResponseEntity<?> 原樣透傳 Branch 的 200/202/403/409,但原本 @ApiResponse 沒有明確指定 response schema。

已於 #1398 程式補上 OpenAPI annotation:

  • HQ POST /api/connector/commands
    ** 200 OK202 AcceptedConnectorCommandResponse
    ** 403 Forbidden409 ConflictConnectorCommandErrorResponse
  • Branch internal POST /api/cp/hq/connector/commands 同步補相同 schema,避免 HQ/Branch contract 不一致。

Runtime HTTP status 與 response body 語意不變,只修正 OpenAPI contract。E2E Catalog 不新增案例。

驗證:

  • java/ems_hq: mvn -q -DskipTests compile PASS
  • java/ems_branch: mvn -q -DskipTests compile PASS
  • git diff --check PASS

已同步於 #1399 補 FE 使用說明,包含 request body、200/202/403/409 response 欄位與 FE AI 串接重點。

是由 陳國瑋3 天 前更新

h3. 2026-07-31 Push 與 HQ staging 部署確認

已依 Ken 要求將 #1398 推上 remote,並重新部署 HQ staging。

  • Remote branch:feature/redmine-1398-driver-state-offpeak-backend
  • Latest commit:a21baa3(含部署驗證紀錄)
  • Main implementation commit:095d58a
  • HQ staging build:mvn -DskipTests -Ddeploy.target=staging package PASS
  • HQ staging deploy:docker1 /opt/ems/ems_hq/api/api.jar
  • Deployed JAR SHA-256:d796ced0cbbd8cd18feedbe7cd52d3b914210642a2b83cfa8e8a9fbc5e9d759b
  • Container:ems-hq-staging-api 已重建並為 Up

已從 docker1 local http://127.0.0.1:7050/api-docs 驗證 HQ staging OpenAPI:

  • POST /api/connector/commands 200 → ConnectorCommandResponse
  • POST /api/connector/commands 202 → ConnectorCommandResponse
  • POST /api/connector/commands 403 → ConnectorCommandErrorResponse
  • POST /api/connector/commands 409 → ConnectorCommandErrorResponse

因此 FE 重新執行 yarn openapi:refresh 時,應可取得具體 response types,不再只有通用 object。

是由 陳國瑋約 20 小時 前更新

  • 子任務 #1403 已新增
動作

匯出至 Atom PDF