# 5C DB audit 邊界分析

本文件承接 [第五階段 Loader 到 Service 後續文件 / 實作 / 驗收範圍補齊表](phase-five-loader-to-service-scope-acceptance-plan.md) 與 [5B config schema 實作與驗收紀錄](phase-five-b-config-schema-implementation-acceptance-record.md)。

5C 的目標是先固定 DB audit 的事件語意、資料邊界、候選程式位置、測試策略與停止線。5C 會碰到資料庫寫入與 schema 風險，因此在使用者完成七項確認前，不修改程式 repo，不新增 audit table，不執行 DDL / ALTER TABLE / formal Apply，也不對真實 DB 寫入資料。

## 0. 文件狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 已建立，等待 5C 七項確認 |
| 建立日期 | 2026-06-07 |
| 對應節點 | 第五階段 5C DB audit |
| 程式 repo | `hs-device-control-template` |
| 程式 branch | `poc/nmodbus-tcp` |
| 程式基準 | `1f635d6`，5B config schema 已完成 |
| 本次是否修改程式 repo | 否，只做唯讀檢查、測試基準與文件整理 |
| 下一步 | 等待使用者確認 `5C DB audit 實作前確認` 七項 |

## 1. 5C 目標

| 目標 | 說明 |
|---|---|
| 固定 audit event 語意 | 先定義 PluginLoader / external DLL / config gate / manual verification 的安全 audit event，而不是直接建立 DB table。 |
| 建立資料最小化原則 | audit 只記錄安全摘要、決策、錯誤碼、操作者摘要、時間與關聯 id，不保存 secret、connection string、完整路徑、正式 IP 或 raw payload。 |
| 先 fake writer | 第一版建議先做 Application 層 audit writer contract 與 fake writer 測試，不直接寫 MySQL。 |
| 承接既有 MySQL 能力 | 程式 repo 已有 `Infrastructure.MySql`、schema dry-run、LogWriter / TaskTraceStore 與 manual-only MySQL 測試，5C 應沿用既有安全模式。 |
| 分離 DDL 與真實 DB 寫入 | audit table schema、DDL dry-run、manual DB write / read / cleanup 必須拆成後續確認，不在未確認時執行。 |
| 建立驗收證據 | 至少需有 Application / Infrastructure.MySql tests、solution tests、停止線掃描與文件同步證據。 |

## 2. 事件範圍草案

| 事件類型 | 建議用途 | 是否納入 5C 最小實作 |
|---|---|---|
| `PluginMetadataReviewed` | 記錄 metadata 被接受、拒絕或需人工確認。 | 可納入 fake writer。 |
| `ExternalDllManualVerificationRequested` | 記錄外部 DLL manual-only 驗證請求摘要。 | 可納入 fake writer，但不保存檔案路徑。 |
| `ExternalDllManualVerificationRejected` | 記錄 gate 關閉、checksum 不符或 contract 不符。 | 可納入 fake writer。 |
| `ConfigSchemaValidated` | 記錄 5B config schema 驗證結果摘要。 | 可納入 fake writer，但不保存原始設定內容。 |
| `DbAuditManualWriteRequested` | 後續真實 DB manual-only 驗證前的人工 gate。 | 需另行確認，不在第一批落地。 |

## 3. 欄位邊界草案

| 欄位 | 建議規則 |
|---|---|
| `AuditId` | 必填或自動產生，使用安全識別字串。 |
| `EventType` | 必填，限定在核准的 audit event 名稱。 |
| `SubjectType` | 必填，例如 Plugin、Config、ExternalDllManualVerification。 |
| `SubjectId` | 必填，保存 plugin id 或安全摘要 id，不保存完整路徑。 |
| `Decision` | 必填，例如 Accepted、Rejected、ManualReviewRequired。 |
| `ReasonCode` | 可選，保存標準錯誤碼或安全原因代碼。 |
| `ReasonSummary` | 可選，需通過敏感資訊遮蔽。 |
| `Operator` | 可選，保存操作者摘要，不保存帳號密碼或 token。 |
| `CorrelationId` | 可選，用於串接 task / request / plugin load 流程。 |
| `CreatedAtUtc` | 必填，統一 UTC。 |

## 4. 唯讀檢查結果

