# 4C ServiceHost contract 草案 / 實作前確認表

本文件承接 [4A WebApi / ServiceHost / Plugin Loader 邊界分析](phase-four-a-boundary-analysis.md)、[第四階段 4B / 4C / 4D 執行切分表](phase-four-execution-split-plan.md)、[第四階段標準 / 文件 / 施作範圍 / 驗收條件總表](phase-four-standards-scope-acceptance.md) 與 [4B WebApi 第一版實作與 API / DB 驗收紀錄](phase-four-b-webapi-implementation-acceptance-record.md)，整理 4C ServiceHost 進入程式實作前需要確認的背景生命週期、Adapter lifecycle、Health、Log / Trace、部署模型、測試策略與停止線。

本文件已取得使用者七項確認，確認紀錄見 [4C ServiceHost 決策確認紀錄](phase-four-c-servicehost-decision-confirmation.md)。本次確認只授權程式 repo 結構檢查與最小 ServiceHost 第一版，不代表已同意 Windows Service 安裝、Worker Service 套件、外部 queue、正式 DB 啟動流程、部署設定、真實硬體控制或任何高風險啟動方式變更。

## 0. 確認狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 已確認 |
| 整理日期 | 2026-06-06 |
| 確認日期 | 2026-06-06 |
| 對應階段 | 第四階段 4C ServiceHost |
| 程式 repo | `hs-device-control-template` |
| 程式 branch | `poc/nmodbus-tcp` |
| 程式基準 commit | `9527773 新增 4B WebApi 第一版與驗收測試` |
| 目前程式狀態 | 已有 `HS.DeviceControl.Application`、`HS.DeviceControl.WebApi`；尚未建立 `HS.DeviceControl.ServiceHost` |
| 本文件可做 | 固定 ServiceHost 定位、責任邊界、停止線、候選專案、測試策略與七項確認 |
| 本文件不做 | 不新增 Windows Service 安裝、不改 public method 簽章、不改 config schema、不執行 DB DDL、不接真實硬體 |

## 1. 第一版定位

4C ServiceHost 第一版的定位是「正式背景執行入口」，負責常駐生命週期、任務協調、Adapter lifecycle、Health 與 Log / Trace 串接。它不是 HTTP API，也不是新的 Workflow engine。

| 原則 | 說明 |
|---|---|
| ServiceHost 只做背景入口 | 負責啟動、停止、常駐迴圈、健康摘要與依賴組裝。 |
| 流程仍在 Application / Core | ServiceHost 不寫 Workflow node 邏輯，不直接修改 TaskStateMachine。 |
| HTTP 仍由 WebApi 負責 | ServiceHost 不提供 Controller、route、middleware 或 Swagger。 |
| 設備仍走 Adapter 邊界 | ServiceHost 不直接操作 PLC、COM、TCP、UDP、Modbus 或真實硬體 protocol。 |
| DB 不自動 Apply | 啟動前可做非破壞性 schema preview / health check，但不得執行 DDL、ALTER 或 Apply。 |
| 第一版不等於正式部署 | 未確認部署方式、服務帳號、Secret 管理、監控與復原策略前，不可視為正式背景服務。 |

## 2. 建議專案與引用方向

若使用者確認進入程式實作，第一版建議先採「console / Generic Host 風格的背景入口」，不要直接做 Windows Service 安裝或正式部署設定。原因是第一版需要先驗證 lifecycle、停止行為、Adapter lifecycle 與 Health，不宜同時綁定作業系統服務安裝模型。

| 項目 | 建議 |
|---|---|
| 候選專案 | `src/HS.DeviceControl.ServiceHost/HS.DeviceControl.ServiceHost.csproj` |
| 候選測試專案 | `tests/HS.DeviceControl.ServiceHost.Tests/HS.DeviceControl.ServiceHost.Tests.csproj` |
| Target framework | `net5.0`，與現有 solution 一致 |
| ServiceHost 可引用 | `HS.DeviceControl.Application`、必要的 Core / Adapter contract |
| ServiceHost 不引用 | `HS.DeviceControl.WebApi`、Web controller、未確認的 Plugin Loader、未確認的正式 DB 啟動器 |
| 第一版啟動形式 | 先用 console / Generic Host 風格驗證背景 lifecycle；Windows Service 包裝另行確認 |

引用方向：

```text
HS.DeviceControl.WebApi -> HS.DeviceControl.Application
HS.DeviceControl.ServiceHost -> HS.DeviceControl.Application
HS.DeviceControl.Application -> Core / Adapters / Infrastructure contracts
```

## 3. ServiceHost 責任邊界

