# 3C Service / API 邊界分析

## 1. 文件定位

本文件是第三階段 3C「正式執行入口」的第一份邊界分析，用來釐清未來 `ServiceHost`、`WebApi`、Core、Adapters 與 Infrastructure 之間的責任分工。

本文件只做設計邊界分析，不代表已同意新增 `ServiceHost` 專案、`WebApi` 專案、API route、背景服務、認證授權套件、佇列套件、資料庫 DDL 或任何正式 DB Apply。

## 2. 3C 目標

3C 的目標不是立刻建立 Server，而是先定義正式平台入口的責任邊界，避免後續把核心流程、硬體操作、DB schema apply、HTTP controller 與背景工作混在同一層。

| 目標 | 說明 |
|---|---|
| 固定 ServiceHost 邊界 | 決定背景常駐、任務執行、重啟恢復、健康檢查與 Log 的責任。 |
| 固定 WebApi 邊界 | 決定 API 只負責輸入驗證、權限、DTO mapping 與查詢，不直接寫核心流程。 |
| 固定共用 Application Service 邊界 | 讓 ServiceHost 與 WebApi 未來可以共用任務啟動、查詢、取消、設備狀態與 schema preview 的協調層。 |
| 保留 Core / Adapter 分層 | Core 不依賴 UI / WebApi / ServiceHost；硬體仍只能透過 Adapter 操作。 |
| 建立停止線 | 在未確認前不新增專案、不改 public method 簽章、不導入套件、不執行 DDL。 |

## 3. 既有前置能力

| 前置能力 | 狀態 | 對 3C 的意義 |
|---|---|---|
| Core Workflow / TaskEngine | 已完成第一階段基礎 | ServiceHost 未來應呼叫 TaskEngine / WorkflowEngine，而不是重寫流程邏輯。 |
| Adapter contract | 已完成 `IDeviceAdapter` 與 Mock / Modbus TCP PoC | ServiceHost / WebApi 不得直接操作 PLC、COM、TCP、UDP、Modbus 或真實硬體。 |
| MySQL TaskStore / node_executions | 第二階段 A 完成 | 未來任務查詢與恢復可引用既有持久化基礎。 |
| DB LogWriter / TraceStore | 第二階段 B 完成 | 未來 API 可查 trace，但查詢需走 read-side contract。 |
| `ITaskTraceStore` | 3A 已完成 | 可作為 Debug Tool、ServiceHost、WebApi 查詢任務 trace 的共同基礎。 |
| `ManualApplyPreview` | 3B 已完成 | 未來 ServiceHost 啟動前可引用 preview，但仍不得自動 Apply。 |
| ConsoleHost | 已完成代表流程驗證 | ConsoleHost 是 Debug 入口，不等於正式 ServiceHost。 |

## 4. ServiceHost 邊界

`ServiceHost` 未來應是正式背景執行入口，負責長時間運行與任務生命週期協調，但不得把核心流程邏輯或硬體細節寫進 Host。

| 責任 | 邊界說明 |
|---|---|
| 啟動與關閉 | 載入設定、初始化必要 infrastructure、建立 adapter registry、啟動背景任務 loop。 |
| 任務執行協調 | 呼叫 Core / Application Service 執行 workflow，不在 Host 內寫 node 邏輯。 |
| 任務狀態管理 | 統一處理 pending、running、completed、failed、cancelled 等狀態。 |
| 重啟恢復 | 未來可依 TaskStore 判斷未完成任務，但策略需另行確認。 |
| 設備生命週期 | 透過 Adapter / Dispatcher 管理 Connect、Disconnect、GetStatus。 |
| Log 與 Trace | 透過既有 LogWriter / TraceStore 寫入，不在 Host 自行拼 DB SQL。 |
| 健康檢查 | 提供 host alive、DB reachable、adapter status 摘要給 WebApi 或維運查詢。 |
| Schema preview | 可在啟動前產生 `ManualApplyPreview`，但第一版不得自動 Apply。 |

ServiceHost 不應負責：

- 不寫 Workflow node 的核心流程邏輯。
- 不直接操作硬體通訊協定。
- 不直接寫 Controller / API route。
- 不執行正式 DDL 或自動 Apply。
- 不保存 DB 密碼、Token 或完整 connection string。
- 不放入案場客製流程。

## 5. WebApi 邊界

`WebApi` 未來應是遠端操作與查詢入口，負責 HTTP request / response、權限、輸入驗證與 DTO mapping。它不應直接執行 node、直接操作 Adapter 或直接碰 DB gateway。

| 責任 | 邊界說明 |
|---|---|
| API request 驗證 | 驗證必要欄位、格式、權限、操作人員與 request id。 |
| DTO mapping | API DTO 與 Core / Application Service DTO 分離，避免 DB model 或內部 model 直接外露。 |
| 任務啟動 | 呼叫共用 Application Service 建立任務或排入執行，不在 Controller 執行 workflow。 |
| 任務查詢 | 呼叫 TaskStore / TraceStore read-side service 查詢，不直接寫 SQL。 |
| 任務取消 | 透過 TaskControl service 發出 cancel request，不直接修改任務狀態。 |
| 設備狀態查詢 | 透過 DeviceStatus service 查詢 adapter status，不直接操作 adapter instance。 |
| Health check | 提供 API alive 與必要依賴狀態，但不洩漏敏感資訊。 |
| 錯誤回應 | 將 `Result` / `ErrorInfo` 轉成一致 API response，不只回傳 bool。 |

