Feature #1397 » redmine-1397-liff-manual-e2e-test-plan-zh-TW.md
Redmine #1397/#1398/#1399 LIFF 人工 E2E 測試計畫
版本:2026-07-31 初版
執行狀態:等待 #1399 Frontend 完成並部署後執行
測試環境:Ken 的 Branch/Charge Point、docker1 HQ staging、#1399 LIFF 測試版
測試起點:所有產品操作都必須從 LIFF Connector 列表或詳細頁開始
1. 目的與通過標準
本計畫驗證 #1397 定義的新版 driverState、semantic actions、RemoteStart/RemoteStop
operation lifecycle、WebSocket initial snapshot,以及私樁長期離峰與排隊行為。API、DB
與 log 只用來佐證 LIFF 操作的真實結果,不可取代 LIFF 畫面與實體充電行為。
整輪測試通過必須同時符合:
- 適用的 P0 案例全部通過;Skip 不是 Pass。
- LIFF 顯示的狀態、按鈕、modal 與 Backend 真實 operation/transaction 一致。
- 實際開始與停止案例必須看到繼電器/電流變化、OCPP transaction 與 DB 收斂。
- 公樁與私樁都完成測試;不能只用 API response 推定另一種樁型也正確。
- 每個案例都留下時間、Connector ID、畫面、WebSocket/API、Branch/CP log 與 DB 證據。
- 測試完成後,兩支 Connector 必須還原成測試前的公私樁、tariff、Charge Group 與離峰設定。
2. Ken 環境基線
2026-07-31 查核到的初始資料如下。正式執行前仍要重查一次,若不同,以當天快照為準。
| 項目 | CP001-001 | CP001-002 |
|---|---|---|
| 廠牌 | CLOUDLINK | CLOUDLINK |
| Branch status | AVAILABLE | AVAILABLE |
| Branch area | public | public |
| CP area | public | public |
| Charge Group | NULL | NULL |
| Connector tariff | 未綁定 | 未綁定 |
| enableOffPeak | NULL | NULL |
| active transaction | 無 | 無 |
| LIFF 測試使用者關聯 | 已關聯 | 已關聯 |
環境路徑:
| 層級 | 環境 |
|---|---|
| LIFF | #1399 完成後由 Ryan 提供實際測試 URL/LIFF channel;執行紀錄必須填入版本或 commit |
| HQ | docker1 staging,ems-hq-staging-api,對外由 hq-api.sylksoft.com 提供 API/WebSocket |
| Branch | Ken 主機,ems-branch-api,host port 18081/OCPP 18082
|
| Charge Point | Ken 主機,ems-cp-api,實體 Connector 為 CP001-001、CP001-002
|
| Branch DB | Ken 主機 MySQL container 的 ems_branch
|
3. 人員、帳號與設備
3.1 必要角色
- Tester A:Ken 的 LINE/LIFF 測試帳號;必須可進入測試 building,並對
CP001-002
對應到 Branch userU2601140001。該 Branch user 已有有效 IdTag。 - Tester B:第二個 LINE/LIFF 帳號,只用於「指定使用者 operationResult」與公/私樁停止授權案例。
執行前必須在 HQ 建立相同 building binding,Branch 建立另一位有效 IdTag user,並將其關聯到
私樁CP001-002。不得共用 Tester A 的 LINE identity。 - BE observer:觀察 HQ/Branch/CP log、DB 與實體設備;不得代替 Tester 在 API 工具直接發動產品操作。
- FE observer:確認 LIFF action mapping、modal、WebSocket reconnect 與 operationId 去重。
若 Tester B 尚未準備完成,標記 M1397-014、M1397-015 為 Blocked,不得填 Pass。
3.2 實體設備
- 一台可正常 AC 充電的測試車,或等效且能產生真實 StartTransaction、MeterValues、StopTransaction 的負載。
-
CP001-001、CP001-002的槍線均可使用。 - 可觀察 Relay/電流的 CP log 或實體量測方式。
- 兩支手機;測 targeted result 時兩個 LIFF session 要同時停留在同一 Connector 詳細頁。
4. 測試前安全檢查
先在 Ken 主機進入 MySQL:
sudo docker exec -it mysql mysql -uroot -p ems_branch
密碼只從既有安全設定取得,不可寫入測試報告、截圖或 Redmine。
4.1 留存基線快照
SELECT id, connector_type, status, area, enable_off_peak,
off_peak_enabled_by_user_id, off_peak_suppressed_window_start,
off_peak_suppressed_window_end, off_peak_suppression_reason,
charge_group, current_transaction_id
FROM e_connectors
WHERE id IN ('CP001-001', 'CP001-002');
SELECT id, status, area, current_transaction_id, relay_status
FROM cp_connectors
WHERE id IN ('CP001-001', 'CP001-002');
SELECT id, tariff_id
FROM e_connector_tariff
WHERE id IN ('CP001-001', 'CP001-002');
SELECT connector_id, user_id
FROM e_connector_user
WHERE connector_id IN ('CP001-001', 'CP001-002')
ORDER BY connector_id, user_id;
將查詢結果貼入本次 Test Run report。不要只依本文件的 2026-07-31 基線還原,因為正式測試日的資料可能已改變。
4.2 確認沒有進行中的工作
SELECT transaction_id, connector_id, id_tag, status, start_timestamp
FROM e_transactions
WHERE connector_id IN ('CP001-001', 'CP001-002')
AND status = 'ACTIVE';
SELECT id, operation_type, source, connector_id, requested_by_user_id,
operation_status, deadline_at, grace_until
FROM e_remote_transaction_log
WHERE connector_id IN ('CP001-001', 'CP001-002')
AND operation_status IN ('SENT', 'ACCEPTED');
SELECT id, connector_id, source, requested_by_user_id, charge_group,
priority, charge_status, status_reason
FROM e_connector_priority
WHERE connector_id IN ('CP001-001', 'CP001-002');
通過條件:ACTIVE transaction、SENT/ACCEPTED operation 與既有 queue 都為空。
若不是空,不得直接刪除 operation 或 transaction;先查明是否仍在供電並正常停止/收斂。
4.3 確認服務與時間
date
sudo docker ps --format '{{.Names}} {{.Status}} {{.Ports}}'
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18081/api-docs
HQ、Branch、CP、手機時間差不得超過一分鐘,否則 operation deadline 與 log 對帳會混亂。
5. 建立專用測試資料
以下 fixture 讓兩支實體樁切換出三種模式:
| 模式 | CP001-001 | CP001-002 | 用途 |
|---|---|---|---|
| PUB | public | public | 公樁 LIFF、Start/Stop、無離峰 switch |
| PRI-0 | public,同 group | private,同 group | group 總 slot=1,扣除一支 public 後 private slot=0;測 MANUAL/OFF_PEAK QUEUED |
| PRI-1 | public,同 group | private,同 group | group 總 slot=2,扣除一支 public 後 private slot=1;測私樁實際 Start/Stop/離峰充電 |
5.1 建立 test-only Charge Group 與 tariffs
只在 4.2 全部為空後執行:
INSERT INTO e_charge_group
(id, contract_capacity, allocated_power, rotation_cycle_active, reserved_slots)
VALUES
('CG_E2E_1397', 7.00, 7.00, 0, 0)
ON DUPLICATE KEY UPDATE
contract_capacity = VALUES(contract_capacity),
allocated_power = VALUES(allocated_power),
rotation_cycle_active = 0,
reserved_slots = 0;
INSERT INTO e_tariff_table
(id, mode, name, connector_area, start_date, end_date,
currency, enabled, version_no, is_template, editable)
VALUES
('E2E1397WAIT', 'RLT', 'E2E #1397 非當前離峰', 'private',
'2026-01-01', '2099-12-31', 'TWD', 1, 1, 0, 1),
('E2E1397ACTIVE', 'RLT', 'E2E #1397 全日離峰', 'private',
'2026-01-01', '2099-12-31', 'TWD', 1, 1, 0, 1)
ON DUPLICATE KEY UPDATE
enabled = 1,
connector_area = 'private',
start_date = '2026-01-01',
end_date = '2099-12-31';
DELETE FROM e_tariff_time_slot
WHERE tariff_id IN ('E2E1397WAIT', 'E2E1397ACTIVE');
INSERT INTO e_tariff_time_slot
(id, tariff_id, season_type, day_type, slot_type,
start_time, end_time, unit_price, sequence_no, cross_day,
create_time, update_time)
VALUES
('E2E1397WAIT01', 'E2E1397WAIT', 'ALL', 'ALL', 'OFF_PEAK',
'00:00:00', '00:01:00', 1.0000, 1, 0, NOW(), NOW()),
('E2E1397ACTIVE01', 'E2E1397ACTIVE', 'ALL', 'ALL', 'OFF_PEAK',
'00:00:00', '23:59:59', 1.0000, 1, 0, NOW(), NOW());
E2E1397WAIT 用來穩定製造「長期離峰已開啟、目前不在離峰 window」;除非測試剛好在
00:00~00:01 執行。E2E1397ACTIVE 用來讓任何測試時間都處於離峰 window。
5.2 切換 PUB 模式
UPDATE e_connectors
SET area = 'public', enable_off_peak = NULL,
off_peak_enabled_by_user_id = NULL,
off_peak_suppressed_window_start = NULL,
off_peak_suppressed_window_end = NULL,
off_peak_suppression_reason = NULL,
charge_group = NULL
WHERE id IN ('CP001-001', 'CP001-002');
UPDATE cp_connectors
SET area = 'public'
WHERE id IN ('CP001-001', 'CP001-002');
DELETE FROM e_connector_priority
WHERE connector_id IN ('CP001-001', 'CP001-002');
變更後關閉舊詳細頁,再由 LIFF 列表重新進入,讓 WebSocket initial snapshot 讀取最新資料。
5.3 切換 PRI-0 模式(private slot=0)
UPDATE e_charge_group
SET contract_capacity = 7.00, allocated_power = 7.00,
reserved_slots = 0, rotation_cycle_active = 0
WHERE id = 'CG_E2E_1397';
UPDATE e_connectors
SET area = 'public', enable_off_peak = NULL, charge_group = 'CG_E2E_1397'
WHERE id = 'CP001-001';
UPDATE e_connectors
SET area = 'private', enable_off_peak = 0,
off_peak_enabled_by_user_id = NULL,
off_peak_suppressed_window_start = NULL,
off_peak_suppressed_window_end = NULL,
off_peak_suppression_reason = NULL,
charge_group = 'CG_E2E_1397'
WHERE id = 'CP001-002';
UPDATE cp_connectors SET area = 'public' WHERE id = 'CP001-001';
UPDATE cp_connectors SET area = 'private' WHERE id = 'CP001-002';
INSERT INTO e_connector_tariff (id, tariff_id)
VALUES ('CP001-002', 'E2E1397WAIT')
ON DUPLICATE KEY UPDATE tariff_id = VALUES(tariff_id);
DELETE FROM e_connector_priority
WHERE connector_id IN ('CP001-001', 'CP001-002');
此時 floor(7/7)=1,再扣除同 group 的一支 public connector,private 可用 slot 為 0。
5.4 切換 PRI-1 模式(private slot=1)
UPDATE e_charge_group
SET contract_capacity = 14.00, allocated_power = 7.00,
reserved_slots = 0, rotation_cycle_active = 0
WHERE id = 'CG_E2E_1397';
此時 floor(14/7)=2,扣除一支 public connector 後,剩一個 private slot。
5.5 切換 private tariff
不在離峰 window:
UPDATE e_connector_tariff
SET tariff_id = 'E2E1397WAIT'
WHERE id = 'CP001-002';
強制處於離峰 window:
UPDATE e_connector_tariff
SET tariff_id = 'E2E1397ACTIVE'
WHERE id = 'CP001-002';
每次切換 tariff 後,關閉 Connector 詳細頁,再由 LIFF 列表重新進入。
6. 執行證據規則
每個案例至少記錄:
- LIFF 操作開始/結束時間與 Tester A/B。
- Connector ID、當時模式 PUB/PRI-0/PRI-1、車輛是否插槍。
- 操作前畫面、等待狀態、結果 modal、操作後畫面。
- command HTTP status/body;涉及非同步操作時記錄
operationId。 - WebSocket initial snapshot 與後續 UPDATED/operationResult 的關鍵欄位。
-
e_remote_transaction_log、e_connector_priority、e_transactions的對應資料。 - 實際 Relay/電流與 OCPP RemoteStart/StartTransaction/RemoteStop/StopTransaction。
結果只能填 PASS、FAIL、BLOCKED、NOT APPLICABLE。不得把沒有執行寫成 PASS。
7. 公樁案例(PUB)
M1397-001:詳細頁只靠 WebSocket initial snapshot
對應:UI-001、UI-002、UI-010、CHG-025。
- 套用 PUB 模式,確認兩樁 AVAILABLE、無 transaction/operation/queue。
- Tester A 從 LIFF 充電樁列表進入
CP001-001詳細頁。 - 用 FE debug log/Network 確認只建立 Connector WebSocket;不得另外呼叫 Connector detail REST API。
- 確認第一份 snapshot 為目前 Connector 資料,不是舊 cache。
預期:
-
areaType=public、rawstatus=AVAILABLE、driverState.code=READY。 - title/description 表示可開始充電,主要 action 為
START_CHARGING/「開始充電」。 -
activeOperation=null。 - 公樁不顯示離峰 switch。
- 列表與詳細頁的狀態一致。
M1397-002:CloudLink 先插槍、尚未按開始
對應:CHG-001、UI-002。
- Tester A 先把車插到
CP001-001,不要按 LIFF 開始。 - 等待設備狀態穩定後,由 LIFF 列表重新進入詳細頁。
- 記錄 raw OCPP status 與 LIFF driverState。
預期:即使設備因插槍回報與待命相關的 raw status,沒有未完成 RemoteStart operation 時,
LIFF 仍顯示 READY/「開始充電」,不得誤顯示「準備中」。
M1397-003:公樁 RemoteStart lifecycle
對應:CHG-001、CHG-020、CHG-029、CHG-032、CHG-034。
- 承 M1397-002,Tester A 按「開始充電」。
- 若有確認 modal,確認開始。
- 按下後立即觀察按鈕、title 與 description,直到開始充電。
- 持續至少一個 MeterValues 上傳週期。
預期:
- command 回 HTTP 202,含新的
operationId。 - LIFF 先進入
PREPARING/「準備中」,不能重複開始。 -
activeOperation.operationId與 response、DBe_remote_transaction_log.id相同。 - 收到 StartTransaction 後轉
CHARGING,主要 action 改為STOP_CHARGING/「停止充電」。 - 只有一筆 ACTIVE transaction;Relay 開啟且有合理電流/MeterValues。
- terminal success operationResult 只顯示一次,不因後續 UPDATED event 重複彈出。
M1397-004:公樁 RemoteStop lifecycle
對應:CHG-001、CHG-020、CHG-029、CHG-032、CHG-034。
- 承 M1397-003,由啟動交易的 Tester A 按「停止充電」並確認。
- 立即觀察狀態,直到實體停止。
預期:
- command 回 HTTP 202,取得 STOP
operationId。 - LIFF 先進入
FINISHING/「停止中」,Start/Stop 都不可重複執行。 - 收到 StopTransaction 後,Relay 關閉、transaction 轉 COMPLETED。
- Connector 回到
READY;停止成功 modal 只顯示一次。
M1397-005:CloudLink PREPARING 取消啟動
對應:CHG-007、CHG-034。
- 車輛先不要建立充電需求,從 READY 按「開始充電」。
- LIFF 顯示 PREPARING 後,在 StartTransaction 前按「取消啟動」並確認。
- 觀察 operation、Relay 與後續 60 秒狀態。
預期:
- action code 為
CANCEL_START,不是依按鈕文字猜 command。 - 取消成功後 START operation 為 CANCELLED,LIFF 回
READY。 - 不建立 ACTIVE transaction,設備不應在取消後又自行開始。
若硬體太快產生 StartTransaction,記錄 Blocked,改用未插車且能進入 waiting mode 的方式重測;
不得把已進入 CHARGING 的停止流程算成取消 PREPARING。
M1397-006:WebSocket 中斷時禁止沿用舊 action
對應:UI-010。
- 在 READY 詳細頁確認「開始充電」可操作。
- 關閉手機網路,或用可控代理只阻斷 Connector WebSocket。
- 斷線後立即點原本位置的「開始充電」。
- 等待 FE 的一次短暫重連失敗,再恢復網路。
預期:
- 斷線後舊
driverState.actions立即不可用,不送出 command。 - 一次短暫重連仍失敗後,退回列表並顯示連線失敗 modal。
- 不以 REST detail 或舊 snapshot 留在可操作狀態。
- 重新進入詳細頁前,DB 不新增 RemoteStart operation。
8. 私樁排隊與離峰案例(PRI-0)
M1397-007:私樁畫面與手動零 slot 排隊
對應:CHG-037、ROT-004、UI-002。
- 套用 PRI-0,tariff 使用
E2E1397WAIT,off-peak 保持 OFF。 - Tester A 從列表進入
CP001-002。 - 確認顯示離峰 switch,driverState 為 READY。
- 按「開始充電」。
預期:
- private area 顯示離峰 switch。
- 因 private slot=0,command 同步回 HTTP 200,不建立 RemoteStart operation。
- 建立
source=MANUAL、requestedByUserId=Tester A Branch user的 Priority。 - driverState 轉
QUEUED,主要操作顯示「取消排隊」,action 為CANCEL_MANUAL_START。 - 點「取消排隊」後只刪除 MANUAL queue,回 READY;不改變 off-peak switch。
M1397-008:開啟長期離峰立即 OFF_PEAK_WAITING
對應:ROT-001、ROT-021。
- 確認沒有 MANUAL queue,tariff 使用
E2E1397WAIT。 - Tester A 將離峰 switch 切成 ON,完成 FE 確認。
- API 成功後立即觀察畫面與 DB,不等待 scheduler。
預期:
- command 為
ENABLE_OFF_PEAK,HTTP 200。 -
enableOffPeak=true,啟用者為 Tester A。 - driverState 立即為
OFF_PEAK_WAITING;主要操作顯示「取消排隊」。 - 因目前不在 OFF_PEAK window,
e_connector_priority尚未建立。 - 「取消排隊」與 switch OFF 都送
DISABLE_OFF_PEAK;成功後回 READY,清除 off-peak actor。
M1397-009:進入離峰 window 後轉 QUEUED
對應:ROT-001、ROT-004、ROT-021。
- tariff 改為
E2E1397ACTIVE,保持 PRI-0。 - 從 LIFF 將離峰切為 ON。
- 先確認立即回 OFF_PEAK_WAITING。
- 等待最多 10 分鐘的正常 off-peak scheduler;為縮短人工測試,可由 BE 呼叫既有維運 enqueue endpoint,
但 Tester 的產品操作仍必須是 LIFF switch ON。 - 觀察 WebSocket 更新。
預期:
- scheduler 建立
source=OFF_PEAK、requester=啟用者的 Priority。 - driverState 由 OFF_PEAK_WAITING 轉 QUEUED,操作仍是「取消排隊」。
- private slot=0,不 dispatch RemoteStart,不出現幽靈 PREPARING。
- 取消後關閉長期離峰並刪除 OFF_PEAK queue;不得刪除其他來源 queue。
9. 私樁實際充電案例(PRI-1)
M1397-010:私樁手動 Start/Stop
對應:CHG-005、CHG-020、CHG-029、CHG-034、ROT-002。
- 先將 off-peak 關閉並清空 queue,切換 PRI-1。
- Tester A 插槍後從 LIFF 按「開始充電」。
- 觀察 READY → PREPARING → CHARGING 與實際供電。
- 再按「停止充電」,觀察 CHARGING → FINISHING → READY。
預期與 M1397-003/004 相同,另須確認 private slot 有效、沒有先建立 MANUAL queue,
且整個 transaction 的 area 為 private。
M1397-011:離峰自動開始、停止後抑制本 window
對應:ROT-008、ROT-021、ROT-022、CHG-034。
- PRI-1、tariff=
E2E1397ACTIVE,車輛插在CP001-002,off-peak 起始為 OFF。 - Tester A 從 LIFF 開啟離峰。
- 等待正常 scheduler enqueue/dispatch;必要時 BE 只觸發既有 enqueue 與 rotation tick。
- 觀察 OFF_PEAK_WAITING → QUEUED → PREPARING → CHARGING。
- CHARGING 時嘗試操作離峰 switch。
- 按「停止充電」,閱讀 modal 後確認。
- StopTransaction 完成後,至少跨兩次 scheduler cycle 觀察是否重啟。
- 再將 off-peak OFF,然後 ON,確認可重新加入本 window。
預期:
- CHARGING 時 FE 不允許關閉 off-peak switch。
- 停止 modal 清楚告知:會停止目前充電、本 window 不再自動啟動、長期偏好仍保持。
- StopTransaction 後
enableOffPeak=true,driverState=OFF_PEAK_WAITING,
reason=USER_CANCELLED_FOR_CURRENT_WINDOW。 - suppression window 持久化;同一 window scheduler 不得重新 dispatch。
- OFF → ON 明確重設 suppression 後,才可重新 OFF_PEAK_WAITING/QUEUED/dispatch。
M1397-012:離峰 transaction 非使用者停止而結束
對應:CHG-003、ROT-003、ROT-022。
- 重新建立一筆離峰 CHARGING transaction。
- 不按 LIFF 停止,改用拔槍或讓設備產生真實 StopTransaction。
- 觀察 LIFF、DB 與後續 scheduler。
預期:
- 不猜測滿電或拔槍,不顯示「已充滿」或「槍未正確連接」。
-
enableOffPeak=true,driverState=OFF_PEAK_WAITING,
reason=TRANSACTION_ENDED_FOR_CURRENT_WINDOW。 - 本 window 不再自動開始;下一個獨立 window 才恢復排程。
M1397-013:RemoteStart/RemoteStop timeout 與一次性失敗提示
對應:CHG-009、CHG-018、CHG-032、CHG-034、CHG-035。
RemoteStart:
- PRI-1、off-peak OFF,使用不會建立充電需求的狀態,從 LIFF 按開始。
- 記錄 operationId,等待 CloudLink 既有 RemoteStart deadline 加 30 秒 reconciliation grace。
- 不重複按開始。
預期:PREPARING 期間不盲目重送;最終 timeout result 只顯示一次,手動來源回 READY。
若 grace 後才收到 StartTransaction,實際 transaction 優先轉 CHARGING,但不重播 timeout modal。
RemoteStop:
- 在可控制的測試 transaction 中暫時製造 StopTransaction 不回或晚回。
- 從 LIFF 按停止,等待 30 秒 deadline。
預期:30 秒內 FINISHING;deadline 時 transaction 仍 ACTIVE 則顯示一次停止失敗並回 CHARGING,
允許新的明確停止。晚到 StopTransaction 仍完成 transaction reconciliation,但不重播舊 modal。
本案例需要 BE/CP observer 可安全製造 timeout;若無法控制,標記 Blocked,不得用單元測試代替。
10. 多使用者與重啟案例
M1397-014:operationResult 只送給發起者
對應:CHG-035。
- Tester A、B 同時開啟同一支 private
CP001-002詳細頁。 - Tester A 從 LIFF 發起 Start 或 Stop,製造一個 terminal success/failure result。
- 同時錄製兩支手機畫面與 WebSocket event。
預期:A、B 都收到共用 driverState UPDATED;只有 A 收到該 operationResult modal。
兩邊都不得看到 browser payload 中暴露另一人的 Branch user identity。
M1397-015:PUBLIC/PRIVATE 停止授權差異
對應:CHG-020、CHG-021、CHG-036。
PUBLIC:
- PUB 模式,由 Tester A 啟動
CP001-002。 - Tester B 開啟同樁並嘗試停止。
預期:B 可看到共用 CHARGING presentation,但 API 回 403
TRANSACTION_OWNED_BY_OTHER_USER;不 dispatch RemoteStop,設備繼續充電。最後由 A 正常停止。
PRIVATE:
- PRI-1 模式,確認 A、B 都是目前關聯住戶。
- 由 A 啟動
CP001-002,再由 B 停止。
預期:B 可以停止;原 transaction owner 不變,但 operation audit 的 stop requester 為 B。
M1397-016:重啟恢復與 terminal result 不重播
對應:CHG-034、CHG-035、UI-010、REL-004。
- 從 LIFF 建立可維持數秒以上的 PREPARING 或 FINISHING,記錄 operationId。
- BE observer 依 Ken 環境 SOP 重啟
ems-branch-api。 - 服務恢復後,Tester 重新連入詳細頁。
- 完成該 operation,關閉頁面再重新進入。
預期:
- 重啟後 initial snapshot 從持久化 operation 還原 PREPARING/FINISHING 與相同 operationId。
- 重啟不建立第二筆 operation、不重複送 Start/Stop。
- operation 終結後重新開頁,initial snapshot 不重播 terminal operationResult。
- 仍生效的問題只由目前 driverState reason/description 表達。
11. 每案 DB/log 對帳
11.1 DB 查詢
SELECT id, operation_type, source, requested_by_user_id, connector_id,
transaction_id, request_time, accepted_at, deadline_at, grace_until,
completed_at, status, operation_status, failure_code, remark
FROM e_remote_transaction_log
WHERE connector_id = 'CP001-002'
ORDER BY id DESC
LIMIT 10;
SELECT id, connector_id, source, requested_by_user_id, charge_group,
priority, start_charging_time, charge_status, status_reason,
create_time, update_time
FROM e_connector_priority
WHERE connector_id = 'CP001-002'
ORDER BY create_time DESC;
SELECT transaction_id, connector_id, id_tag, start_timestamp, stop_timestamp,
meter_start, meter_stop, reason, status, energy_consumed
FROM e_transactions
WHERE connector_id = 'CP001-002'
ORDER BY transaction_id DESC
LIMIT 10;
SELECT id, area, enable_off_peak, off_peak_enabled_by_user_id,
off_peak_suppressed_window_start, off_peak_suppressed_window_end,
off_peak_suppression_reason, charge_group, current_transaction_id
FROM e_connectors
WHERE id = 'CP001-002';
11.2 log 位置
- Branch:
/opt/ems/ems_branch/api/logs/ - Charge Point:
/opt/ems/ems_cp/api/logs/ - HQ staging:docker1 的
ems-hq-staging-apicontainer log
每個 operationId 要能串起 LIFF command、HQ、Branch Remote operation、OCPP command 與 transaction。
12. 測後還原
- 從 LIFF 正常停止所有 transaction,等兩樁 AVAILABLE、Relay OFF。
- 若 private off-peak 仍為 ON,先從 LIFF 切 OFF,確認 queue 清除。
- 依 4.1 當天留下的基線還原兩樁;若當天基線仍是 2026-07-31 狀態,可執行:
DELETE FROM e_connector_priority
WHERE connector_id IN ('CP001-001', 'CP001-002');
DELETE FROM e_connector_tariff
WHERE id IN ('CP001-001', 'CP001-002');
UPDATE e_connectors
SET area = 'public', enable_off_peak = NULL,
off_peak_enabled_by_user_id = NULL,
off_peak_suppressed_window_start = NULL,
off_peak_suppressed_window_end = NULL,
off_peak_suppression_reason = NULL,
charge_group = NULL
WHERE id IN ('CP001-001', 'CP001-002');
UPDATE cp_connectors
SET area = 'public'
WHERE id IN ('CP001-001', 'CP001-002');
DELETE FROM e_tariff_time_slot
WHERE tariff_id IN ('E2E1397WAIT', 'E2E1397ACTIVE');
DELETE FROM e_tariff_table
WHERE id IN ('E2E1397WAIT', 'E2E1397ACTIVE');
DELETE FROM e_charge_group
WHERE id = 'CG_E2E_1397';
- 重跑 4.1、4.2 查詢,確認與基線一致。
- 從 LIFF 重新進入兩樁詳細頁,確認皆為 public、READY、不顯示離峰 switch。
不得刪除 e_remote_transaction_log、e_transactions 或 OCPP log;它們是本輪 E2E 證據。
13. Test Run 報告要求
正式執行時另建 test_report/YYYYMMDD_NNN_redmine_1397_liff_manual_e2e.md,逐案填:
- Test case ID/Catalog case ID。
- 實際前置資料與 fixture mode。
- LIFF 完整操作步驟。
- Expected/Actual 畫面與狀態轉換。
- API status/body、WebSocket event、operationId。
- DB/log/實體 Relay 與電流證據。
- PASS/FAIL/BLOCKED 與 defect ticket。
- 清理與還原結果。
本計畫是待執行步驟,不得預先填寫 PASS。