# MySqlSchemaInspector 實作前確認清單

## 1. 文件目的

本文件整理進入 `MySqlSchemaInspector` 第一版實作前需要確認的工程邊界、實作位置、套件導入條件、query builder、row mapping、測試案例與人工驗證節點。

此節點仍然是「實作前確認」，不會導入 `MySqlConnector`、不會建立真實連線字串、不會連線 MySQL、不會讀取真實 `information_schema`，也不會執行任何 DDL。

## 2. 前置條件

| 項目 | 狀態 |
|---|---|
| MySQL 版本 | 使用者指定為 MySQL 5.6.2 |
| Schema Attribute / SQL Generator | 已完成第一版 |
| `ISchemaInspector` | 已完成抽象與 mock inspector |
| `SchemaDryRunPlanner` | 已完成 mock snapshot 比對 |
| `SchemaInitializer` DryRun | 已完成第一版 |
| ConsoleHost 顯示 | 已可顯示 Schema Initializer DryRun 結果 |
| 真實 MySQL Inspector 前置確認 | 已完成 |
| 自動測試 | `dotnet test` 通過 318 個測試 |
| 最新程式 commit | `ac52376` |

## 3. 本節點建議結論

可以準備進入 `MySqlSchemaInspector` 第一版實作，但第一版建議拆成兩段：

| 段落 | 內容 | 是否需要真實 DB |
|---|---|---|
| A. 純程式準備 | 建立 query builder、row mapping、result mapping 與單元測試 | 否 |
| B. 真實 DB 驗證 | 導入套件、連線唯讀 MySQL、讀取 `information_schema` | 是，需另行確認 |

本次建議先做 A 段，等 A 段完成後，再由使用者確認是否進入 B 段。

## 4. 實作位置建議

| 類型 | 建議位置 | 說明 |
|---|---|---|
| `MySqlSchemaInspector` | `Infrastructure` 或 schema 專屬 infrastructure 區 | 需依賴 MySQL provider，不應放在 Core |
| query builder | 與 `MySqlSchemaInspector` 同區或內部 helper | 負責產生 `information_schema` 查詢，不持有密碼 |
| row mapper | 與 inspector 同區 | 將 table / column / index rows 轉成 schema snapshot |
| connection settings | Infrastructure config model | 不放密碼預設值，不寫進 repo |
| tests | 對應測試專案 | 用假資料列測 mapping，不需真實 DB |

Core 仍只保留 schema model 與抽象契約，不直接引用 MySQL 套件。

## 5. 套件導入條件

導入 `MySqlConnector` 前需再次確認：

| 確認項 | 原因 |
|---|---|
| 是否允許新增 NuGet package | AGENTS 規則要求新增核心套件前需確認 |
| 套件版本 | 需相容 .NET 5.0 |
| 放置專案 | 建議只放在 Infrastructure / MySQL 實作專案，不放 Core |
| CI 還原 | 確認 GitHub Actions 能還原套件 |
| 連線字串來源 | 不得寫死在 repo |
| 測試策略 | 單元測試不依賴真實 DB，真實 DB 驗證另列人工節點 |

若使用者尚未確認，下一步只能做文件與設計，不可直接修改 `.csproj`。

## 6. Query Builder 範圍

第一版 query builder 建議只產生三類查詢：

| 查詢 | 來源 | 目的 |
|---|---|---|
| Table query | `information_schema.TABLES` | 取得指定 database 內的 table |
| Column query | `information_schema.COLUMNS` | 取得指定 database 內的欄位 |
| Index query | `information_schema.STATISTICS` | 取得指定 database 內的 index 與 primary key |

### 6.1 共用條件

每個查詢都必須包含：

- `TABLE_SCHEMA = @DatabaseName`
- 可選 table filter，但不得直接串接使用者輸入。
- 明確排序，例如 table name、ordinal position、index name、sequence。
- 參數化查詢，不拼接 database name。

### 6.2 Table query 欄位

| 欄位 | 目的 |
|---|---|
| `TABLE_NAME` | table 名稱 |
| `TABLE_COMMENT` | table 描述 |
| `ENGINE` | engine |
| `TABLE_COLLATION` | collation |

### 6.3 Column query 欄位

