專案

一般

配置概況

Feature #1381 » branch-admin-engineer-command-plan.md

Branch Admin Engineer Command Center implementation plan - 陳國瑋, 2026-07-14 05:37

 

Branch Admin Engineer Command Center Implementation Plan

1. 目標

在 Branch Admin 增加僅供 Engineer Role 使用的「工程師工具」,讓工程師可以:

  1. 對指定 CloudLink Connector 執行受控 Modbus 讀取與控制。
  2. 由 Branch 直接向已連線 Charge Point 發送完整的 OCPP 1.6 CSMS Command。
  3. 查詢每次操作的 request、response、錯誤、耗時及後續狀態時間軸。
  4. 以 Fortune(華城)充電樁測試為主要使用情境,同時保留其他廠牌的能力標示。

本文件是實作規劃,不包含本次程式碼或資料庫變更。

2. 已確認的產品決策

項目 決策
使用者 新增 engineer Role,顯示名稱為 Engineer
初始成員 將既有帳號 ADMINpower_user 額外加入 engineer Role
Role 繼承 不自動授權所有 administratorpower_user Role 成員
導覽位置 Branch Admin 側邊欄新增獨立「工程師工具」頁面
頁面結構 Charge Point/Connector 選擇器,加上 ModbusOCPP操作紀錄 三個分頁
Connector 入口 Connector 頁面可以 deep-link 到工程師工具並預選 Connector
操作原因 不要求填寫
二次確認 不做全面二次確認;僅 Reset、供電開關、修改 Meter ID 顯示一次簡單確認
OCPP 範圍 提供全部 19 個 OCPP 1.6 CSMS -> Charge Point Command
未驗證能力 仍允許發送,但顯示「未驗證」警告
已知不支援 UI 禁用並顯示原因;後端同樣拒絕,不能只依賴前端
OCPP 輸入 結構化表單及進階 JSON 模式;兩者都必須通過同一份 OCPP schema 驗證
API 執行方式 保留既有 8 個同步 API;新增 Engineer 專用 Command API,在 HTTP request 內完成 WebSocket dispatch,response tracking 採非同步
長時間操作 GetDiagnosticsUpdateFirmware 以操作時間軸追蹤後續 StatusNotification
檔案 URL V1 由 Engineer 手動輸入 HTTP/HTTPS URL,Branch 不提供檔案上傳或儲存服務
稽核保留 e_engineer_command_log 保留 365 天
Modbus 控制 供電開關刻意呼叫 controlTestMode(),不改為 controlRelay()
原始 Modbus 不提供任意 function code、register address 或 raw payload

3. 現況與缺口

3.1 Branch OCPP

現有 OcppController 提供 8 個 API:

  • RemoteStartTransaction
  • RemoteStopTransaction
  • Reset
  • TriggerMessage
  • ChangeAvailability
  • DataTransfer
  • GetConfiguration
  • ReserveNow

主要缺口:

  • OCPP 1.6 的另外 11 個 CSMS Command 尚無 Branch API。
  • 回應處理採逐 Command 註冊 handler;ReserveNow 未註冊 response handler。
  • 既有 API 會在 HTTP request 中等待最多 15 秒,不適合 Engineer 操作追蹤及長時間指令。
  • 現有 e_ocpp_message_log 是傳輸層訊息紀錄,沒有操作者、功能來源、完整操作狀態及跨服務 correlation。
  • FirmwareStatusNotificationDiagnosticsStatusNotification 尚無 Branch incoming handler。

既有 /api/fev/connector/availability 及 8 個 /api/ocpp API必須維持相容,內部可逐步共用新的 dispatcher,但不得改變現有 response contract。

3.2 Charge Point Modbus

CloudLink Charge Point 已有受控的 Modbus 方法及部分 OCPP DataTransfer

  • MeterRead 目前只回傳 current、voltage、active power、total energy。
  • RelayControl 已透過 controlTestMode() 實作供電控制。
  • Meter Controller 另有 apparent power、power factor、balance、relay state、Meter ID 等能力,但不應由 Browser 直接呼叫 Charge Point REST API。

缺口是建立完整、受控且可稽核的 Branch -> OCPP DataTransfer -> Charge Point Modbus 路徑。

