# MySQL DB LogWriter / TraceStore manual-only 真實 DB 驗證設計

## 1. 文件目的

本文件承接 [MySQL DB LogWriter / TraceStore 第一版實作紀錄](mysql-db-logwriter-tracestore-implementation-record.md)，設計 `MySqlLogWriter` 對真實 MySQL 5.6.2 測試資料庫執行 `task_log_traces` 寫入、查詢與 cleanup 的 manual-only 驗證節點。

本文件只定義驗證節點、前置資料、環境 gate、測試資料、通過條件與停止線，不直接連線資料庫、不執行 DDL、不修改 `ILogWriter` public contract，也不新增 `TaskTraceStore` public 查詢介面。

## 2. 驗證節點名稱

```text
MySQL DB LogWriter manual-only Write / Inspect / Cleanup
```

## 3. 驗證目的

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

- 透過本機環境變數建立 MySQL 連線。
- 將 `LogEntry` 寫入真實測試 DB 的 `task_log_traces`。
- 驗證 `task_log_traces` 的欄位、索引與 comment 符合 C# schema class。
- 查詢剛寫入的 trace，確認 Task、Node、Device、Command、Status、Error 與 summary 欄位可對回。
- 驗證 password、token、secret、authorization、connection string 類型內容會被遮蔽。
- 驗證 cleanup 只刪除本次 manual 測試 trace，不清除其他資料。
- 驗證輸出不暴露 password 或完整 connection string。

## 4. 本節點不做的事

| 項目 | 原因 |
| --- | --- |
| 建立 database | 目前只驗證 LogWriter，不做 DB provisioning。 |
| 自動建立 `task_log_traces` | Schema Apply / DDL Executor 尚未確認。 |
| 執行 `CREATE TABLE` / `ALTER TABLE` / `DROP` | 避免影響真實 DB 結構。 |
| 寫入正式 DB | 第二階段只允許測試 DB manual-only 驗證。 |
| 將 `MySqlLogWriter` 接入 ConsoleHost | 會改變啟動行為，需另行確認。 |
| 新增 `TaskTraceStore` public 查詢介面 | 會新增查詢 contract，需先確認需求邊界。 |
| 導入背景 queue、批次 flush 或 retention job | 屬於正式維運設計，第一版先不納入。 |

## 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 table | `task_log_traces` | 可寫入 | 必須已存在。 |
| 是否允許 INSERT | `true` | 可寫入 | 必須由使用者明確確認。 |
| 是否允許 SELECT | `true` | 可寫入 | 驗證查詢必要。 |
| 是否允許 cleanup DELETE | 建議 `true` | 可寫入 | 只刪除本次 manual trace。 |
| 是否驗證 index | `true` | 可寫入 | 使用 metadata inspect 驗證。 |
| 是否驗證 comment | `true` | 可寫入 | 使用 table / column comment 驗證。 |

## 6. 前置 schema 檢查

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

必要資料表：

```text
task_log_traces
```

必要欄位：

| 欄位 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `trace_id` | `varchar(64)` | 是 | Trace 主鍵。 |
| `task_id` | `varchar(64)` | 否 | 任務識別碼。 |
| `node_id` | `varchar(64)` | 否 | Workflow 節點識別碼。 |
| `node_name` | `varchar(128)` | 否 | Workflow 節點名稱。 |
| `device_id` | `varchar(64)` | 否 | 設備識別碼。 |
| `command_name` | `varchar(128)` | 否 | 設備命令名稱。 |
| `level` | `varchar(32)` | 是 | Log 等級。 |
| `status` | `varchar(32)` | 否 | 節點或命令狀態。 |
| `retry_count` | `int` | 是 | 重試次數。 |
| `time_taken_ms` | `int` | 是 | 節點總耗時毫秒。 |
| `adapter_time_taken_ms` | `int` | 是 | Adapter 命令耗時毫秒。 |
| `error_code` | `varchar(64)` | 否 | 標準錯誤代碼。 |
| `message` | `varchar(255)` | 否 | Log 訊息摘要。 |
| `data_summary` | `text` | 否 | Adapter Data 摘要。 |
| `raw_request_summary` | `text` | 否 | 原始請求摘要，需確認敏感資訊已遮蔽。 |
| `raw_response_summary` | `text` | 否 | 原始回應摘要，需確認敏感資訊已遮蔽。 |
| `metadata_summary` | `text` | 否 | 額外 metadata 摘要。 |
| `created_at` | `datetime` | 是 | Trace 建立時間。 |

