3D Application contract 草案 / 實作前確認表
本文件承接 3D contract 草案 / 實作前確認表、3D contract 決策確認表、3D 程式 repo 結構檢查與實作前確認 與 3D 程式 repo 結構檢查線上驗收紀錄,把 3D 第一版真正進入 HS.DeviceControl.Application 前需要確認的候選檔案、contract 名稱、測試策略與停止線整理成可逐項確認的表格。
本文件只整理 Application contract 草案與實作前確認,不修改程式 repo,不載入外部 DLL,不建立 Plugin Loader,不修改 Adapter public contract,不修改 config schema,不新增 ServiceHost / WebApi,也不執行 DB 寫入、DDL 或正式 Apply。
0. 確認狀態
| 項目 | 內容 |
| 文件狀態 | 已確認 |
| 整理日期 | 2026-06-05 |
| 確認日期 | 2026-06-06 |
| 對應階段 | 第三階段 3D Plugin / 多設備單元 |
| 程式 repo | hs-device-control-template |
| 程式 branch | poc/nmodbus-tcp |
| 程式 commit | aee6ab6a2c3818ecdd244ce7f1db01d763ed4a14 |
| 程式 repo 狀態 | 唯讀盤點完成,工作樹乾淨 |
| 本次目標 | 確認 3D 第一版 Application contract 候選範圍 |
| 本次不做 | 不改程式、不新增 route、不載入 DLL、不建立 Plugin Loader、不改 Adapter / config / DB |
| 使用者確認 | 已確認第 10 節七項決策 |
1. 第一版定位
3D Application contract 第一版的目標,是在既有 HS.DeviceControl.Application 專案中先建立多設備單元、資源占用、命令規劃與 Plugin metadata 的最小 contract,讓後續程式實作有穩定邊界。
第一版仍不是完整 Plugin 平台,也不是正式排程器。它只做可測試、可回退、可被 ServiceHost / WebApi 未來共用的 Application 層 contract。
| 原則 | 說明 |
| Application 層承接 | 3D 第一版候選只放 HS.DeviceControl.Application 與 HS.DeviceControl.Application.Tests。 |
| Core 保持乾淨 | 不把 ControlUnit、Plugin metadata、Resource Lock 或 Command Plan 寫入 Core。 |
| Adapter contract 不變 | 不修改 IDeviceAdapter、DeviceCommand、ExecuteResult public contract。 |
| Config schema 不變 | 不改 devices.json / workflows.json schema,不導入 schema migration。 |
| 先規劃再執行 | 第一版 Commands 只做 command plan / validation,不執行命令、不建立背景 queue。 |
| Plugin 只做 metadata | 不掃描資料夾、不讀 DLL、不使用 Assembly.Load。 |
2. 既有 Application 風格
目前程式 repo 已有 HS.DeviceControl.Application,可作為 3D 延伸基準。
| 既有區塊 | 現況 | 3D 延伸方式 |
Tasks | TaskControlService、request / result DTO、ITaskControlService | 保持任務啟動 / 查詢 / 取消邊界,不把 Resource Lock 寫入 Task service。 |
Devices | DeviceStatusService、IDeviceStatusService | 可供 ControlUnit status 彙總參考,但不直接呼叫 Execute()。 |
Schema | SchemaPreviewService 包裝 ManualApplyPreview | 保持 preview-only,不把 plugin/config apply 混進 schema preview。 |
Health | HealthService 與 dependency check | 3D 可補 read-only catalog health,但不暴露 secret。 |
Common | ApplicationErrorCodes 已有 APP-0001 至 APP-0005 | 3D 可新增 Application 層錯誤碼,不改 Core error contract。 |
| Tests | Application.Tests 使用 xUnit 與 fake / in-memory | 3D 第一版測試也應使用 fake / in-memory,不連 DB、不載入 DLL。 |
3. 第一版候選檔案
以下候選檔案只有在使用者確認第 10 節七項決策後,才可進入程式 repo 實作。
| 區塊 | 候選檔案 | 用途 | 是否本次新增程式 |
| ControlUnits | src/HS.DeviceControl.Application/ControlUnits/IControlUnitCatalogService.cs | 查詢多設備單元 catalog。 | 否 |
| ControlUnits | src/HS.DeviceControl.Application/ControlUnits/ControlUnitDefinition.cs | 定義單元、站位、設備綁定摘要。 | 否 |
| ControlUnits | src/HS.DeviceControl.Application/ControlUnits/ControlUnitDeviceBinding.cs | 定義 ControlUnitId / StationId / DeviceId / ResourceId 關係。 | 否 |
| ControlUnits | src/HS.DeviceControl.Application/ControlUnits/ControlUnitStatusQuery.cs | 查詢單元狀態。 | 否 |
| ControlUnits | src/HS.DeviceControl.Application/ControlUnits/ControlUnitStatusResult.cs | 回傳單元狀態與設備摘要。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/IResourceLockService.cs | 定義取得、釋放與查詢 resource lock。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/ResourceDefinition.cs | 定義 resource id、名稱與適用單元。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/ResourceLockRequest.cs | 取得鎖請求。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/ResourceLockResult.cs | 取得鎖結果與標準錯誤。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/ResourceReleaseRequest.cs | 釋放鎖請求。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/ResourceReleaseResult.cs | 釋放鎖結果。 | 否 |
| Resources | src/HS.DeviceControl.Application/Resources/ResourceLockMode.cs | Exclusive / SharedRead 候選 enum。 | 否 |
| Commands | src/HS.DeviceControl.Application/Commands/IDeviceCommandPlanner.cs | 規劃設備命令,不執行命令。 | 否 |
| Commands | src/HS.DeviceControl.Application/Commands/DeviceCommandPlanRequest.cs | command plan 請求。 | 否 |
| Commands | src/HS.DeviceControl.Application/Commands/DeviceCommandPlanResult.cs | command plan 結果。 | 否 |
| Commands | src/HS.DeviceControl.Application/Commands/DeviceCommandPlanItem.cs | 單筆設備命令、resource dependency 與順序。 | 否 |
| Plugins | src/HS.DeviceControl.Application/Plugins/IPluginCatalogService.cs | 查詢 plugin metadata catalog。 | 否 |
| Plugins | src/HS.DeviceControl.Application/Plugins/PluginDescriptor.cs | 定義 plugin id、version、capability 與相容性。 | 否 |
| Plugins | src/HS.DeviceControl.Application/Plugins/PluginCapabilityDescriptor.cs | 描述支援 device type / command / adapter contract。 | 否 |
| Plugins | src/HS.DeviceControl.Application/Plugins/PluginCatalogResult.cs | 回傳 plugin catalog 查詢結果。 | 否 |
| Common | src/HS.DeviceControl.Application/Common/ApplicationErrorCodes.cs | 補 3D Application error code。 | 否 |
| Tests | tests/HS.DeviceControl.Application.Tests/* | DTO、fake service 與停止線測試。 | 否 |
4. ControlUnits contract 草案
ControlUnits 第一版只做單元、站位與設備綁定描述,不修改既有 config schema。
| Contract | 欄位 / 方法草案 |
IControlUnitCatalogService.GetStatus(ControlUnitStatusQuery query) | 查詢指定單元或全部單元狀態。 |
ControlUnitDefinition | ControlUnitId、ControlUnitName、Description、Stations、DeviceBindings、Metadata |
ControlUnitDeviceBinding | ControlUnitId、StationId、DeviceId、ResourceId、CommandNames |
ControlUnitStatusQuery | ControlUnitId、IncludeDevices、IncludeResources、Operator |
ControlUnitStatusResult | Success、ControlUnitId、Status、DeviceStatuses、ResourceStatuses、Code、Message、Error |
邊界限制:
ControlUnitId只代表平台管理單元,不是 IP、Port 或實體連線資訊。StationId只描述操作位置,不取代DeviceId。- 不把醫院藥局或案場專用規則寫入 Core。
- 第一版可用 in-memory catalog 測試,不讀正式設定檔。
5. Resources contract 草案
Resources 第一版只建立 resource lock contract 與 fake / in-memory 測試,不建立跨 process lock、不寫 DB。
| Contract | 欄位 / 方法草案 |
IResourceLockService.Acquire(ResourceLockRequest request) | 嘗試取得指定 resource。 |
IResourceLockService.Release(ResourceReleaseRequest request) | 釋放指定 lock。 |
ResourceDefinition | ResourceId、ResourceName、ControlUnitId、DeviceIds、Metadata |
ResourceLockRequest | ResourceId、Mode、OwnerTaskId、OwnerNodeId、DeviceId、CommandName、TimeoutMs、Operator |
ResourceLockResult | Success、LockId、ResourceId、Acquired、Mode、Code、Message、Error |
ResourceReleaseRequest | LockId、ResourceId、OwnerTaskId、Reason、Operator |
ResourceReleaseResult | Success、LockId、ResourceId、Released、Code、Message、Error |
ResourceLockMode | Exclusive、SharedRead |
6. Commands contract 草案
Commands 第一版建議做 DeviceCommandPlan,不是正式 Command Queue。目標是先讓命令可被規劃、驗證、標示 resource dependency,但不下硬體命令。
| Contract | 欄位 / 方法草案 |
IDeviceCommandPlanner.Plan(DeviceCommandPlanRequest request) | 產生命令計畫與 resource dependency。 |
DeviceCommandPlanRequest | TaskId、NodeId、ControlUnitId、DeviceId、CommandName、ResourceId、Operator、CorrelationId |
DeviceCommandPlanResult | Success、PlanId、Items、RequiresLock、Code、Message、Error |
DeviceCommandPlanItem | Sequence、DeviceId、CommandName、ResourceId、RequiresExclusiveLock、Metadata |
第一版停止線:
- 不新增背景 queue 或 worker。
- 不呼叫
IDeviceAdapter.Execute()。 - 不改
WorkflowEngine節點執行流程。 - 不新增 WebApi route 或 ServiceHost job。
7. Plugins contract 草案
Plugins 第一版只做 read-only metadata catalog,不建立 loader。
| Contract | 欄位 / 方法草案 |
IPluginCatalogService.List() | 回傳目前已知 plugin metadata。 |
PluginDescriptor | PluginId、PluginName、Version、Vendor、Capabilities、Compatibility、Checksum、Metadata |
PluginCapabilityDescriptor | CapabilityName、DeviceType、SupportedCommands、AdapterContractVersion |
PluginCatalogResult | Success、Plugins、Code、Message、Error |
Plugin metadata 不得包含:
- 密碼、Token、IP、Port、完整 connection string。
- 正式 DLL 絕對路徑。
- 可被未確認 loader 直接執行的 entry point。
- 案場客製流程或 UI 操作邏輯。
8. Application error code 草案
3D 第一版若進入程式實作,可只在 Application 層補錯誤碼,不改 Core。
| 錯誤代碼 | 建議常數 | 用途 |
APP-0301 | ControlUnitNotFound | 找不到指定 control unit。 |
APP-0302 | ControlUnitInvalidDefinition | control unit 定義缺少必要欄位或重複。 |
APP-0311 | ResourceNotFound | 找不到指定 resource。 |
APP-0312 | ResourceLockDenied | resource 已被占用或不允許取得。 |
APP-0321 | CommandPlanInvalid | command plan request 不合法。 |
APP-0331 | PluginMetadataInvalid | plugin metadata 不合法或缺少必要欄位。 |
9. 測試策略
| 測試節點 | 驗證目的 | 建議方式 |
| ControlUnit definition validation | 確認 ControlUnitId、StationId、DeviceId、ResourceId 必填與重複檢查。 | HS.DeviceControl.Application.Tests 單元測試。 |
| ControlUnit status read-only | 確認 status 查詢不呼叫 Adapter Execute()。 | fake adapter / fake catalog。 |
| Resource lock acquire / release | 確認同一 ResourceId 的 exclusive lock 不可重複取得,release reason 可追蹤。 | in-memory fake service。 |
| Command plan validation | 確認缺少 DeviceId / CommandName / ResourceId 會回標準錯誤。 | 不執行命令。 |
| Plugin catalog validation | 確認 plugin id、version、capability 必填,metadata 不含敏感資訊。 | 不讀 DLL。 |
| Stop-line guard | 確認本批不修改 Adapter contract、不改 config schema、不新增 Plugin Loader。 | 檔案範圍與單元測試對照。 |
10. 七項確認表
以下七項需使用者確認後,才可進入程式 repo 實作。
| 編號 | 決策項 | 建議定案 | 同意後可進入 | 停止線 |
| 1 | Application 層放置位置 | 同意 3D 第一版只新增於 HS.DeviceControl.Application 與 HS.DeviceControl.Application.Tests。 | 可新增 ControlUnits / Resources / Commands / Plugins 資料夾。 | 不改 Core、Adapters、Infrastructure、ConsoleHost。 |
| 2 | ControlUnits contract | 同意以 ControlUnitDefinition、ControlUnitDeviceBinding、ControlUnitStatusResult 作為第一版命名。 | 可實作 read-only catalog / status contract。 | 不改 config schema、不保存連線資訊。 |
| 3 | Resources contract | 同意新增 IResourceLockService 與 lock / release request-result DTO。 | 可實作 fake / in-memory resource lock 測試。 | 不建立 DB table、不做跨 process lock。 |
| 4 | Commands contract | 同意第一版只做 DeviceCommandPlan,不建立正式 Command Queue。 | 可實作 command plan / validation contract。 | 不呼叫 Adapter Execute()、不新增背景 worker。 |
| 5 | Plugins contract | 同意第一版只做 PluginDescriptor / catalog metadata。 | 可實作 read-only plugin catalog contract。 | 不建立 Plugin Loader、不載入 DLL、不掃描資料夾。 |
| 6 | Error code / tests | 同意只補 Application 層錯誤碼與 Application.Tests。 | 可新增 APP-03xx 錯誤與單元測試。 | 不改 Core error contract、不連 DB、不接硬體。 |
| 7 | 停止線 | 同意本批仍不新增 ServiceHost / WebApi、不改 Adapter public contract、不改 config schema。 | 可安全進入最小 Application contract 程式實作。 | 不保存 secret、不改啟動方式、不導入新套件。 |
建議使用者回覆格式:
3D Application contract 確認:
1. 同意
2. 同意
3. 同意
4. 同意
5. 同意
6. 同意
7. 同意
11. 仍需停止的項目
除非使用者另行明確授權,仍不得自動執行:
- 不載入外部 DLL。
- 不建立 Plugin Loader。
- 不掃描 plugin folder。
- 不新增或更換 plugin framework、queue framework、IoC framework、background service framework。
- 不修改
IDeviceAdapter、ExecuteResult、DeviceCommandpublic contract。 - 不修改
devices.json/workflows.jsonschema。 - 不新增
ServiceHost/WebApi專案、route、controller、endpoint 或 middleware。 - 不執行 DB 寫入、DDL、ALTER TABLE 或正式 Apply。
- 不保存密碼、Token、完整 connection string、IP、Port、正式 DLL 路徑或正式環境資訊。
12. 建議下一步
使用者已於 2026-06-06 確認第 10 節七項決策。下一步可參考 3D Application contract 決策確認表,再進入「3D Application contract 第一版實作前最後確認」或最小 Application contract 程式實作;仍不得超出本文件停止線。