3.3 Branch Admin 與權限

  • 前端選單由 /api/menu/list 及 SS3A function/role mapping 動態產生。
  • 前端使用 OpenAPI 產生的 TypeScript types、React Hook Form、Zod、TanStack Query 及既有 UI 元件。
  • 必須新增 SS3A role、function、API mapping、i18n 及指定帳號 role mapping,不能只在 React 寫死選單或角色判斷。

4. OCPP 1.6 Command Catalog

Engineer OCPP API 提供以下全部 19 個 Command:

分類 Command 主要欄位
Remote operation RemoteStartTransaction idTag、connectorId、chargingProfile
Remote operation RemoteStopTransaction transactionId
Device control Reset type
Device control ChangeAvailability connectorId、type
Device control UnlockConnector connectorId
Request trigger TriggerMessage requestedMessage、connectorId
Vendor extension DataTransfer vendorId、messageId、data
Configuration GetConfiguration key
Configuration ChangeConfiguration key、value
Configuration ClearCache 無 payload
Reservation ReserveNow connectorId、expiryDate、idTag、reservationId、parentIdTag
Reservation CancelReservation reservationId
Smart charging SetChargingProfile connectorId、csChargingProfiles
Smart charging ClearChargingProfile id、connectorId、chargingProfilePurpose、stackLevel
Smart charging GetCompositeSchedule connectorId、duration、chargingRateUnit
Diagnostics GetDiagnostics location、startTime、stopTime、retries、retryInterval
Firmware UpdateFirmware location、retrieveDate、retries、retryInterval
Local auth list GetLocalListVersion 無 payload
Local auth list SendLocalList listVersion、localAuthorizationList、updateType

Schema 的基準來源為 documents/OCPP_1.6_documentation/schemas/json/。實作時將所需 schema 複製到 Branch runtime resources,並由後端 validator 驗證;不能只靠前端 Zod。

5. Modbus Command Catalog

V1 只允許下列 command key:

Command key 類型 行為
CONNECTION_TEST Read 驗證 Gateway/Slave 是否可通訊
READ_SUPPLY_STATE Read 讀取目前供電狀態
READ_VOLTAGE Read 讀取電壓
READ_CURRENT Read 讀取電流
READ_ACTIVE_POWER Read 讀取有效功率
READ_APPARENT_POWER Read 讀取視在功率
READ_POWER_FACTOR Read 讀取功率因數
READ_TOTAL_ENERGY Read 讀取累積電量
READ_BALANCE Read 讀取餘額
READ_METER_ID Read 讀取 Meter ID
SET_SUPPLY_STATE Write on/off 轉成 controlTestMode(..., 1/0)
SET_METER_ID Write 設定 1 到 255 的 Meter ID

明確排除:

  • 清除歷史資料
  • 任意 Modbus function code
  • 任意 register address/value
  • 瀏覽器直接連線 Charge Point REST API
  • 對 Fortune、Tesla 或其他非 CloudLink Connector 發送 Modbus command

6. 目標架構

sequenceDiagram
    actor E as Engineer
    participant FE as Branch Admin
    participant API as Branch Engineer API
    participant DB as Command Log DB
    participant WS as Branch OCPP WebSocket
    participant CP as Charge Point

    E->>FE: 選擇裝置、Command、填寫 payload
    FE->>API: POST Engineer Command
    API->>API: Role、target、capability、schema 驗證
    API->>DB: 建立 command log + CREATED event
    API->>WS: OCPP CALL(uniqueId, action, payload)
    WS->>CP: 發送指令
    API->>DB: 更新為 SENT
    API-->>FE: 202 + commandLogId + SENT
    CP-->>WS: CALLRESULT 或 CALLERROR
    WS->>DB: 依 uniqueId 更新狀態及 event
    opt Diagnostics/Firmware
        CP->>WS: StatusNotification
        WS->>DB: 附加進度 event
    end
    FE->>API: Poll command detail
    API-->>FE: 狀態、payload、時間軸

