# MySQL TaskStore node_executions manual-only 真實 DB 驗證設計

## 1. 文件目的

本文件設計 `MySqlTaskStore` 將 `TaskExecutionRecord.NodeRecords` 寫入真實 MySQL 5.6.2 測試資料庫的 manual-only 驗證方式。

本文件只整理驗證節點、前置資料、環境 gate、測試資料、通過條件與停止線，不直接連線資料庫、不執行 DDL、不寫入正式 DB。

## 2. 驗證節點名稱

```text
MySQL TaskStore node_executions manual-only Save / Inspect
```

## 3. 驗證目的

確認 `HS.DeviceControl.Infrastructure.MySql` 目前的 `node_executions` 第一版實作，在使用者明確開啟 manual-only gate 後，可以：

- 對 `task_executions` 寫入任務摘要。
- 對 `node_executions` 先刪除同 task id 的舊節點紀錄，再依 `NodeRecords` 順序寫入新節點紀錄。
- 確認 `node_executions` 的主鍵、欄位、索引與 comment 符合目前 C# schema class。
- 確認節點欄位可保留 `NodeId`、`NodeName`、`DeviceId`、`CommandName`、`Status`、`RetryCount`、`TimeTakenMs`、`ErrorCode`、`NextNodeId` 與 summary 欄位。
- 驗證 cleanup 只清除本次測試 task id 的 `task_executions` 與 `node_executions` 資料。
- 驗證輸出不暴露 password 或完整 connection string。

## 4. 本節點不做的事

| 項目 | 原因 |
| --- | --- |
| 建立 database | 目前只驗證 TaskStore，不做 DB provisioning。 |
| 自動建立 `node_executions` | Schema Apply / DDL Executor 尚未確認。 |
| 執行 `CREATE TABLE` / `ALTER TABLE` / `DROP` | 避免影響真實 DB 結構。 |
| 寫入正式 DB | 第一版只允許測試 DB。 |
| 修改 `ITaskStore` public contract | 驗證資料可用 internal / test helper 讀取，不把查詢節點明細升成正式契約。 |
| 讓 `FindById` / `ListRecent` 回填 `NodeRecords` | 這是後續正式查詢設計，不塞進 manual-only 驗證。 |
| 驗證 `command_executions` 或詳細 log table | 兩者資料來源與邊界尚未確認。 |

## 5. 驗證前需要使用者確認

| 欄位 | 建議值 | 是否可寫入 repo | 備註 |
| --- | --- | --- | --- |
| MySQL 版本 | `5.6.2` | 可寫入 | 已知目標版本。 |
| Host / IP | `<masked>` | 不寫完整值 | 不在文件保留完整 IP。 |
| Port | `3306` | 可寫入 | 非敏感資訊。 |
| Database name | `hs_device_control_test` | 可寫入 | 必須是測試 DB。 |
| User name | `hs_device` | 可寫入或遮蔽 | 建議只給測試 DB 權限。 |
| Password | 不提供範例 | 不可寫入 | 只能由本機環境變數提供。 |
| Required tables | `task_executions`, `node_executions` | 可寫入 | 兩張表都必須已存在。 |
| 是否驗證 index | `true` | 可寫入 | 使用 `information_schema.STATISTICS` 驗證。 |
| 是否驗證 comment | `true` | 可寫入 | 使用 table / column comment 驗證。 |
| 是否允許 INSERT / UPDATE / DELETE | `true` | 可寫入 | 必須由使用者明確確認。 |

## 6. 前置 schema 檢查

在執行寫入前，驗證流程必須先確認真實測試 DB 已具備必要 schema。

必要資料表：

```text
task_executions
node_executions
```

`node_executions` 必要重點：

| 類別 | 內容 |
| --- | --- |
| 主鍵 | `task_id`, `sequence_no` |
| 必填欄位 | `task_id`, `sequence_no`, `node_id`, `status`, `retry_count`, `started_at`, `time_taken_ms`, `created_at` |
| 主要索引 | `idx_node_executions_task_id`, `idx_node_executions_status`, `idx_node_executions_device`, `idx_node_executions_node_id` |
| comment | table comment 與主要 column comment 需存在 |

若缺少 `node_executions`、欄位、主鍵、索引或 comment，驗證節點應停止並回報缺口，不得自動建立或修改資料表。

## 7. 建議環境變數

沿用既有 MySQL TaskStore manual-only gate：

```text
HS_MYSQL_TASKSTORE_ENABLED
HS_MYSQL_TASKSTORE_ALLOW_WRITE
HS_MYSQL_TASKSTORE_HOST
HS_MYSQL_TASKSTORE_PORT
HS_MYSQL_TASKSTORE_DATABASE
HS_MYSQL_TASKSTORE_USER
HS_MYSQL_TASKSTORE_PASSWORD
HS_MYSQL_TASKSTORE_TABLE
HS_MYSQL_TASKSTORE_TIMEOUT_SECONDS
HS_MYSQL_TASKSTORE_SSL_MODE
HS_MYSQL_TASKSTORE_CLEANUP
```

補充規則：

- `HS_MYSQL_TASKSTORE_ENABLED=true` 才可連 DB。
- `HS_MYSQL_TASKSTORE_ALLOW_WRITE=true` 才可寫入。
- `HS_MYSQL_TASKSTORE_TABLE` 仍只代表 `task_executions`。
- `node_executions` 第一版固定使用同名資料表，不新增 table name 設定，避免測試與 schema class 脫節。
- `HS_MYSQL_TASKSTORE_PASSWORD` 不得寫入 repo、文件或測試輸出。

若要同時跑 schema metadata 檢查，可搭配既有 Inspector 環境變數：

