# MySQL DB LogWriter 真實 DB 驗證前確認清單

## 1. 文件目的

本文件用於執行 `MySqlLogWriter` 對 `task_log_traces` 真實 MySQL 5.6.2 測試 DB 寫入 / 查詢 / cleanup 驗證前，先確認測試 DB、schema、manual-only gate、cleanup 與停止線是否已準備完成。

本文件不保存密碼、不連線資料庫、不執行 DDL、不寫入資料，只作為執行前確認清單。若任一必要條件未確認，Codex 不得自行執行真實 DB 寫入測試。

## 2. 驗證目標

| 項目 | 內容 |
| --- | --- |
| 驗證節點 | MySQL DB LogWriter `task_log_traces` 真實 DB manual-only 驗證 |
| 主要目的 | 確認 `MySqlLogWriter.Write(LogEntry)` 可寫入真實測試 DB，並可查回 trace row |
| 查詢確認 | 透過測試內部 helper 依同一個 `task_id` 查回兩筆 trace rows |
| sanitizer 確認 | 查回資料不得包含 password、token、secret、authorization 或完整 connection string 原文 |
| cleanup | 只清除本次 `manual-logwriter-poc-` 前綴的測試資料 |
| 不驗證項目 | `TaskTraceStore` public 查詢介面、Schema Apply / DDL Executor、ConsoleHost 接入 |

## 3. 已知測試 DB 資訊

| 欄位 | 目前值 | 保存規則 | 備註 |
| --- | --- | --- | --- |
| MySQL 版本 | `5.6.2` | 可寫入 | 第二階段目前目標版本。 |
| Host / IP | `<masked>` | 不寫完整值 | 由使用者本機環境變數提供。 |
| Port | `3306` | 可寫入 | 測試 DB 連線埠。 |
| Database | `hs_device_control_test` | 可寫入 | 必須確認為測試 DB。 |
| User | `hs_device` | 可寫入 | 建議只給測試 DB 權限。 |
| Password | `<local-env-only>` | 不可寫入 | 只能由本機環境變數提供。 |
| Expected table | `task_log_traces` | 可寫入 | 本驗證必要 table。 |
| 是否驗證 index | 是 | 可寫入 | 使用 `information_schema` 檢查。 |
| 是否驗證 comment | 是 | 可寫入 | 使用 table / column comment 檢查。 |

## 4. 執行前必須確認

| 確認項目 | 必要狀態 | 備註 |
| --- | --- | --- |
| 是否為測試 DB | 必須是 | 不得使用正式 DB。 |
| `task_log_traces` | 已存在 | 本驗證不自動建表。 |
| table comment | 已存在 | `task_log_traces` 需有 table comment。 |
| column comment | 已存在 | 必要欄位需有 comment。 |
| index | 已存在 | 必要 index 需可由 `information_schema` 讀取。 |
| INSERT 權限 | 已確認 | 只允許 manual-only 測試寫入。 |
| SELECT 權限 | 已確認 | 查詢驗證必要。 |
| DELETE 權限 | 建議確認 | cleanup 需要；若不允許 cleanup，需先確認可接受測試資料暫留。 |
| Password | 已由本機環境變數設定 | 不得貼到對話、文件或 commit。 |
| cleanup | 預設開啟 | 只刪除本次 manual `task_id` 的 trace rows。 |

## 5. 必要 schema 停止線

執行寫入前，manual-only 測試會先用 `MySqlSchemaInspector` 與測試內部 schema precheck 檢查：

| 類別 | 必要內容 |
| --- | --- |
| 必要資料表 | `task_log_traces` |
| `task_log_traces` 主鍵 | `trace_id` |
| 必要欄位 | `trace_id`、`task_id`、`level`、`retry_count`、`time_taken_ms`、`adapter_time_taken_ms`、`created_at` |
| 建議欄位 | `node_id`、`node_name`、`device_id`、`command_name`、`status`、`error_code`、`message`、`data_summary`、`raw_request_summary`、`raw_response_summary`、`metadata_summary` |
| 必要索引 | `idx_task_log_traces_task_id`、`idx_task_log_traces_node_id`、`idx_task_log_traces_device`、`idx_task_log_traces_command`、`idx_task_log_traces_level`、`idx_task_log_traces_error_code`、`idx_task_log_traces_created_at` |
| 必要描述 | `task_log_traces` table comment 與必要 column comment |

若缺少 table、欄位、主鍵、index 或 comment，測試必須停止並回報，不得自動建立或修改資料表。

## 6. 必要環境變數

