# Schema Inspector 抽象介面與 mock inspector 實作前確認

## 1. 文件目的

本文件整理進入 `Schema Inspector` 第一版程式實作前的確認項目。

此節點只處理抽象介面、mock inspector、schema snapshot 回傳模型與測試案例，不導入 MySQL 套件、不連線 MySQL、不讀取 `information_schema`，也不執行 DDL。

這樣做的目的，是先把「Inspector 讀出目前 schema」與「Dry Run Plan 比對目標 schema」的程式接縫驗證起來，避免一開始就被真實資料庫、密碼、網路與權限問題卡住。

## 2. 本節點範圍

| 項目 | 是否納入 | 說明 |
|---|---|---|
| `ISchemaInspector` 抽象介面 | 納入 | 定義讀取目前 schema snapshot 的契約 |
| `MockSchemaInspector` / `FakeSchemaInspector` | 納入 | 測試與 ConsoleHost 前置驗證可使用 |
| schema snapshot model | 納入 | 優先沿用既有 `SchemaDefinition` / `TableDefinition` / `ColumnDefinition` / `IndexDefinition` |
| Inspector result | 納入 | 需能表達成功、失敗、錯誤與警告 |
| Dry Run Plan 串接測試 | 納入 | 用 mock snapshot 驗證與目標 schema 比對 |
| MySQL 套件 | 不納入 | 不新增 `MySqlConnector` |
| 真實 MySQL 連線 | 不納入 | 不需要 host / port / user / password |
| `information_schema` 查詢 | 不納入 | 留到真實 MySQL Inspector 節點 |
| DDL 執行 | 不納入 | 不建立、不修改、不刪除資料表 |

## 3. 建議介面設計

建議先建立抽象介面，讓後續可替換 mock inspector 與真實 MySQL inspector。

```csharp
public interface ISchemaInspector
{
    SchemaInspectResult Inspect(SchemaInspectRequest request);
}
```

建議不要讓介面直接依賴 MySQL 連線物件，也不要把 connection string 放進 Core 介面。

## 4. 建議 request model

`SchemaInspectRequest` 建議包含：

| 欄位 | 說明 |
|---|---|
| `DatabaseName` | 目標 database 名稱；mock inspector 可用來標示測試情境 |
| `ExpectedTables` | 可選，限制只讀取或回傳指定 table |
| `IncludeIndexes` | 是否包含 index snapshot |
| `IncludeComments` | 是否包含 table / column comment |
| `CorrelationId` | 方便 log 與測試追蹤 |

第一版也可以先不建立複雜 options，只保留必要欄位，避免過早設計。

## 5. 建議 result model

`SchemaInspectResult` 建議包含：

| 欄位 | 說明 |
|---|---|
| `Success` | 是否讀取成功 |
| `Schema` | 成功時回傳目前 schema snapshot |
| `Warnings` | 可繼續執行但需提醒的項目 |
| `Error` | 失敗時回傳標準錯誤資訊 |
| `TimeTakenMs` | 執行耗時 |
| `Source` | 例如 `Mock`、`MySQL information_schema` |

錯誤格式需盡量沿用既有 Result / ErrorInfo 風格，不要只回傳 `bool` 或丟出未處理 exception。

## 6. Mock inspector 行為

建議第一版 mock inspector 支援下列情境：

| 情境 | 行為 |
|---|---|
| 回傳空 database | `SchemaDefinition` 中無 table |
| 回傳既有完整 schema | 模擬 DB 已符合目標 schema |
| 回傳缺少 column | 讓 Dry Run Plan 產生 `ColumnsToAdd` |
| 回傳缺少 index | 讓 Dry Run Plan 產生 `IndexesToAdd` |
| 回傳欄位型別不同 | 讓 Dry Run Plan 產生 `ManualReviewItems` |
| 模擬讀取失敗 | 回傳標準 `ErrorInfo`，不吞 exception |

Mock inspector 不應該假裝連線 MySQL，也不應該藏入任何真實連線資訊。

## 7. 建議放置位置

| 類型 | 建議位置 |
|---|---|
| 抽象介面 | 若只使用 schema model，可放在 Core schema 區；若會牽涉外部連線，需放 Infrastructure |
| Mock inspector | 優先放測試專案或測試 helper；若 ConsoleHost 需要展示，可放 Infrastructure / Mock 實作區 |
| 真實 MySQL inspector | 後續放 Infrastructure 或 MySQL schema 實作區，不放 Core |

若現有程式 repo 已經有 `Schema` 資料夾與 SQL Generator，第一版可以先把純抽象與 mock 放在同一個低風險區域，但需避免讓 Core 依賴 MySQL 套件。

## 8. 測試案例建議

| 測試案例 | 驗證目的 |
|---|---|
| mock inspector 可回傳空 schema | 確認空 DB snapshot 可表示 |
| mock inspector 可回傳既有 table / column / index | 確認 snapshot model 可承載資料 |
| mock snapshot 與目標 schema 相同 | Dry Run Plan 不應產生 SQL |
| mock snapshot 缺少 column | Dry Run Plan 應產生 `ADD COLUMN` |
| mock snapshot 缺少 index | Dry Run Plan 應產生 `ADD INDEX` |
| mock snapshot 欄位型別不同 | Dry Run Plan 應進 `ManualReviewItems` |
| mock inspector 失敗 | result 應包含標準錯誤資訊 |
| inspector 不產生 DDL | 確認 inspector 只讀 snapshot，不產生 SQL、不執行 SQL |

## 9. 實作前需確認

| 確認項目 | 建議 |
|---|---|
| 是否先做 mock inspector | 建議先做 |
| 是否新增 MySQL 套件 | 本節點不新增 |
| 是否改 public method 簽章 | 避免改既有 public 簽章，新增介面與 model 即可 |
| 是否改啟動方式 | 不改 |
| 是否需要 ConsoleHost 展示 | 本節點先不接 ConsoleHost，避免擴大範圍 |
| 是否需要文件同步 | 需要，完成後同步開發進度 |

## 10. 建議決策

建議採用：

> 先建立 `ISchemaInspector` + mock inspector + 單元測試，不碰真實 MySQL。

原因：

- 可先驗證 schema snapshot 與 Dry Run Plan 的程式接縫。
- 不需要密碼、host、port、權限與外部服務。
- 不會引入 MySQL 套件，風險低。
- 後續要接 `MySqlSchemaInspector` 時，可沿用同一個介面與測試結構。

## 11. 建議下一步

若確認本文件方向，下一步可進入：

> `Schema Inspector 抽象介面與 mock inspector 第一版實作`

實作時建議只包含：

- `ISchemaInspector`
- `SchemaInspectRequest`
- `SchemaInspectResult`
- `MockSchemaInspector`
- 對應單元測試

仍不做：

- `MySqlConnector`
- 真實 DB 連線
- `information_schema` 查詢
- Schema Initializer
- DDL Executor
- ConsoleHost 啟動自動建表