| 檢查項目 | 結果 |
|---|---|
| 文件 repo 狀態 | `main...origin/main`，乾淨。 |
| 程式 repo 狀態 | `poc/nmodbus-tcp...origin/poc/nmodbus-tcp`，乾淨。 |
| 現有 audit model | `PluginAuditRecord` 已存在於 Application 層，僅保存安全摘要，不負責 DB 寫入。 |
| 現有安全遮蔽 | `PluginContractTextSafety` 已用於 plugin / external DLL 安全文字檢查。 |
| 現有 MySQL 專案 | `HS.DeviceControl.Infrastructure.MySql` 已存在，含 schema inspector、LogWriter、TaskTraceStore 與 fake gateway 測試。 |
| 現有 schema 工具 | Core 已有 `DbTableAttribute`、`SchemaDefinitionParser`、`MySqlSchemaSqlGenerator`、`SchemaManualApplyPreviewBuilder`。 |
| 現有 manual-only DB 測試 | Infrastructure.MySql.Tests 已有 MySQL manual-only 測試入口，需明確 gate 才會接真實 DB。 |
| 5C 風險 | 若新增 audit table、DDL 或真實 DB write，需要另行確認，不可混入第一批。 |

## 5. 候選程式檔案

若使用者確認 5C 七項，建議第一批只做 Application 層與測試，不碰真實 DB：

| 類型 | 候選檔案 | 說明 |
|---|---|---|
| Audit contract | `src/HS.DeviceControl.Application/Plugins/` 或 `src/HS.DeviceControl.Application/Auditing/` | 建立 audit event、request、result、writer interface。 |
| Fake writer | `tests/HS.DeviceControl.Application.Tests` | 以 in-memory fake writer 驗證資料最小化、敏感資訊遮蔽與錯誤碼。 |
| Error codes | `src/HS.DeviceControl.Application/Common/ApplicationErrorCodes.cs` | 若新增錯誤碼，需只加 5C audit 相關代碼，不改既有代碼語意。 |
| DB schema 文件 | 程式 repo `docs/` | 記錄 5C 第一批不建立 DB table；若需 schema 草案，需標示 manual-only。 |
| MySQL writer | `src/HS.DeviceControl.Infrastructure.MySql` | 延後到第二批，需另行確認 audit table / DDL / manual DB write。 |

## 6. 測試基準

| 測試 | 結果 |
|---|---|
| `dotnet test tests\HS.DeviceControl.Application.Tests\HS.DeviceControl.Application.Tests.csproj --no-restore` | 57 passed / 0 failed / 0 skipped |
| `dotnet test tests\HS.DeviceControl.Infrastructure.MySql.Tests\HS.DeviceControl.Infrastructure.MySql.Tests.csproj --no-restore` | 89 passed / 0 failed / 0 skipped |
| `dotnet test HS.DeviceControl.sln --no-restore` | 516 passed / 0 failed / 0 skipped |

備註：測試在 sandbox 內第一次被 OneDrive `obj` cache 寫入權限擋下，提升執行後通過。solution tests 仍出現既有 `.NET 5.0` EOL warning，非 5C 文件節點造成。

## 7. 驗收策略

| 驗收項目 | 預期證據 |
|---|---|
| audit event contract | 單元測試確認必要欄位、合法事件、錯誤碼與 UTC 時間。 |
| 資料最小化 | 測試確認 secret、connection string、完整路徑、正式 IP、raw payload 會被拒絕或遮蔽。 |
| fake writer | 測試確認記錄成功、失敗、查詢最後一筆與清空，不碰真實 DB。 |
| DB 停止線 | 掃描確認第一批不新增 DDL、ALTER TABLE、formal Apply、real DB write。 |
| 與既有 plugin 流程銜接 | PluginLoader / external DLL manual-only 可產生 audit request，但不觸發 DB 寫入。 |
| 文件同步 | README、docs README、status / progress 與 public 鏡像同步。 |

## 8. 明確排除

- 不新增正式 audit table。
- 不執行 DDL / ALTER TABLE / formal Apply。
- 不對真實 DB 寫入 audit record。
- 不保存 secret、token、connection string、完整檔案路徑、正式 IP、正式 port、正式帳號或 raw payload。
- 不修改 `MySqlTaskStore`、`MySqlLogWriter` 或 `MySqlTaskTraceStore` 既有 public contract。
- 不修改 WebApi auth / Swagger。
- 不修改 ServiceHost 或 Windows Service。
- 不載入外部 DLL，不掃描 plugin folder。
- 不修改 Adapter public contract。

## 9. 下一步

請先確認 [5C DB audit 實作前確認表](phase-five-c-db-audit-preimplementation-checklist.md) 七項。確認前，只能停留在文件、唯讀檢查與測試基準；確認後才可進入 5C 第一批 audit contract / fake writer 程式實作。