| 類型 | 可負責 | 不可負責 |
|---|---|---|
| Host lifecycle | `Starting`、`Running`、`Stopping`、`Stopped`、`Faulted` 狀態摘要與 graceful stop。 | 不直接修改 Task terminal state，不把錯誤吞掉。 |
| 任務協調 | 呼叫 Application task contract，協調待執行任務與取消請求。 | 不在 Host 寫 Workflow node、NextNode、Retry 或狀態機規則。 |
| Adapter lifecycle | 透過已確認的 Adapter / dispatcher 邊界做 Connect、Disconnect、GetStatus。 | 不直接寫硬體 protocol，不直接操作 UI 或真實設備連線資訊。 |
| Health | 彙整 Host alive、Application health、Adapter status、TaskStore / Schema preview 狀態。 | 不暴露 secret、connection string、IP、Port、完整 stack trace。 |
| Log / Trace | 透過既有 LogWriter / TraceStore 記錄 TaskId、NodeId、DeviceId、CommandName、Operator、HostName、AppVersion。 | 不繞過既有錯誤處理，不直接裸寫 SQL log。 |
| Schema preview | 可在啟動前或 health 中做非破壞性 preview 摘要。 | 不執行 DDL、ALTER TABLE、正式 Apply。 |
| 部署 | 第一版只記錄候選模式與停止線。 | 不新增 Windows Service 安裝、排程器、外部 queue 或正式部署腳本。 |

## 4. 背景生命週期草案

| 狀態 | 語意 | 第一版驗收重點 |
|---|---|---|
| `Starting` | Host 正在載入設定、組裝 Application service 與建立 Adapter registry。 | 啟動失敗需回傳標準錯誤並寫 log。 |
| `Running` | Host 可接受背景任務協調與 health 查詢。 | 不在 paused / stopping 狀態執行新任務。 |
| `Stopping` | Host 已停止接收新任務，正在處理停止流程。 | 需定義 in-flight 任務處理策略，不能直接吞掉取消或例外。 |
| `Stopped` | Host 已完成停止與 Adapter disconnect。 | 多次 stop 應安全，不造成重複斷線錯誤。 |
| `Faulted` | Host 啟動或執行期間遇到不可恢復錯誤。 | 需保留 ErrorCode、ExceptionType、Message 與追蹤資訊。 |

第一版 stop 行為建議採保守策略：停止接收新任務、送出取消或停止訊號、等待已確認的 Application / Core 邊界處理狀態，不在 Host 內自行改寫終態規則。

## 5. Adapter lifecycle 草案

| 項目 | 建議 |
|---|---|
| 啟動連線 | 第一版可先以 mock / in-memory Adapter 驗證 lifecycle，不接真實硬體。 |
| 連線策略 | 是否啟動時 connect all 或 lazy connect，需使用者確認後再實作。 |
| 狀態查詢 | 透過 Adapter `GetStatus` 或既有 Application device status contract。 |
| 停止斷線 | Host stop 時需確保 Adapter disconnect 被呼叫，且失敗時留下標準錯誤。 |
| 重試策略 | 不在本文件新增硬體重連策略；若需要重連、backoff、熔斷，需另行確認。 |
| 真實硬體 | 本輪禁止真實 PLC、COM、TCP、UDP、Modbus 或案場設備連線。 |

## 6. Health / Log / Trace 草案

| 類型 | 第一版建議欄位 | 注意事項 |
|---|---|---|
| Host health | `status`、`startedAtUtc`、`uptimeMs`、`lastError`、`checkedAtUtc` | 不暴露 secret 或完整 stack trace。 |
| Dependency health | Application、TaskStore、Adapter registry、Schema preview | 只回安全摘要。 |
| Task trace | `TaskId`、`WorkflowId`、`NodeId`、`Status`、`TimeTakenMs` | 透過既有 Log / Trace contract。 |
| Device trace | `DeviceId`、`CommandName`、`Status`、`ErrorCode` | 不直接記錄敏感連線資訊。 |
| Host metadata | `Operator`、`HostName`、`AppVersion`、`Source` | 需與現有 Log 規則一致。 |

## 7. DB 與 Schema 邊界

4C 可以檢查 DB / Schema readiness，但不得把 readiness check 變成自動 DDL 或正式 Apply。

| 分類 | 可執行 | 不可執行 |
|---|---|---|
| 自動測試 | ServiceHost lifecycle fake tests、Application fake service、manual gate disabled 測試。 | 不要求真實 MySQL 連線。 |
| Schema preview | 可呼叫既有 ManualApplyPreview 非破壞性流程，確認 `CanApply=False`、`DdlExecutionAllowed=False`。 | 不執行 DDL。 |
| 真實 DB | 只在另行確認測試 DB、環境變數、AllowRead / AllowWrite 與 cleanup 後執行。 | 不碰正式 DB，不保存 connection string。 |
| Host startup | 可記錄 readiness 結果並決定是否進入 `Faulted`。 | 不在啟動時自動建表、ALTER、Apply 或 cleanup。 |