核心原則:

  • HTTP request 內必須完成 command log 建立與 OCPP WebSocket dispatch;OCPP CALL 成功送出後,其 response、後續 status notification 的關聯及稽核不得依賴原始 HTTP connection。Client 離開頁面不會取消已送出的 Command。
  • OCPP 傳輸仍由既有 WebSocket/session infrastructure 負責。
  • 新流程以 ocppUniqueId 查找 command log,使用通用 response observer 更新狀態。
  • 原有 response handlers 及同步 request managers 仍可同時接收 response,確保舊 API 相容。
  • 所有 Branch 與 CloudLink Charge Point 相關 app log 都加入 correlationId;UI 不保存 PID/thread 的整份 raw log。

7. Branch Backend 實作

7.1 Command catalog 與 validation

建立集中式 EngineerCommandCatalog

  • 定義 protocol、command name、target level、risk level、payload schema、terminal result 規則。
  • OCPP action 只能從 catalog 選取,不能讓 client 傳任意 action。
  • Modbus operation 只能從第 5 節 allowlist 選取。
  • OCPP JSON schema validation 同時服務結構化表單及進階 JSON request。
  • 驗證 OCPP connectorId 必須屬於所選 Charge Point。
  • Charge Point 未連線時在 dispatch 前失敗,狀態記為 SEND_FAILED/OFFLINE
  • Operator 一律取自 JWT identity,不接受 request body 覆寫。

7.2 Engineer Command API(非同步追蹤)

建議 API:

Method Path 用途
GET /api/engineer/commands/catalog 回傳 command、schema、風險及 capability
POST /api/engineer/ocpp/commands 建立並發送 OCPP command,回傳 HTTP 202
POST /api/engineer/modbus/commands 建立並發送受控 Modbus command,回傳 HTTP 202
POST /api/engineer/commands/search 分頁查詢操作紀錄
GET /api/engineer/commands/{id} 查詢完整 operation 與 event timeline

OCPP create request 範例:

{
  "chargePointId": "CP001",
  "connectorId": "CP001-001",
  "command": "ChangeConfiguration",
  "payload": {
    "key": "HeartbeatInterval",
    "value": "60"
  }
}

Create response 最少包含:

{
  "commandLogId": "uuid",
  "correlationId": "uuid",
  "ocppUniqueId": "uuid",
  "state": "SENT",
  "capability": "UNVERIFIED",
  "createdAt": "2026-07-14T10:00:00+08:00"
}

API response 需清楚區分:

  • HTTP/API validation error:request 根本沒有建立操作。
  • SEND_FAILED:操作已建立,但 Charge Point offline 或 WebSocket send 失敗。
  • CALL_ERROR:收到 OCPP CALLERROR,保存 errorCode、description、details。
  • REJECTED:收到合法 CALLRESULT,但 protocol status 為 Rejected/NotSupported 等。
  • TIMEOUT:在 vendor-aware response timeout 內未收到 CALLRESULT/CALLERROR。

HTTP 202 只表示 Branch 已完成 WebSocket dispatch 並開始追蹤結果。Command 本身不需要排入背景佇列;只有 CALLRESULT、CALLERROR 與後續 status notification 由 WebSocket incoming flow 非同步更新 operation。

7.3 Request 內 dispatch 與非同步 response observer

新增獨立 EngineerOcppCommandDispatcher

  1. 建立 log 後產生 correlationIdocppUniqueId
  2. 在發送前寫入 MDC,並建立 DISPATCHING event。
  3. 呼叫既有 OcppCommandSender 發送標準 OCPP CALL。
  4. 發送成功後在同一 HTTP request 內更新 SENT 並回傳 HTTP 202;不等待 Charge Point 的 CALLRESULT/CALLERROR。
  5. 若 WebSocket dispatch 當下失敗,更新為 SEND_FAILED,error response 必須包含 commandLogId,方便查詢稽核紀錄。
  6. OcppMessageProcessor 稍後收到 CALLRESULT/CALLERROR 時,先交給通用 observer 依 uniqueId 更新 Engineer log,再保留既有 response handler 流程。

V1 不要求 durable job queue,也不承諾 Branch process 重啟後重新發送尚未 dispatch 的 Command。服務重啟恢復若有需要,另立需求定義。

這個 observer 不應依賴 19 個獨立 handler。Action 由 command log 或 e_ocpp_message_log 的原始 request 查得。

7.4 狀態機

建議主要狀態:

CREATED -> VALIDATED -> DISPATCHING -> SENT
SENT -> COMPLETED | REJECTED | CALL_ERROR | TIMEOUT
SENT -> RUNNING -> COMPLETED | FAILED | TIMEOUT | STATUS_UNKNOWN
CREATED/VALIDATED/DISPATCHING -> SEND_FAILED
  • 一般 command 收到 CALLRESULT 後依 payload status 判定 COMPLETEDREJECTED
  • 沒有 status 的空 CALLRESULT 視該 command 定義判定成功。
  • GetDiagnosticsUpdateFirmware 收到初始 response 後進入 RUNNING,後續通知才決定最終狀態。
  • Fortune 的同步 response timeout 使用現有 vendor timeout 概念,預設 120 秒;其他 vendor 使用可設定預設值。
  • 長時間操作 timeout 另設設定值,不能沿用同步 response timeout。

7.5 Firmware/Diagnostics 時間軸

新增 incoming handlers:

  • FirmwareStatusNotificationHandler
  • DiagnosticsStatusNotificationHandler

兩者都必須:

  1. 回傳符合 OCPP schema 的空 CALLRESULT。
  2. 保存原始 status notification 到 OCPP message log。
  3. 找出同一 Charge Point 尚在執行的對應 Engineer operation。
  4. 寫入 command event 並更新主要狀態。

因 status notification 不帶原始 command uniqueId,V1 對同一 Charge Point 的同類長時間 command 只允許一筆 active operation;重複送出回 HTTP 409,避免錯誤關聯。

7.6 Capability matrix

Capability 狀態:

  • VERIFIED:已在指定 vendor/model/firmware 驗證。
  • UNVERIFIED:可發送,UI 顯示警告。
  • UNSUPPORTED:已知不支援,前後端都拒絕。

Fortune 的 19 個 command 初始可設為 UNVERIFIED,已經實機驗證者再調整為 VERIFIED。未知 vendor 預設為 UNVERIFIED,不能假設支援。

建議新增 e_ocpp_command_capability 保存 vendor、model、firmware、command、status、note、verifiedAt、verifiedBy;V1 不必製作 capability 管理 UI,可先由 migration seed 及後續維運 patch 更新。

7.7 URL 與敏感資料

  • GetDiagnostics.locationUpdateFirmware.location 只接受合法 HTTP/HTTPS URI。
  • 拒絕含 user-info 的 URL,例如 https://user:password@host/path
  • 稽核資料保存實際發送 payload,列表及一般 UI 顯示使用 masked payload。
  • URL query value、idTag 等可能敏感欄位預設遮蔽;完整資料只在 Engineer detail API 的受權限欄位中提供。
  • app log 不直接輸出完整敏感 payload,使用 commandLogId、correlationId、action 及結果定位 DB audit。

8. Charge Point 實作

8.1 新增受控 DataTransfer message

保留既有 MeterReadRelayControl contract,另外新增明確的 Engineer messageId,例如:

vendorId: CloudLink
messageId: EngineerModbusCommand
data: JSON string

Data 最少包含:

{
  "correlationId": "uuid",
  "connectorId": 1,
  "operation": "READ_POWER_FACTOR",
  "parameters": {}
}

Charge Point handler 必須再次檢查 operation allowlist,不能把 parameters 當作 raw Modbus request。

8.2 Modbus operation mapping

  • Read command 呼叫既有 ConnectorMeterReaderModbusService 的具名方法。
  • SET_SUPPLY_STATE 固定呼叫 controlTestMode(host, port, slaveId, timeout, command)
  • SET_METER_ID 使用 controlMeterId() 並限制 1 到 255。
  • 每個 response 回傳 operation、connectorId、value/unit 或 result、elapsedMs。
  • 錯誤回傳穩定 error code,例如 CONNECTOR_NOT_FOUNDGATEWAY_MISSINGMODBUS_TIMEOUTINVALID_PARAMETEROPERATION_FAILED
  • 在 handler scope 將 correlationId 放入 MDC,所有相關 Charge Point log 都可用該 ID 搜尋。

8.3 明確不變更的硬體語意

畫面與 Branch API 使用「供電控制」語意,但 CloudLink 智慧電表只能透過 Test Mode 控制:

UI: 供電開啟/關閉
Backend operation: SET_SUPPLY_STATE
Charge Point implementation: controlTestMode(..., 1/0)

