# 3C Application contract 第一版實作紀錄

本文件記錄第三階段 3C Application contract 第一版程式實作內容、驗證結果與停止線遵守狀態。

## 0. 實作狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 已完成 |
| 實作日期 | 2026-06-04 |
| 程式 repo | `hs-device-control-template` |
| 程式分支 | `poc/nmodbus-tcp` |
| 對應確認 | [3C Application contract 決策確認紀錄](service-api-application-contract-decision-confirmation.md) |
| 本次範圍 | 新增 Application 專案、Application 測試專案、Task / Device / Schema / Health contract 與第一版薄 service |
| 本次不做 | 不新增 `ServiceHost`、不新增 `WebApi`、不新增 route、不導入新套件、不執行 DB 寫入、DDL 或 Apply |

## 1. 程式修改範圍

| 類型 | 檔案 / 目錄 | 說明 |
|---|---|---|
| Solution | `HS.DeviceControl.sln` | 加入 `HS.DeviceControl.Application` 與 `HS.DeviceControl.Application.Tests`。 |
| Application 專案 | `src/HS.DeviceControl.Application/HS.DeviceControl.Application.csproj` | `net5.0`；只引用 Core / Adapters。 |
| Task | `src/HS.DeviceControl.Application/Tasks/*` | 新增 `ITaskControlService`、DTO 與 `TaskControlService`。 |
| Device | `src/HS.DeviceControl.Application/Devices/*` | 新增 `IDeviceStatusService`、DTO 與 `DeviceStatusService`。 |
| Schema | `src/HS.DeviceControl.Application/Schema/*` | 新增 `ISchemaPreviewService`、DTO 與 `SchemaPreviewService`。 |
| Health | `src/HS.DeviceControl.Application/Health/*` | 新增 `IHealthService`、健康狀態 DTO、dependency check 與 `HealthService`。 |
| Common | `src/HS.DeviceControl.Application/Common/ApplicationErrorCodes.cs` | 定義 Application 層錯誤碼。 |
| Tests | `tests/HS.DeviceControl.Application.Tests/*` | 新增 Application 第一版測試。 |

## 2. 第一版行為

### 2.1 Task Control

| 方法 | 第一版行為 | 停止線 |
|---|---|---|
| `Start(TaskStartRequest request)` | 驗證 `WorkflowId` 後建立 `TaskExecutionRecord`，狀態為 `Queued`，並保存至 `ITaskStore`。 | 不啟動背景 worker、不新增 queue、不等待完整 Workflow 完成。 |
| `GetStatus(TaskStatusQuery query)` | 透過 `ITaskStore.FindById` 讀取任務狀態與節點摘要。 | 不直接讀 MySQL implementation，不新增 WebApi route。 |
| `Cancel(TaskCancelRequest request)` | 判斷任務是否終態；終態拒絕取消，非終態只接受取消請求。 | 第一版不實作 runtime cancellation，不改 `TaskExecutionRecord` public method。 |

### 2.2 Device Status

`DeviceStatusService` 只呼叫 `IDeviceAdapter.GetStatus()`，不呼叫 `Execute()`，因此不會繞過 Task / Adapter 邊界直接下設備命令。

### 2.3 Schema Preview

`SchemaPreviewService` 只包裝既有 `SchemaManualApplyPreviewBuilder`。結果保留：

- `CanApply = false`
- `DdlExecutionAllowed = false`
- `DdlExecuted = false`

本批沒有新增 Apply gate、schema history、rollback 或任何 DDL 執行入口。

### 2.4 Health

`HealthService` 回傳 Application 與 dependency 摘要，並遮蔽常見敏感欄位，例如 `Server`、`Database`、`User Id`、`Password`、`Token`、`ConnectionString`。Dependency exception 只保留例外型別摘要，不回傳內部 stack trace。

## 3. 測試覆蓋

| 測試檔案 | 驗證重點 |
|---|---|
| `TaskControlServiceTests.cs` | Start 建立 queued task、缺少 WorkflowId 失敗、GetStatus 對應任務與節點歷程、查無任務、終態不可取消、非終態只接受取消請求。 |
| `DeviceStatusServiceTests.cs` | `GetStatus` 只讀 Adapter 狀態，不呼叫 `Execute()`；缺少 DeviceId 失敗。 |
| `SchemaPreviewServiceTests.cs` | Preview 會回傳 ManualApplyPreview 並阻擋 DDL / Apply；Inspector 失敗會保留標準錯誤；null request 失敗。 |
| `HealthServiceTests.cs` | 無 dependency 時 Healthy；敏感連線資訊遮蔽；dependency exception 不暴露 stack trace；Degraded 狀態彙整。 |

## 4. 驗證結果

| 驗證命令 | 結果 |
|---|---|
| `dotnet test tests\HS.DeviceControl.Application.Tests\HS.DeviceControl.Application.Tests.csproj` | 通過：15 passed、0 failed。 |
| `dotnet test HS.DeviceControl.sln` | 通過：453 passed、0 failed。 |

執行整體 solution 測試時出現既有 `.NET 5.0` EOL 警告 `NETSDK1138`，未影響測試結果。此警告來自目前專案已確認使用 `net5.0` 的技術決策，非本次 3C 實作新增風險。

## 5. 停止線檢查

| 停止線 | 本次結果 |
|---|---|
| 不新增 `ServiceHost` | 遵守，未新增。 |
| 不新增 `WebApi` | 遵守，未新增。 |
| 不新增 API route / controller / endpoint / middleware | 遵守，未新增。 |
| 不新增或更換核心套件、Web framework、queue、background service 套件 | 遵守，未新增。 |
| 不修改既有 Core / Adapter / Infrastructure public method 簽章 | 遵守，只新增 Application 專案與測試。 |
| 不執行 DB 寫入、DDL、ALTER TABLE 或正式 Apply | 遵守，測試只使用 in-memory / mock。 |
| 不保存密碼、Token、完整 connection string | 遵守，Health 測試已覆蓋遮蔽行為。 |
| 不改程式啟動方式 | 遵守，ConsoleHost 未修改。 |

## 6. 影響範圍

- 新增 Application 協調層，讓未來 `ServiceHost` / `WebApi` 可共用同一批 contract。
- 既有 Core、Adapters、ConsoleHost、Infrastructure.MySql 未被修改。
- 既有測試全數通過。
- 程式 repo 已於 2026-06-05 commit / push 至 `aee6ab6`。

## 7. 建議下一步

3C commit / push 前確認、程式 repo push、文件 repo push 與線上驗收已完成。建議下一步進入 3D Plugin / 多設備單元邊界分析，或另行確認真實 DB read-only ManualApplyPreview 驗證。