```powershell
$env:HS_MYSQL_LOGWRITER_ENABLED="true"
$env:HS_MYSQL_LOGWRITER_ALLOW_WRITE="true"
$env:HS_MYSQL_LOGWRITER_HOST="<test-db-host>"
$env:HS_MYSQL_LOGWRITER_PORT="3306"
$env:HS_MYSQL_LOGWRITER_DATABASE="hs_device_control_test"
$env:HS_MYSQL_LOGWRITER_USER="hs_device"
$env:HS_MYSQL_LOGWRITER_PASSWORD="<password>"
$env:HS_MYSQL_LOGWRITER_TABLE="task_log_traces"
$env:HS_MYSQL_LOGWRITER_TIMEOUT_SECONDS="15"
$env:HS_MYSQL_LOGWRITER_SSL_MODE="None"
$env:HS_MYSQL_LOGWRITER_CLEANUP="true"
```

安全規則：

- `HS_MYSQL_LOGWRITER_ENABLED=true` 只表示允許連線測試 DB。
- `HS_MYSQL_LOGWRITER_ALLOW_WRITE=true` 只表示允許 manual-only 測試寫入測試資料。
- 密碼不得寫入文件、README、commit message、issue、log 或截圖。
- 若 `HS_MYSQL_LOGWRITER_CLEANUP=false`，必須先確認測試資料可以暫留。

## 7. 執行指令

確認完成後，才可在程式 repo 根目錄執行：

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

## 8. 通過條件

| 項目 | 預期結果 |
| --- | --- |
| Gate | `Enabled: true`、`AllowWrite: true` |
| SchemaPrecheck | `True` |
| Write | 兩筆 `LogEntry` 寫入成功 |
| Trace rows | `TraceRowCount: 2` |
| Info trace | `manual-log-node-1`、`Completed`、`manual-log-device-1`、`ManualLogCommand` |
| Error trace | `manual-log-node-2`、`Failed`、`MANUAL_LOG_FAILED` |
| Sanitizer | 查回資料不含 `secret` 原文，且包含遮蔽符號 |
| Cleanup | 成功刪除本次 manual `task_id` 的 `task_log_traces` |
| 輸出安全 | Console output 不包含 password 或完整 connection string |

## 9. 必須停止並回報的情境

| 情境 | 處理方式 |
| --- | --- |
| 使用者未明確確認為測試 DB | 停止，不執行。 |
| 密碼或連線資訊缺少 | 停止，請使用者在本機設定環境變數。 |
| `task_log_traces` 不存在 | 停止，不自動建表。 |
| 缺少欄位、主鍵、index 或 comment | 停止，不執行寫入。 |
| 測試 DB 連線失敗 | 停止，回報錯誤類型與已遮蔽訊息。 |
| Write 失敗 | 停止，回報錯誤碼、例外型別與是否 cleanup。 |
| sanitizer 驗證失敗 | 停止，回報哪個 summary 欄位仍含敏感原文。 |
| Cleanup 失敗 | 停止，回報殘留 `task_id`，由使用者決定是否手動清除。 |

## 10. 延後邊界

| 項目 | 狀態 | 原因 |
| --- | --- | --- |
| `TaskTraceStore` public 查詢介面 | 延後 | 會新增查詢 contract，需要另行設計與確認。 |
| ConsoleHost 接入 DB LogWriter | 延後 | 會改變啟動與輸出行為，需另行確認。 |
| Schema Apply / DDL Executor | 延後 | 任何 `CREATE TABLE`、`ALTER TABLE`、`DROP` 都需要另行確認。 |
| 正式 DB 寫入 | 延後 | 第二階段只允許測試 DB manual-only gate。 |
| retention / purge job | 延後 | 屬正式維運策略，不納入本驗證節點。 |

## 11. 執行後需回填的紀錄

若真實 DB manual-only 驗證完成，需新增或更新驗證紀錄，至少包含：

- 驗證日期與程式 commit。
- 是否為測試 DB。
- schema precheck 結果。
- `TraceRowCount`。
- 兩筆 trace row 摘要。
- sanitizer 查回結果。
- cleanup 結果。
- 失敗時的錯誤類型、錯誤訊息與是否有殘留資料。

建議紀錄檔：

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

## 12. 下一步建議

確認本清單所有必要項目後，再由使用者明確授權執行 `task_log_traces` 真實 DB manual-only 寫入 / 查詢 / cleanup 驗證。若任何 schema 條件不符合，先停下討論是手動建表、修正測試 DB，或延後到 Schema Apply / DDL Executor 階段。