不得在實作時自行改用 controlRelay(),也不額外暴露 Test Mode command。

9. Database Plan

9.1 e_engineer_command_log

建議欄位:

  • id BINARY(16) UUID
  • protocolOCPP / MODBUS
  • command_name
  • charge_point_id
  • connector_id nullable
  • vendormodelfirmware_version snapshot
  • capability_status snapshot
  • operator_id
  • correlation_id
  • ocpp_unique_id nullable
  • request_payload JSON/LONGTEXT
  • response_payload JSON/LONGTEXT nullable
  • state
  • protocol_status nullable
  • error_codeerror_descriptionerror_details nullable
  • created_atsent_atresponded_atcompleted_at
  • elapsed_ms nullable

索引至少包含:

  • unique correlation_id
  • unique nullable ocpp_unique_id
  • (created_at)
  • (charge_point_id, created_at)
  • (connector_id, created_at)
  • (operator_id, created_at)
  • (protocol, command_name, state, created_at)

9.2 e_engineer_command_event

使用子表保存完整時間軸,避免把多次 status notification 覆蓋在主表:

  • id BINARY(16) UUID
  • command_log_id FK
  • sequence_no
  • event_type
  • state
  • payload JSON/LONGTEXT nullable
  • message
  • created_at

索引及唯一條件:

  • unique (command_log_id, sequence_no)
  • index (command_log_id, created_at)

9.3 Migration 與 retention

新增可重複執行的 SQL patch,包含:

  • command log/event/capability tables
  • Engineer role/function/API/i18n mappings
  • ADMINpower_user 的 member-role mappings
  • 365 天 cleanup task;刪除主表時先刪 event,或以 FK cascade 處理

Hibernate entity 與 SQL patch 必須一致;integration-test schema 也要同步新增必要表格。

10. SS3A 權限 Plan

建議 function tree:

engineer_tool_mgmt              /engineer-tools       menu
engineer_tool_execute           execute OCPP/Modbus
engineer_tool_log_list          search logs
engineer_tool_log_view          view detail/timeline

Migration 必須:

  1. 新增 ss3a_role.engineer 及 zh_TW/en_US i18n。
  2. 新增 function、function i18n、API records 及 function-API mappings。
  3. 將上述 function 只授權給 engineer Role。
  4. ADMINpower_user member 加入 engineer Role。
  5. 不把 function 直接加到 administratorpower_user Role。

所有 POST/search/detail API 都要有後端權限測試,不能只測側邊欄是否隱藏。

11. Frontend Implementation Guidance

11.1 路由與整體 layout

新增 /engineer-tools 頁面,沿用現有 dashboard shell。頁面採全寬工作區,不做 landing page,也不要把整個 section 包成巢狀 Card。

第一列固定為 target bar:

  • Charge Point searchable select
  • Connector searchable select;只在 command 需要 connector 時必填
  • 線上狀態
  • vendor、model、firmware
  • capability badge

Target bar 下方使用三個 tabs:

  • Modbus
  • OCPP
  • 操作紀錄

Desktop 可使用左側 command list、右側 form/result 的兩欄布局;mobile 改為上下排列。command list 需有固定寬度或 responsive grid,切換 command 時不能造成整頁寬度跳動。

11.2 Modbus tab

  • 只在 Connector Type 為 CloudLink 時啟用。
  • command 依「連線與狀態」、「電力讀值」、「控制」分組。
  • Read command 直接執行,不顯示確認 modal。
  • SET_SUPPLY_STATESET_METER_ID 顯示一次簡單確認。
  • 顯示結構化 result、單位、耗時、commandLogId 及 correlationId。
  • UI 文案使用「供電控制」,可用次要說明標示底層為智慧電表 Test Mode;不新增獨立 Test Mode 控制。

11.3 OCPP tab

  • 19 個 command 依第 4 節分類顯示,支援搜尋。
  • target bar 顯示 VERIFIEDUNVERIFIEDUNSUPPORTED badge。
  • UNVERIFIED 可執行,送出按鈕附近顯示非阻斷警告。
  • UNSUPPORTED 禁用並顯示 capability note。
  • 使用 segmented control 切換「表單」與「JSON」。
  • 表單由 catalog/schema metadata 產生或映射;JSON mode 使用同一份 payload state,切換模式不可丟資料。
  • JSON schema error 顯示到欄位/path,例如 /csChargingProfiles/chargingSchedule/...
  • Reset 送出前顯示一次簡單確認;其他 OCPP command 不增加二次確認。
  • 建立成功後立即顯示 operation status panel,TanStack Query 輪詢 detail API;進入 terminal state 後停止輪詢。