WebApi 不應負責：

- 不直接呼叫 PLC、COM、TCP、UDP、Modbus 或任何具體硬體。
- 不在 Controller 寫 Workflow node 決策。
- 不直接改任務狀態。
- 不直接執行 DB schema apply。
- 不把內部 exception、connection string 或密碼回傳給前端。
- 不在第一版新增認證授權套件，除非另行確認。

## 6. 共用 Application Service 邊界

3C 建議先定義「共用協調層」概念，再決定是否進入程式實作。這層可以讓 ServiceHost 與 WebApi 使用同一組任務控制能力，避免 Controller 與 Host 各自複製流程。

| 候選服務 | 目的 | 第一版建議 |
|---|---|---|
| TaskControlService | 啟動任務、取消任務、查詢任務狀態 | 先做文件與 contract 候選，不直接新增 public method。 |
| TaskTraceQueryService | 查詢 task trace、node execution、command execution | 可引用 3A `ITaskTraceStore` 邊界。 |
| DeviceStatusService | 查詢設備狀態、連線狀態、最後錯誤 | 需先釐清 adapter registry 與狀態快取策略。 |
| SchemaPreviewService | 啟動前 schema preview 與風險摘要 | 只允許 `ManualApplyPreview`，不得正式 Apply。 |
| HealthService | 回傳 host / API / DB / adapter 健康狀態 | 第一版可先定義回傳欄位。 |

這些服務是否放在 Core、Infrastructure、Host 共用專案或新的 Application 層，會影響 public method 簽章與專案分層，必須另行決策。

## 7. API 類型候選

以下只列候選 API 類型，不代表已確認 route、HTTP method、DTO 或權限。

| API 類型 | 目的 | 候選能力 | 第一版邊界 |
|---|---|---|---|
| Task Control API | 遠端啟動、查詢、取消任務 | 建立任務、查任務摘要、取消任務 | 不直接執行 workflow node；長時間任務不應讓 HTTP request 長時間阻塞。 |
| Task Trace API | 查詢任務 trace 與節點歷程 | 依 TaskId、時間範圍、狀態、錯誤碼查詢 | 只走 read-side contract，保留敏感資訊遮罩。 |
| Device Status API | 查詢設備連線與可用狀態 | 依 DeviceId 查狀態、最後錯誤、最後命令時間 | 不直接下硬體命令；命令執行需走 Task / Adapter 邊界。 |
| Schema Preview API | 管理者查看 schema preview | 回傳 plan hash、risk、blocked、SQL preview | 僅 preview，不 Apply；需權限與遮蔽。 |
| Health API | 維運確認服務可用 | API alive、ServiceHost alive、DB / adapter 摘要 | 不回傳密碼、完整連線資訊或敏感錯誤。 |
| Config / Workflow Query API | 查詢目前載入的 workflow / device 摘要 | read-only 設定摘要 | 第一版只建議 read-only；設定修改屬後續。 |

## 8. 資料與 DTO 邊界

| 項目 | 原則 |
|---|---|
| API DTO | 應與 DB row model、Core internal model 分離。 |
| Core model | 不依賴 WebApi attribute、HTTP status code 或 controller 類型。 |
| Error response | 應保留 `ErrorCode`、`ErrorMessage`、`TaskId`、`NodeId`、`DeviceId` 等可追蹤資訊。 |
| Sensitive data | 不回傳 password、token、secret、authorization、完整 connection string。 |
| Pagination | 查詢 API 建議延續 `Limit + 1` / `HasMore`，避免第一版做昂貴 `TotalCount`。 |
| Time format | API 對外時間建議使用 ISO 8601，並明確標示 UTC 或 local offset。 |
| Operator | 未來所有寫入或控制請求需帶操作身分，但欄位與授權來源需另行確認。 |

## 9. 任務生命週期邊界

正式 API 不應把長時間 workflow 塞在單一 HTTP request 中同步等完。第一版建議先把任務控制拆成「建立請求、取得 TaskId、查詢結果」。

| 階段 | 責任層 | 說明 |
|---|---|---|
| Request validation | WebApi | 檢查 workflow id、request id、operator、權限與參數格式。 |
| Task creation | Application Service | 建立任務紀錄或排入執行，不直接寫 HTTP controller。 |
| Execution | ServiceHost / TaskEngine | 執行 workflow、呼叫 adapter、寫 log。 |
| Query | WebApi + read-side service | 查 TaskStore / TraceStore，不直接查 DB gateway。 |
| Cancel request | WebApi + Application Service | 發出取消要求，由 TaskEngine / StateMachine 判斷合法性。 |
| Result reporting | Application Service / WebApi | 將 Result / ErrorInfo 轉成 API response。 |