```text
HS_MYSQL_INSPECT_ENABLED=true
HS_MYSQL_INSPECT_EXPECTED_TABLES=task_executions,node_executions
HS_MYSQL_INSPECT_INCLUDE_INDEXES=true
HS_MYSQL_INSPECT_INCLUDE_COMMENTS=true
```

## 8. 測試資料設計

測試 task id 必須使用固定前綴：

```text
manual-taskstore-poc-{yyyyMMddHHmmss}-{短隨機碼}
```

建議建立一筆 `TaskExecutionRecord`，至少包含兩筆節點紀錄：

| sequence_no | node_id | status | 用途 |
| --- | --- | --- | --- |
| 1 | `manual-node-1` | `Success` | 驗證成功節點、設備與命令欄位。 |
| 2 | `manual-node-2` | `Failed` 或 `Success` | 驗證錯誤欄位或下一節點欄位。 |

建議欄位值：

| 欄位 | 建議值 |
| --- | --- |
| `workflow_id` | `manual-mysql-taskstore-poc` |
| `device_id` | `manual-device-1` |
| `command_name` | `manual-command-1` |
| `data_summary` | `manual data summary` |
| `metadata_summary` | `manual metadata summary` |
| `transition_summary` | `manual transition summary` |

## 9. 建議驗證流程

1. 使用者確認目標是測試 DB，且可接受寫入與 cleanup。
2. 設定 TaskStore manual-only 環境變數。
3. 先執行 schema inspect，確認 `task_executions` 與 `node_executions` 存在。
4. 若 schema inspect 缺表或缺欄位，停止並回報，不執行寫入。
5. 建立含兩筆以上 `NodeRecords` 的 `TaskExecutionRecord`。
6. 呼叫 `MySqlTaskStore.Save(record)`。
7. 使用 test-only / internal helper 查詢 `node_executions`，確認同一 `task_id` 的資料列數、順序與欄位值。
8. 呼叫 `FindById` / `ListRecent` 確認任務摘要仍可查。
9. 若 cleanup 開啟，先刪除 `node_executions` 同 task id 資料，再刪除 `task_executions` 同 task id 資料。
10. 輸出驗證摘要，後續回填人工驗證紀錄。

## 10. 建議 xUnit 範圍

後續若進入實作，建議新增或擴充 manual-only 測試：

```text
tests/HS.DeviceControl.Infrastructure.MySql.Tests/Tasks/MySqlTaskStoreNodeExecutionsManualMySql56Tests.cs
```

建議測試：

| 測試 | 目的 |
| --- | --- |
| `SaveAndInspectNodes_ShouldPersistNodeExecutionsWhenManualGateIsEnabled` | 寫入含節點紀錄的 task，並查詢 `node_executions` 驗證資料列。 |
| `ManualGate_ShouldSkipNodeExecutionWriteWhenDisabled` | gate 未開時不連 DB、不寫入。 |
| `SchemaPrecheck_ShouldReportMissingNodeExecutionsWithoutWrite` | 缺少 `node_executions` 時停止，不自動 DDL。 |

此測試仍歸類為 manual-only，不放入一般 CI 必跑路徑。

## 11. 通過條件

| 條件 | 判斷 |
| --- | --- |
| gate 正常 | 未開 `ENABLED` 或 `ALLOW_WRITE` 時不連 DB、不寫入。 |
| schema 前置檢查正常 | `task_executions` 與 `node_executions` 存在，必要欄位、索引與 comment 可讀。 |
| Save 成功 | `MySqlTaskStore.Save` 未回傳錯誤。 |
| 節點資料列正確 | `node_executions` 同 task id 的筆數等於 `NodeRecords.Count`。 |
| 順序正確 | `sequence_no` 從 1 開始並符合 `NodeRecords` 順序。 |
| 核心欄位正確 | `node_id`、`status`、`retry_count`、`time_taken_ms`、`device_id`、`command_name` 可對回。 |
| 任務摘要仍可查 | `FindById` 與 `ListRecent` 仍能查回 task summary。 |
| cleanup 安全 | 僅刪除本次 `task_id` 的 `node_executions` 與 `task_executions`。 |
| 無敏感資訊 | 輸出不包含 password 或完整 connection string。 |

## 12. 失敗時需記錄

失敗紀錄至少包含：

- 驗證時間。
- 程式 commit。
- MySQL 版本。
- 遮蔽後的 host / database / user。
- schema precheck 是否通過。
- `Save` 是否成功。
- `node_executions` 查詢是否成功。
- row count 與 expected count。
- cleanup 是否成功。
- error code。
- error message。
- exception type。
- 是否疑似缺表、缺欄位、權限不足或資料型別不符。

不得記錄：

- password。
- 完整 connection string。
- 非本次測試 task id 的資料內容。
- 正式 DB 資料列內容。

## 13. 停止線

遇到以下狀況必須停止並請使用者確認：

1. 需要建立或修改 `node_executions` table。
2. 需要調整欄位型別、索引或 comment。
3. 需要新增或變更 `ITaskStore` public method。
4. 需要讓 `FindById` / `ListRecent` 回填節點明細。
5. 需要連接正式 DB 或保存正式資料。
6. 需要調整 DB 帳號權限。

## 14. 目前結論

`node_executions` 第一版已完成 fake gateway 寫入實作與單元測試，但尚未對真實測試 DB 執行 manual-only 寫入 / 查詢驗證。

已完成 [MySQL TaskStore node_executions manual-only xUnit 驗證入口實作紀錄](mysql-taskstore-node-executions-manual-xunit-implementation-record.md)。

建議下一步在使用者確認測試 DB 已具備 `node_executions` table、index、comment，且明確開啟 manual-only gate 後，執行真實 DB 寫入 / 查詢驗證並整理驗證紀錄。