11.4 操作紀錄 tab

Filter:

  • 時間範圍
  • protocol
  • command
  • Charge Point/Connector
  • operator
  • state/result
  • correlationId / ocppUniqueId

Table 欄位:

  • 執行時間
  • protocol / command
  • target
  • operator
  • state/result
  • elapsed
  • correlationId

點擊 row 開啟 detail drawer 或獨立 detail view,內容包含:

  • 裝置 snapshot
  • masked request/response JSON
  • OCPP CALLERROR details
  • command event timeline
  • commandLogId、correlationId、ocppUniqueId 的複製按鈕

長字串使用 monospace、wrap 及 copy icon,不能讓 JSON 或 ID 撐破 drawer。

11.5 Connector deep-link

在既有 Connector status/action 區加入工具 icon button,導向:

/engineer-tools?connectorId={id}&tab=ocpp

只有具 Engineer Role/function 的使用者顯示。目標頁仍須重新由 API 驗證 target 與權限。

11.6 前端技術要求

  • 完成 Branch OpenAPI 後執行 yarn openapi:refresh,使用產生的 types。
  • 沿用既有 React Hook Form、Zod、TanStack Query、shadcn 元件及 toast/error pattern。
  • command catalog 是畫面能力與 schema 的唯一後端來源,不在 FE 重複寫 vendor allowlist。
  • FE 可維護 presentation metadata,例如中文標籤、欄位排序及分組,但 command key 必須來自 API contract。
  • 實作後執行 lint/build,並檢查 desktop/mobile 無重疊、截斷或布局跳動。

12. Test Plan

12.1 Branch unit tests

  • 19 個 OCPP command 都能從 catalog 解析並通過合法 schema。
  • 每個 command 的 required field、enum、nested payload 及 additional property 驗證。
  • 任意 action、任意 Modbus operation、跨 Charge Point connector 被拒絕。
  • capability 的 VERIFIED/UNVERIFIED/UNSUPPORTED 行為。
  • state machine 不允許非法倒退或重複 terminal transition。
  • URL scheme、user-info、Meter ID range 驗證。
  • JWT operator 覆蓋 request operator 的攻擊情境不存在。

12.2 Branch integration tests

  • Engineer 可呼叫 catalog、execute、search、detail。
  • administrator/power_user Role 本身不能呼叫;只有額外持有 engineer Role 的指定 member 可以。
  • 非 Engineer 回 403,未登入回 401。
  • fake OCPP session 對 19 個 command 驗證 CALL action、uniqueId、payload。
  • CALLRESULT、CALLERROR、offline、send failure、timeout 都正確更新 log/event。
  • 舊 8 個 /api/ocpp API 及 /api/fev regression tests。
  • cleanup 只刪除超過 365 天資料。

12.3 Charge Point tests

  • 12 個受控 Modbus operation 的 normal/abnormal cases。
  • 非 allowlist operation、raw register/function payload 被拒絕。
  • SET_SUPPLY_STATE spy 驗證呼叫 controlTestMode(),且沒有呼叫 controlRelay()
  • Gateway missing、connector missing、Modbus timeout、invalid Meter ID 的穩定 error response。
  • correlationId 在 DataTransfer response 及 MDC log 可查。

12.4 OCPP long-running tests

  • Firmware status progression:Downloaded/Downloading/Installing/Installed 及 failure states。
  • Diagnostics status progression:Uploading/Uploaded 及 failure states。
  • 同一 Charge Point 重複 active long-running command 回 409。
  • 無可關聯 operation 的 status notification 仍正常回 CALLRESULT,並記錄 orphan warning,不可影響 WebSocket session。

12.5 Fortune 實機驗證矩陣

每個 Fortune model/firmware 對 19 個 command 記錄:

  • request payload
  • CALLRESULT/CALLERROR
  • response latency
  • protocol status
  • 實際設備行為
  • capability 結論及備註