必要索引：

| Index | Columns | 用途 |
| --- | --- | --- |
| `idx_task_log_traces_task_id` | `task_id` | 查詢指定任務完整 trace。 |
| `idx_task_log_traces_node_id` | `node_id` | 查詢指定節點 trace。 |
| `idx_task_log_traces_device` | `device_id` | 查詢設備 trace。 |
| `idx_task_log_traces_command` | `command_name` | 查詢命令 trace。 |
| `idx_task_log_traces_level` | `level` | 查詢錯誤或警告等級。 |
| `idx_task_log_traces_error_code` | `error_code` | 查詢特定錯誤代碼。 |
| `idx_task_log_traces_created_at` | `created_at` | 依時間排序、稽核與後續清理。 |

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

## 7. 建議環境變數

DB LogWriter 建議使用獨立 gate，避免與 TaskStore 寫入混用同一組開關。

```text
HS_MYSQL_LOGWRITER_ENABLED
HS_MYSQL_LOGWRITER_ALLOW_WRITE
HS_MYSQL_LOGWRITER_HOST
HS_MYSQL_LOGWRITER_PORT
HS_MYSQL_LOGWRITER_DATABASE
HS_MYSQL_LOGWRITER_USER
HS_MYSQL_LOGWRITER_PASSWORD
HS_MYSQL_LOGWRITER_TABLE
HS_MYSQL_LOGWRITER_TIMEOUT_SECONDS
HS_MYSQL_LOGWRITER_SSL_MODE
HS_MYSQL_LOGWRITER_CLEANUP
```

補充規則：

- `HS_MYSQL_LOGWRITER_ENABLED=true` 才可連 DB。
- `HS_MYSQL_LOGWRITER_ALLOW_WRITE=true` 才可寫入。
- `HS_MYSQL_LOGWRITER_TABLE` 預設為 `task_log_traces`。
- `HS_MYSQL_LOGWRITER_PASSWORD` 不得寫入 repo、文件或測試輸出。
- `HS_MYSQL_LOGWRITER_CLEANUP=true` 時，只能刪除本次測試 trace id 或 task id 前綴資料。

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

```text
HS_MYSQL_INSPECT_ENABLED=true
HS_MYSQL_INSPECT_EXPECTED_TABLES=task_log_traces
HS_MYSQL_INSPECT_INCLUDE_INDEXES=true
HS_MYSQL_INSPECT_INCLUDE_COMMENTS=true
```

## 8. 測試資料設計

測試資料必須使用固定前綴：

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

建議欄位值：

| 欄位 | 建議值 |
| --- | --- |
| `trace_id` | `manual-logwriter-poc-{timestamp}-{short}` |
| `task_id` | `manual-logwriter-poc-task-{timestamp}-{short}` |
| `node_id` | `manual-log-node-1` |
| `node_name` | `Manual Log Node` |
| `device_id` | `manual-log-device-1` |
| `command_name` | `ManualLogCommand` |
| `level` | `Info` 或 `Error` |
| `status` | `Completed` 或 `Failed` |
| `error_code` | 成功情境為空；失敗情境可用 `MANUAL_LOG_FAILED` |
| `raw_request_summary` | 包含 `password=secret` 的測試字串，用來驗證遮蔽。 |
| `raw_response_summary` | 包含 `token=secret` 的測試字串，用來驗證遮蔽。 |
| `metadata_summary` | 包含 `connectionString=secret` 的測試字串，用來驗證遮蔽。 |

第一版建議寫入兩筆 trace：

| 筆數 | level | status | 用途 |
| --- | --- | --- | --- |
| 1 | `Info` | `Completed` | 驗證成功 trace 與核心欄位。 |
| 2 | `Error` | `Failed` | 驗證 error_code、message 與敏感資訊遮蔽。 |

## 9. 建議驗證流程

1. 使用者確認目標是測試 DB，且可接受 INSERT / SELECT / cleanup。
2. 設定 `HS_MYSQL_LOGWRITER_*` manual-only 環境變數。
3. 先執行 schema inspect，確認 `task_log_traces` 存在。
4. 若 schema inspect 缺表或缺欄位，停止並回報，不執行寫入。
5. 建立兩筆 `LogEntry`，包含成功與失敗情境。
6. 使用 `MySqlLogWriter.Write(entry)` 寫入 `task_log_traces`。
7. 使用 test-only / internal helper 依 `task_id` 或 `trace_id` 查詢資料。
8. 驗證 row count、欄位值、索引 metadata、comment metadata。
9. 驗證 raw request / response / metadata summary 不包含敏感原文。
10. 若 cleanup 開啟，只刪除本次 `trace_id` 或 `task_id` 前綴資料。
11. 輸出驗證摘要，後續回填人工驗證紀錄。