| 欄位 | 目的 |
|---|---|
| `TABLE_NAME` | table 名稱 |
| `COLUMN_NAME` | 欄位名稱 |
| `COLUMN_TYPE` | 完整 MySQL 型別 |
| `DATA_TYPE` | 基礎型別 |
| `IS_NULLABLE` | nullable |
| `COLUMN_DEFAULT` | default value |
| `COLUMN_COMMENT` | 欄位描述 |
| `ORDINAL_POSITION` | 欄位順序 |
| `CHARACTER_MAXIMUM_LENGTH` | 字串長度 |
| `NUMERIC_PRECISION` / `NUMERIC_SCALE` | 數值精度 |

### 6.4 Index query 欄位

| 欄位 | 目的 |
|---|---|
| `TABLE_NAME` | table 名稱 |
| `INDEX_NAME` | index 名稱 |
| `COLUMN_NAME` | 欄位名稱 |
| `NON_UNIQUE` | 判斷 unique |
| `SEQ_IN_INDEX` | 複合 index 欄位順序 |

## 7. Row Mapping 規則

Row mapping 第一版需處理：

| 情境 | 規則 |
|---|---|
| table 無 comment | 保留空字串，不視為錯誤 |
| column default 為 null | 區分「沒有 default」與「default null」的表示方式 |
| `IS_NULLABLE` | `YES` 對應 nullable，其他視為 not nullable |
| `NON_UNIQUE` | `0` 對應 unique，`1` 對應 non-unique |
| `INDEX_NAME = PRIMARY` | 轉成 primary key metadata |
| 複合 index | 依 `SEQ_IN_INDEX` 排序 |
| 未預期型別 | 不直接失敗，轉成 manual review warning |
| 資料列缺少必要欄位 | 回傳標準錯誤，不吞 exception |

## 8. Error / Result 規則

`MySqlSchemaInspector` 不應只回傳 bool，也不應讓未處理 exception 直接外拋到 Host。

建議錯誤至少包含：

- `ErrorCode`
- `ErrorMessage`
- `ExceptionType`
- `DatabaseName`
- `Source`
- `CorrelationId`
- `TimeTakenMs`

建議先沿用既有 `SchemaInspectResult` / `ErrorInfo` 風格；若需新增公開欄位或改 public method 簽章，必須先停下確認。

## 9. 測試案例

不連真實 DB 的第一批測試建議包含：

| 測試 | 預期 |
|---|---|
| Table query 包含 database filter | 查詢必須使用 `@DatabaseName` |
| Column query 包含排序 | 欄位需依 table / ordinal position 排序 |
| Index query 可還原複合 index | 多欄位 index 依 `SEQ_IN_INDEX` 排序 |
| nullable mapping | `YES` / `NO` 正確轉換 |
| unique mapping | `NON_UNIQUE = 0` 轉 unique |
| primary key mapping | `INDEX_NAME = PRIMARY` 可辨識 |
| table / column comment 空值 | 不失敗 |
| metadata row 缺少必要欄位 | 回傳標準錯誤 |
| 未知型別 | 產生 warning 或 manual review，不直接套用 |

## 10. 人工驗證節點規劃

等使用者確認可以連真實 MySQL 後，需建立人工驗證節點。

人工驗證回報至少包含：

| 項目 | 說明 |
|---|---|
| 驗證節點名稱 | 真實 MySQL Inspector metadata 讀取驗證 |
| 驗證目的 | 確認唯讀帳號可讀指定 database metadata |
| 驗證方式 | 使用指定 Host / Port / Database / User，Password 由安全來源提供 |
| 實際結果 | 讀到 table / column / index 數量 |
| 是否符合預期 | 是否只讀指定 database，是否未執行 DDL |
| 發現問題 | 權限、連線、型別、comment、collation 差異 |
| 下一步 | 是否串接 Dry Run Plan 或補 mapping 規則 |

## 11. 必須停下確認的事項

以下事項不得在本節點自動執行：

| 事項 | 原因 |
|---|---|
| 新增 `MySqlConnector` | 新增套件需確認 |
| 修改 `.csproj` | 會影響程式 repo build / restore |
| 新增真實 connection settings | 可能涉及密碼與環境資訊 |
| 連線 MySQL | 外部服務操作需確認 |
| 讀取真實 `information_schema` | 進入真實 DB metadata |
| 修改 public method 簽章 | 可能影響既有契約 |
| 修改 ConsoleHost 啟動方式 | 影響使用流程 |
| 執行任何 DDL | 會修改資料庫 |

## 12. 建議下一步

建議下一步先向使用者確認是否允許導入 `MySqlConnector`。

若尚未允許導入套件，可先做更細的「Query Builder / Row Mapper 設計」，仍不碰 `.csproj`。