測試後以 migration/維運 patch 將 capability 從 UNVERIFIED 更新為 VERIFIEDUNSUPPORTED

13. 分階段實作順序

Phase 1: Database、Role 與 operation foundation

  • 建立 command log/event/capability tables。
  • 建立 Engineer role/function/API mappings,授權 ADMINpower_user
  • 實作 audit repository/service、state machine、365-day cleanup。
  • 實作 catalog、schema validator、search/detail API。

Phase 2: OCPP dispatch 與非同步 response tracking

  • 實作 request 內 dispatch、HTTP 202 response、generic response observer。
  • 先接通現有 8 個 command,補上 ReserveNow response 缺口。
  • 確認舊 8 個 API 及 FEV API 相容。

Phase 3: 補齊全部 19 個 OCPP command

  • 加入其餘 11 個 command schema/validation/dispatch。
  • 加入 CALLRESULT/CALLERROR audit。
  • 加入 Firmware/Diagnostics incoming handlers 及 timeline correlation。
  • 產出完整 OpenAPI contract。

Phase 4: CloudLink Modbus command bridge

  • Branch 增加 Modbus create API 及 CloudLink-only target validation。
  • Charge Point 增加受控 DataTransfer handler。
  • 完成 12 個 operation、錯誤碼與 correlation log。

Phase 5: Branch Admin UI

  • 新增動態選單、target bar、三個 tabs。
  • 完成 schema-driven OCPP form/JSON mode、Modbus controls、log timeline。
  • 加入 Connector deep-link。
  • 執行 OpenAPI refresh、lint、build 及 responsive verification。

Phase 6: Fortune 實機驗證與 capability 收斂

  • 逐 command 執行 Fortune test matrix。
  • 修正 vendor-specific payload/timeout 差異,但不破壞標準 OCPP schema。
  • 更新 capability seed/patch 及測試報告。

14. 驗收條件

功能完成至少需要符合:

  1. 只有持有 Engineer Role 的使用者看得到並呼叫得到工程師工具。
  2. ADMINpower_user 已額外持有 Engineer Role。
  3. Fortune 可由同一個 Engineer API 嘗試全部 19 個 OCPP Command。
  4. UNVERIFIED 可發送、UNSUPPORTED 前後端都禁止。
  5. 所有 payload 都通過對應 OCPP schema;無任意 action 入口。
  6. Modbus 僅限 CloudLink 及 12 個 allowlist operation。
  7. 供電控制實際呼叫 controlTestMode()
  8. 每次操作都有 commandLogId、operator、target、request、response/error、elapsed、correlationId。
  9. Firmware/Diagnostics 能顯示後續狀態時間軸。
  10. 現有 8 個 OCPP API、FEV API 及一般 Branch Admin 功能無 regression。
  11. 操作紀錄可搜尋、展開並保留 365 天。
  12. FE 在 desktop/mobile 可完整操作,無文字或控制項重疊。

15. 主要風險與控制

風險 控制方式
Fortune 回應慢 vendor-aware response timeout;HTTP API 不同步等待
Vendor 實作偏離 OCPP schema 保存 CALLERROR/raw response;用 capability note 記錄,不放寬任意 action
長時間通知無 uniqueId 每 CP/command 限制單一 active operation,按 CP 與 operation 關聯
敏感 payload 外洩 DB 權限、UI masking、app log 不輸出完整 payload
Engineer 指令誤操作 Role 隔離、controlled catalog、指定高風險 command 單次確認、完整 audit
Modbus 被當成 raw console Branch 與 Charge Point 雙重 allowlist validation
新流程破壞現有 OCPP API 保留既有 endpoints/contracts,以 observer 旁路更新 audit
Capability 判斷過度樂觀 未知預設 UNVERIFIED,必須經 Fortune 實機矩陣後才標 VERIFIED

16. 不在 V1 範圍

  • Branch 韌體或 diagnostics 檔案儲存服務
  • 任意 OCPP action/raw WebSocket frame console
  • 任意 Modbus register/function console
  • Capability 管理 UI
  • 全系統集中式 log 平台
  • CloudLink Charge Point 實作全部 19 個 CSMS command handler
  • 自動把未來 administrator/power_user 成員加入 Engineer Role
    (1-1/1)