## 10. 建議 xUnit 範圍

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

```text
tests/HS.DeviceControl.Infrastructure.MySql.Tests/Logging/MySqlLogWriterManualMySql56Tests.cs
```

建議測試：

| 測試 | 目的 |
| --- | --- |
| `WriteAndInspect_ShouldPersistTaskLogTracesWhenManualGateIsEnabled` | 寫入兩筆 `LogEntry`，並查詢 `task_log_traces` 驗證資料列。 |
| `ManualGate_ShouldSkipLogWriterWriteWhenDisabled` | gate 未開時不連 DB、不寫入。 |
| `SchemaPrecheck_ShouldReportMissingTaskLogTracesWithoutWrite` | 缺少 `task_log_traces` 時停止，不自動 DDL。 |

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

## 11. 通過條件

| 條件 | 判斷 |
| --- | --- |
| gate 正常 | 未開 `ENABLED` 或 `ALLOW_WRITE` 時不連 DB、不寫入。 |
| schema 前置檢查正常 | `task_log_traces` 存在，必要欄位、索引與 comment 可讀。 |
| 寫入成功 | `MySqlLogWriter.Write` 不拋出例外，且 fallback writer 沒有錯誤 trace。 |
| trace 資料列正確 | 同一 manual `task_id` 或指定 `trace_id` 可查回預期筆數。 |
| 核心欄位正確 | `task_id`、`node_id`、`device_id`、`command_name`、`level`、`status` 可對回。 |
| 錯誤欄位正確 | `error_code`、`message` 可保留可讀摘要。 |
| 敏感資訊遮蔽 | 查回資料不得包含 password、token、secret、authorization 或完整 connection string 原文。 |
| cleanup 安全 | 僅刪除本次 manual 測試 trace。 |
| 輸出安全 | console output 不包含 password 或完整 connection string。 |

## 12. 失敗時需記錄

失敗紀錄至少包含：

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

不得記錄：

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

## 13. 停止線

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

1. 需要建立或修改 `task_log_traces` table。
2. 需要調整欄位型別、索引或 comment。
3. 需要修改 `ILogWriter` public method。
4. 需要新增 `TaskTraceStore` public 查詢介面。
5. 需要將 `MySqlLogWriter` 接入 ConsoleHost、ServiceHost 或 WebApi。
6. 需要連接正式 DB 或保存正式資料。
7. 需要調整 DB 帳號權限。
8. 需要變更 MySQL 套件或連線策略。

## 14. 驗證紀錄格式

後續完成驗證後，建議新增：

```text
docs/mysql-db-logwriter-tracestore-real-db-verification-record.md
```

紀錄格式：

| 欄位 | 內容 |
| --- | --- |
| 驗證節點名稱 | `MySQL DB LogWriter manual-only Write / Inspect / Cleanup` |
| 驗證目的 | 確認 `MySqlLogWriter` 可對真實測試 DB 寫入與查詢 trace |
| 驗證日期 | 實際日期 |
| 程式 commit | 驗證時 commit |
| MySQL 版本 | `5.6.2` |
| 驗證 DB | 測試 DB 名稱或遮蔽值 |
| 驗證方式 | manual-only xUnit |
| 實際結果 | Write / Inspect / Cleanup 摘要 |
| 是否符合預期 | 是 / 否 |
| 發現問題 | 列出限制或錯誤 |
| 建議下一步 | 下一個可執行項目 |

## 15. 目前結論

`MySqlLogWriter` 第一版已完成 fake gateway 測試、schema preview、payload sanitizer 與 fallback 行為，但尚未對真實測試 DB 執行 manual-only 寫入 / 查詢 / cleanup 驗證。

已完成 [MySQL DB LogWriter / TraceStore manual-only xUnit 驗證入口實作紀錄](mysql-db-logwriter-tracestore-manual-xunit-implementation-record.md)。

建議下一步先整理「MySQL DB LogWriter 真實 DB 驗證前確認清單」，再由使用者確認測試 DB 已具備 `task_log_traces` table、index、comment 與可接受 INSERT / SELECT / cleanup 後，才執行真實 DB 驗證。
