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

本文件記錄第三階段 3D Plugin / 多設備單元的 Application contract 第一版最小實作結果。實作範圍僅限程式 repo 的 `HS.DeviceControl.Application` 與 `HS.DeviceControl.Application.Tests`，不擴大到 Host、API、Plugin Loader、外部 DLL、Adapter public contract、config schema 或正式 DB / DDL。

## 0. 實作摘要

| 項目 | 內容 |
|---|---|
| 實作日期 | 2026-06-06 |
| 程式 repo | `hs-device-control-template` |
| 程式 branch | `poc/nmodbus-tcp` |
| 程式 commit | `a1585512a750a52e08c9bc3f2a12773b57305e0b` |
| commit 訊息 | `新增 3D Application contract 第一版` |
| GitHub Actions | `Notify docs repo status` run `27029042871`，結果 `success` |
| 實作範圍 | ControlUnits、Resources、Commands、Plugins、Application error code、Application.Tests |
| 測試結果 | Application tests 30 passed；solution tests 468 passed |
| 既有警告 | `NETSDK1138`：專案仍使用 .NET 5.0，屬既有 target framework 警告 |

## 1. 新增 Application contract

| 區塊 | 新增內容 | 第一版效果 |
|---|---|---|
| ControlUnits | `IControlUnitCatalogService`、`ControlUnitDefinition`、`ControlUnitDeviceBinding`、`ControlUnitStatusQuery`、`ControlUnitStatusResult`、`ControlUnitCatalogService` | 提供 read-only ControlUnit catalog / status contract，驗證 ControlUnit 與 Device / Resource binding 一致性。 |
| Resources | `IResourceLockService`、`ResourceDefinition`、`ResourceLockRequest`、`ResourceLockResult`、`ResourceReleaseRequest`、`ResourceReleaseResult`、`ResourceLockMode`、`InMemoryResourceLockService` | 提供 process 內 in-memory exclusive lock / release contract，未導入 DB table 或跨 process lock。 |
| Commands | `IDeviceCommandPlanner`、`DeviceCommandPlanRequest`、`DeviceCommandPlanResult`、`DeviceCommandPlanItem`、`DeviceCommandPlanner` | 建立 command plan 與 validation，排序命令但不執行 Adapter `Execute()`，未建立 queue / worker。 |
| Plugins | `IPluginCatalogService`、`PluginDescriptor`、`PluginCapabilityDescriptor`、`PluginCatalogResult`、`PluginCatalogService` | 提供 read-only plugin metadata catalog，檢查必要欄位與敏感資訊，不載入 DLL、不建立 Plugin Loader。 |
| Common | `ApplicationErrorCodes` | 新增 `APP-0301` 至 `APP-0331`，讓 3D Application contract 有獨立錯誤碼。 |

## 2. 錯誤碼

| 錯誤碼 | 常數 | 用途 |
|---|---|---|
| `APP-0301` | `ControlUnitNotFound` | 查無 ControlUnit。 |
| `APP-0302` | `ControlUnitInvalidDefinition` | ControlUnit 定義或 binding 不一致。 |
| `APP-0311` | `ResourceNotFound` | 查無 Resource。 |
| `APP-0312` | `ResourceLockDenied` | Resource 被其他 owner 鎖定，或 release 條件不符。 |
| `APP-0321` | `CommandPlanInvalid` | Command plan request / item 缺少必要欄位或順序無效。 |
| `APP-0331` | `PluginMetadataInvalid` | Plugin metadata 缺少必要欄位或包含敏感資訊。 |

## 3. 測試證據

| 驗證命令 | 結果 |
|---|---|
| `dotnet test tests\HS.DeviceControl.Application.Tests\HS.DeviceControl.Application.Tests.csproj` | 通過，30 passed，0 failed。 |
| `dotnet test HS.DeviceControl.sln` | 通過，468 passed，0 failed；出現既有 .NET 5 EOL warning。 |
| 污染字串掃描 | 未命中使用者指定的污染字串清單；文件內不列出原始污染字串。 |
| `git diff --cached --check` | 通過，無 whitespace error。 |

## 4. 停止線確認

| 停止線 | 結果 |
|---|---|
| 不新增 `ServiceHost` / `WebApi` | 符合，本次未新增 Host / API 專案、route、controller、endpoint 或 middleware。 |
| 不建立 Plugin Loader | 符合，只建立 metadata catalog，不呼叫 `Assembly.Load`。 |
| 不載入外部 DLL | 符合，沒有 plugin folder、DLL path、載入器或 sandbox。 |
| 不修改 Adapter public contract | 符合，未修改 `IDeviceAdapter`、`DeviceCommand`、`ExecuteResult`。 |
| 不修改 config schema | 符合，未修改 `devices.json`、`workflows.json`、`appsettings.json` 或 schema。 |
| 不執行 DB DDL / Apply | 符合，未新增 DB table、migration、DDL executor 或正式 Apply。 |
| 不導入新套件 / 框架 | 符合，未變更 csproj package reference。 |

## 5. 實際效果

3D 已從文件決策推進到可編譯、可測試的 Application 層 contract。ControlUnits、Resources、Commands、Plugins 都已有第一版最小服務邊界與 xUnit 驗證，後續若要進入 WebApi、ServiceHost、Plugin Loader、正式 Command Queue、跨 process Resource Lock 或 config schema，仍需另行決策確認。

## 6. 建議下一步

建議先完成文件 repo 的 3D 完成稽核、commit / push、部署查驗與線上驗收紀錄，再判定第三階段是否正式收斂完成。
