# MySQL TaskStore node_executions manual-only xUnit 驗證入口實作紀錄

## 1. 實作目的

本次實作承接 [MySQL TaskStore node_executions manual-only 真實 DB 驗證設計](mysql-taskstore-node-executions-manual-verification-design.md)，新增一個預設不連線、不寫入的 manual-only xUnit 驗證入口。

目標是讓後續使用者明確開啟測試 DB gate 時，可以驗證 `MySqlTaskStore.Save(record)` 是否會同步寫入 `task_executions` 與 `node_executions`，並可查回節點資料列。

## 2. 完成內容

| 項目 | 狀態 | 說明 |
| --- | --- | --- |
| manual-only xUnit 測試類別 | 已完成 | 新增 `MySqlTaskStoreNodeExecutionsManualMySql56Tests`。 |
| gate 保護 | 已完成 | 沿用 `HS_MYSQL_TASKSTORE_ENABLED` 與 `HS_MYSQL_TASKSTORE_ALLOW_WRITE`，未開啟時直接 skip，不連 DB。 |
| schema precheck | 已完成 | 寫入前先透過 `MySqlSchemaInspector` 檢查 `task_executions` 與 `node_executions`。 |
| node table 檢查 | 已完成 | 檢查必要欄位、主鍵、索引與 comment；缺少時停止，不執行寫入。 |
| schema precheck internal helper | 已完成 | 將 node table 停止線抽成 `MySqlTaskStoreNodeExecutionSchemaPrecheck`，讓 manual test 與單元測試共用同一套規則。 |
| schema precheck 單元測試 | 已完成 | 補上缺表、缺欄位、缺 comment、缺 PK、缺 index 與通過情境測試，不需要連真實 DB。 |
| 測試資料 | 已完成 | 建立含兩筆 `NodeRecords` 的 manual task，覆蓋成功與失敗節點欄位。 |
| node 查詢 helper | 已完成 | 測試內部直接查詢 `node_executions`，不擴大 `ITaskStore` public contract。 |
| cleanup | 已完成 | 若 cleanup 開啟，先刪 `node_executions`，再刪 `task_executions`，且只針對本次 manual task id。 |

## 3. 新增測試

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

| 測試 | 目的 |
| --- | --- |
| `SaveAndInspectNodes_ShouldPersistNodeExecutionsWhenManualGateIsEnabled` | gate 開啟後執行 schema precheck、Save、node row 查詢、FindById / ListRecent 與 cleanup。 |
| `ManualGate_ShouldSkipNodeExecutionWriteWhenDisabled` | 驗證 gate 未開時不會允許寫入。 |
| `Validate_ShouldFailWhenNodeExecutionsTableIsMissing` | 驗證缺少 `node_executions` 時會停止，不進入寫入。 |
| `Validate_ShouldFailWhenRequiredNodeColumnIsMissing` | 驗證缺少必要欄位時會停止。 |
| `Validate_ShouldFailWhenRequiredNodeColumnCommentIsMissing` | 驗證缺少欄位 comment 時會停止。 |
| `Validate_ShouldFailWhenPrimaryKeyDoesNotIncludeSequenceNo` | 驗證主鍵缺少 `sequence_no` 時會停止。 |
| `Validate_ShouldFailWhenRequiredIndexIsMissing` | 驗證缺少必要索引時會停止。 |
| `Validate_ShouldFailWhenNodeTableCommentIsMissing` | 驗證缺少 table comment 時會停止。 |
| `Validate_ShouldPassWhenTaskAndNodeTablesMatch` | 驗證 schema 符合時可通過 precheck。 |

## 4. 安全邊界

- 不執行 `CREATE TABLE` / `ALTER TABLE` / `DROP TABLE`。
- 不自動建立 `node_executions`。
- 不修改 `ITaskStore` public method。
- 不讓 `FindById` / `ListRecent` 回填 `NodeRecords`。
- 不寫入正式 DB。
- 不輸出 password 或完整 connection string。
- 缺表、缺欄位、缺索引或缺 comment 時，只回報並停止。

## 5. 驗證方式

本次只驗證一般測試路徑與 gate skip 行為。

```powershell
dotnet test tests\HS.DeviceControl.Infrastructure.MySql.Tests\HS.DeviceControl.Infrastructure.MySql.Tests.csproj
```

結果：

- MySQL Infrastructure 測試通過：59 passed。
- 全專案 `dotnet test` 通過：391 passed。
- 新增 manual-only 測試在 gate 未開時不連線、不寫入。
- 新增 schema precheck 單元測試，可在不連 DB 的情況下證明缺表、缺欄位、缺 index、缺 comment 與 PK 不符會被擋下。
- 尚未執行真實 DB 寫入 / 查詢驗證。

## 6. 後續真實 DB 驗證指令

使用者確認測試 DB 已有 `task_executions` 與 `node_executions` 後，才可手動設定環境變數並執行：

```powershell
dotnet test tests\HS.DeviceControl.Infrastructure.MySql.Tests\HS.DeviceControl.Infrastructure.MySql.Tests.csproj --filter FullyQualifiedName~MySqlTaskStoreNodeExecutionsManualMySql56Tests --logger "console;verbosity=detailed"
```

必要 gate：

```text
HS_MYSQL_TASKSTORE_ENABLED=true
HS_MYSQL_TASKSTORE_ALLOW_WRITE=true
```

仍需由使用者在本機設定 host、port、database、user、password、timeout、ssl mode 與 cleanup。密碼不得寫入 repo。

## 7. 目前結論

`node_executions` 已具備 fake gateway 寫入測試、manual-only 真實 DB 驗證入口，以及不連 DB 的 schema precheck 停止線測試。下一步應在使用者確認測試 DB table、index、comment 與 gate 後，執行真實 DB manual-only 驗證並整理驗證紀錄。
