Schema Initializer DryRun 流程設計
1. 文件目的
本文件定義第二階段 Schema Initializer 的 DryRun 流程,用來承接已完成的:
MySqlSchemaSqlGeneratorALTER TABLE Dry Run PlanISchemaInspector/MockSchemaInspectorSchemaDryRunPlanner- ConsoleHost Schema Dry Run 顯示
目標是先建立安全的初始化協調層設計,讓後續可以逐步導入真實 MySQL metadata 檢查與正式建表流程。
本文件只做流程設計,不進行程式實作。
本節點明確不連線 MySQL、不讀取 information_schema、不執行 DDL,也不修改 ConsoleHost 啟動方式。
2. 範圍邊界
| 項目 | 本次是否包含 |
|---|---|
| 定義 Schema Initializer 職責 | 是 |
| 定義 DryRun / Apply 分離 | 是 |
| 定義 ConsoleHost 未來接入流程 | 是 |
| 定義錯誤、警告、manual review 回傳規則 | 是 |
| 實作 C# class | 否 |
| 導入 MySQL 套件 | 否 |
| 連線 MySQL | 否 |
讀取 information_schema | 否 |
執行 CREATE TABLE / ALTER TABLE | 否 |
| 修改 ConsoleHost 啟動方式 | 否 |
3. 核心設計原則
3.1 DryRun 優先
Schema 初始化流程必須先支援 DryRun。
DryRun 的目的不是修改資料庫,而是回答:
- 目前 schema 與目標 schema 差在哪裡?
- 會產生哪些 SQL?
- 哪些差異需要人工審查?
- 有哪些 warning 或風險?
- 是否可以進入 Apply?
3.2 Apply 必須獨立
Apply 不得與 DryRun 共用同一個隱含流程。
未來若要支援 Apply,必須另外建立:
- 明確的 Apply request。
- 明確的執行確認。
- DDL executor。
- 執行前備份 / rollback 策略說明。
- 權限與連線檢查。
- 實際執行紀錄。
3.3 Initializer 只做協調
Schema Initializer 不應直接組 SQL,也不應直接知道 MySQL metadata 細節。
它只負責協調:
- 建立目標 schema。
- 呼叫 inspector 取得目前 schema snapshot。
- 呼叫 planner 產生 DryRun plan。
- 彙整結果。
- 回傳標準 result 給 ConsoleHost 或未來 Host。
4. 建議元件分工
| 元件 | 職責 |
|---|---|
SchemaDefinitionProvider | 從 C# schema class / attribute 建立目標 SchemaDefinition |
ISchemaInspector | 讀取目前資料庫 schema snapshot |
SchemaDryRunPlanner | 比對目標 schema 與目前 schema,產生 DryRun plan |
SchemaInitializer | 協調 provider、inspector、planner,回傳初始化結果 |
SchemaExecutor | 未來 Apply 模式才需要,用於實際執行 DDL |
ConsoleHost | 顯示 DryRun 結果,不直接組 SQL、不直接執行 DDL |
5. DryRun 流程
flowchart TD
A["ConsoleHost 啟動 Schema DryRun"] --> B["SchemaInitializer.RunDryRun"]
B --> C["SchemaDefinitionProvider 建立 TargetSchema"]
B --> D["ISchemaInspector 取得 CurrentSchema"]
C --> E["SchemaDryRunPlanner.GenerateDryRunPlan"]
D --> E
E --> F["SchemaDryRunResult"]
F --> G["ConsoleHost Formatter"]
G --> H["顯示 Summary / SQL preview / Manual review / Warnings"]
6. 建議 Request / Result
6.1 SchemaInitializerDryRunRequest
建議欄位:
| 欄位 | 說明 |
|---|---|
DatabaseName | 目標 database 名稱 |
CorrelationId | 本次 dry run 追蹤代號 |
ExpectedTables | 預期檢查的 table 清單,可空白代表檢查全部目標 schema |
IncludeIndexes | 是否檢查 index |
IncludeComments | 是否檢查 table / column comment |
Source | 呼叫來源,例如 ConsoleHost |
6.2 SchemaInitializerResult
建議欄位:
| 欄位 | 說明 |
|---|---|
Success | Initializer 是否成功完成流程 |
Mode | 固定為 DryRun 或未來 Apply |
Plan | SchemaMigrationPlan |
Warnings | inspector、planner、initializer 彙整 warning |
ManualReviewItems | 需要人工審查的項目 |
Error | 標準 ErrorInfo |
TimeTakenMs | 執行耗時 |
CorrelationId | 追蹤代號 |
7. Error / Warning 規則
7.1 必須失敗的情境
| 情境 | 建議錯誤 |
|---|---|
| request 為 null | SchemaDefinitionInvalid |
| target schema 無 table | SchemaDefinitionInvalid |
| inspector 為 null | SchemaDefinitionInvalid |
| inspector 讀取失敗 | SchemaInspectionFailed |
| planner 回傳 null | SchemaDefinitionInvalid |
| plan 產生失敗 | 保留 planner error |
7.2 可通過但需 warning 的情境
| 情境 | 建議 warning |
|---|---|
| DryRun 模式 | Dry Run 不會連線或修改 MySQL。 或等價明確文字 |
| 有 manual review | 提醒使用者不可直接 Apply |
| 有未知欄位差異 | 提醒需人工確認 |
| comment 差異 | 可列為 warning 或 manual review,暫不自動修改 |
8. ConsoleHost 接入策略
8.1 第一版
第一版維持目前安全策略:
- ConsoleHost 顯示 mock dry run。
- 不讀取真實 DB。
- 不新增啟動參數。
- 不導入 MySQL 套件。
8.2 第二版
第二版可考慮加入明確模式:
dotnet run --project src\HS.DeviceControl.ConsoleHost -- --schema-dry-run
但需先確認:
- 啟動參數格式。
- 與既有 workflow demo 啟動方式是否衝突。
- 是否要支援 config 指定 database。
- 是否要輸出 JSON 報告。
8.3 Apply 模式
Apply 模式不可在未確認前導入。
未來若要支援,建議明確區分:
--schema-dry-run
--schema-apply
並在 Apply 前要求:
- 顯示 SQL 清單。
- 顯示目標 database。
- 顯示連線資訊摘要,但不可印出密碼。
- 顯示 manual review 是否為 0。
- 顯示備份與 rollback 風險說明。
9. 驗收標準
Schema Initializer DryRun 第一版實作完成時,至少需要符合:
| 驗收項目 | 標準 |
|---|---|
| DryRun 不執行 DDL | 必須 |
| DryRun result 可被 ConsoleHost 顯示 | 必須 |
| inspector failure 可回傳標準錯誤 | 必須 |
| plan failure 可回傳標準錯誤 | 必須 |
| warnings 不得遺失 | 必須 |
| manual review 不得遺失 | 必須 |
| 測試覆蓋 null request / inspector fail / success plan | 必須 |
10. 建議下一步
建議下一步做:
Schema Initializer DryRun 實作前確認
確認內容應包含:
- 是否先建立
SchemaInitializerclass。 - 是否先使用
MockSchemaInspector完成第一版。 - 是否暫不修改 ConsoleHost 啟動參數。
- 測試要放在 Core tests 或新測試專案。
- 是否需要同步新增 ConsoleHost 人工驗證節點。