## 10. 權限與安全邊界

| 項目 | 第一版分析 |
|---|---|
| 認證方式 | 尚未決定，不在本文件導入套件。 |
| 授權角色 | 至少需區分查詢、任務控制、設備控制、schema preview、系統管理。 |
| 操作人員 | API 寫入與控制請求需帶 Operator / HostName / AppVersion。 |
| 審計 | 任務啟動、取消、schema preview、設備控制需可追蹤。 |
| Secret | 不保存密碼、Token、完整 connection string 到 repo 或 API response。 |
| 外部存取 | 未確認前不開正式對外 endpoint。 |

## 11. DB 與 Schema 邊界

3C 會使用第二階段與 3A / 3B 的 DB 能力，但不得擴大成正式 DDL 或自動 Apply。

| 項目 | 邊界 |
|---|---|
| TaskStore | 可作為任務查詢與歷程來源，但正式寫入策略需跟 ServiceHost 執行流程綁定後再確認。 |
| TraceStore | 可作為 API 查詢 trace 的 read-side 來源。 |
| ManualApplyPreview | 可作為 ServiceHost 啟動前檢查或管理查詢資料。 |
| DDL Apply | 不屬於 3C 邊界分析；不得在本階段導入。 |
| DB connection | 連線資訊來源、密碼環境變數與權限需另行確認。 |
| Schema history | 仍未建立，需新的決策才能進入正式 apply history。 |

## 12. 驗證節點候選

| 驗證節點 | 驗證目的 | 前置條件 |
|---|---|---|
| ServiceHost 邊界設計確認 | 確認 ServiceHost 不寫核心流程、不直接操作硬體、不自動 Apply | 完成 3C 決策確認。 |
| WebApi 邊界設計確認 | 確認 Controller 只做 request / response 與授權，不寫 workflow | 完成 API 類型與 DTO 邊界確認。 |
| Task Control dry-run 驗證 | 未來若實作，可確認建立任務後回傳 TaskId，而非阻塞 HTTP | 需確認是否新增 Application Service contract。 |
| Device Status read-only 驗證 | 未來若實作，可確認只查狀態、不下控制命令 | 需確認 adapter status registry。 |
| Schema Preview API 驗證 | 未來若實作，可確認只回傳 preview、不 Apply | 需確認管理權限與遮蔽規則。 |

## 13. 尚待決策

| 決策 | 影響 |
|---|---|
| 是否先建立 Application Service contract | 會影響 public method 簽章與專案分層。 |
| ServiceHost 採 Console / Worker Service / Windows Service 哪種形式 | 會影響啟動方式、部署方式與維運方式。 |
| WebApi 是否獨立專案 | 會影響 solution 結構、套件、部署與權限。 |
| API 是否採同步查詢、非同步任務控制 | 會影響 TaskId、輪詢、取消與 timeout 設計。 |
| 認證授權策略 | 會影響角色、Operator、審計與正式對外風險。 |
| Device Status 來源 | 會影響 adapter registry、狀態快取、連線生命週期與錯誤回報。 |
| 是否允許 Schema Preview API | 會影響管理權限、SQL preview 外露與風險控管。 |

## 14. 停止線

本文件完成後，以下項目仍不得自動執行：

- 不新增 `ServiceHost` 專案。
- 不新增 `WebApi` 專案。
- 不新增 API route、controller、endpoint 或 middleware。
- 不新增或更換認證授權、佇列、背景服務、Web framework 套件。
- 不修改 Core / Adapter / Infrastructure public method 簽章。
- 不執行 DB 寫入、DDL、ALTER TABLE 或正式 Apply。
- 不保存密碼、Token、完整 connection string 或正式環境資訊。
- 不改程式啟動方式。
- 不導入外部 DLL、Plugin Loader 或真實硬體控制。

## 15. 建議下一步

已整理 [3C Service / API 決策確認表](service-api-decision-confirmation.md)，且使用者已同意七項決策；後續也已完成 [3C 程式 repo 結構檢查與實作前確認](service-api-code-structure-preimplementation-checklist.md)、[3C Application Service contract 草案 / 實作前確認表](service-api-application-contract-preimplementation-checklist.md) 與 [3C Application contract 決策確認紀錄](service-api-application-contract-decision-confirmation.md)。以下為本次已確認的問題；後續若進入程式實作，仍須遵守不新增 `ServiceHost` / `WebApi` 的停止線：

1. 是否同意先做 Application Service contract，而不是直接建立 WebApi controller。
2. 是否同意 ServiceHost 第一版只做背景任務協調，不處理 HTTP。
3. 是否同意 WebApi 第一版只做 request / response、權限與查詢，不直接執行 workflow。
4. 是否同意 Task Control API 採建立任務後回傳 TaskId 的模式。
5. 是否同意 Device Status API 第一版只讀狀態，不下控制命令。
6. 是否同意 Schema Preview API 只回傳 `ManualApplyPreview`，不得 Apply。
7. 是否同意未確認前不新增專案、不導入套件、不改 public method 簽章。