## 8. 測試策略

| 測試 | 目的 | 是否本輪授權 |
|---|---|---|
| Contract 文件驗證 | 確認 4C 責任、停止線、候選檔案與七項確認已整理。 | 是 |
| ServiceHost project compile | 若進入實作，確認專案與引用方向正確。 | 待確認 |
| Lifecycle tests | 驗證 start / stop / repeated stop / faulted 行為。 | 待確認 |
| Adapter lifecycle tests | 驗證 mock adapter connect / disconnect / status。 | 待確認 |
| Health tests | 驗證 Host / Application / Adapter health 摘要。 | 待確認 |
| Log / Trace tests | 驗證 Host metadata 與錯誤資訊不遺失。 | 待確認 |
| 真實 DB tests | 只在另行確認測試 DB 與 gate 後執行。 | 否 |
| Windows Service install test | 需要 OS service 模型與權限確認。 | 否 |

## 9. 第一版候選檔案

以下只是使用者確認後的候選範圍，尚未授權修改程式 repo。

| 類型 | 候選檔案 |
|---|---|
| ServiceHost 專案 | `src/HS.DeviceControl.ServiceHost/HS.DeviceControl.ServiceHost.csproj` |
| 啟動入口 | `src/HS.DeviceControl.ServiceHost/Program.cs` |
| 背景服務 | `src/HS.DeviceControl.ServiceHost/Services/*` |
| Options / settings | `src/HS.DeviceControl.ServiceHost/Options/*`，但不改既有 config schema |
| Health / lifecycle model | `src/HS.DeviceControl.ServiceHost/Models/*` |
| 測試專案 | `tests/HS.DeviceControl.ServiceHost.Tests/*` |
| Solution | `HS.DeviceControl.sln` |
| 文件 | 決策確認表、實作紀錄、完成稽核、commit / push 前確認、驗收紀錄 |

## 10. 七項確認表

使用者已確認以下七項，可進入 4C 程式 repo 結構檢查與最小 ServiceHost 第一版實作。

| 編號 | 決策項 | 建議確認 | 實作影響 |
|---:|---|---|---|
| 1 | 4C 先以 ServiceHost contract 草案 / 實作前確認為準 | 同意後才可把本文件視為 4C 起點。 | 目前仍不改程式。 |
| 2 | ServiceHost 第一版只做背景入口，不提供 HTTP | 同意。 | HTTP route 仍屬 WebApi。 |
| 3 | 第一版採 console / Generic Host 風格，不先做 Windows Service 安裝 | 同意。 | 降低 OS service 與部署權限風險。 |
| 4 | ServiceHost 只呼叫 Application contract，不寫 Workflow / Node 邏輯 | 同意。 | 維持 Core / Application 邊界。 |
| 5 | Adapter lifecycle 先用 mock / 已確認邊界驗證，不接真實硬體 | 同意。 | 禁止真實 PLC、COM、TCP、UDP、Modbus 連線。 |
| 6 | DB / Schema 只允許非破壞性 preview / readiness，不做 DDL / Apply | 同意。 | 避免啟動時改 DB。 |
| 7 | 進入程式實作前，需先做程式 repo 結構檢查並回報新增 / 修改檔案 | 同意。 | 使用者確認後才可新增 ServiceHost 專案與測試。 |

## 11. 仍需停止的項目

即使本文件建立完成，仍不得自動執行以下項目：

- 不新增 `HS.DeviceControl.ServiceHost`。
- 不新增 Windows Service 安裝、系統服務註冊、排程服務或部署腳本。
- 不新增外部 queue、背景服務框架或正式部署套件。
- 不提供 HTTP route、Controller、middleware 或 Swagger。
- 不建立 Plugin Loader。
- 不掃描 plugin folder。
- 不載入外部 DLL。
- 不修改 Core / Adapters / Infrastructure / Application public method 簽章。
- 不修改 `devices.json` / `workflows.json` / `appsettings.json` schema。
- 不執行 DB DDL、ALTER TABLE、正式 Apply 或正式 DB 寫入。
- 不保存密碼、Token、IP、Port、完整 connection string 或正式環境資訊。
- 不接真實硬體或案場客製邏輯。

## 12. 建議下一步

建議使用者先回覆 4C 七項確認。若七項均同意，下一步再做「4C 程式 repo 結構檢查與 stage / commit 前風險盤點」，確認 `Application` contract、現有 WebApi、solution 結構與測試專案後，才決定是否新增最小 ServiceHost 第一版。
