一、第一階段 MVP 範圍
第一階段目標是先把共用控制核心做穩,讓流程可執行、可測試、可追蹤,暫時不追求完整 UI 或中央平台。
建立 C# Solution 與基本專案結構
Core Library
WorkflowNode / WorkflowEngine
StateMachine / TaskEngine
IDeviceAdapter 與 Mock Adapter
ConsoleHost
標準 Result / ErrorInfo / ErrorCode
FileLogWriter / ConsoleLogWriter / MemoryLogWriter
devices.json / workflows.json / appsettings.json 範例
Config Validator
單元測試與流程模擬測試
README.md 與 AGENTS.md 初版
二、第一階段不做事項
不做事項不是永遠不做,而是避免第一階段範圍膨脹,先讓核心骨架可用、可測、可維護。
- 不接真實硬體,只使用 Mock Adapter 驗證流程。
- 不做完整 WinForms Debug Tool,只保留後續設計方向。
- 不做正式 Web UI、中央 Server、多案場管理、報表與統計分析。
- 不導入正式資料庫,第一版以 JSON 設定與檔案 Log 為主。
- 不做完整權限系統,但保留 Operator / HostName / AppVersion Log 欄位。
- 不把案場客製邏輯寫入共用 Core。
三、交付成果
| 類別 | 交付項目 |
|---|---|
| 程式 | Core、Adapters、ConsoleHost、測試專案。 |
| 設定 | devices.json、workflows.json、appsettings.json、Config Validator。 |
| 測試 | 成功、失敗、逾時、重試、取消、設定錯誤、非法狀態轉換。 |
| 文件 | README.md、AGENTS.md、架構方向、開工規格、錯誤代碼表、Log 格式說明。 |
四、驗收標準
- Solution 可在 Visual Studio 或 dotnet CLI 編譯成功。
- ConsoleHost 可執行一個三節點以上的 Mock Workflow。
- 可重現 success、failed、timeout、retry、cancelled 五種流程結果。
- 每個節點 Log 必含 TaskId、NodeId、NodeName、Status、StartTime、EndTime、TimeTakenMs、ErrorCode。
- Config Validator 能檢查缺少必填欄位、NodeId 重複、NextNode 不存在、DeviceId 不存在。
- StateMachine 能阻擋非法狀態轉換,例如 completed 不可回到 running。
- dotnet test 可重複執行並通過。
五、技術基底與命名
| 項目 | 第一階段決策 | 說明 |
|---|---|---|
| .NET 版本 | .NET 5.0 | 依目前決策採用 .NET 5.0 作為第一階段 Core、ConsoleHost 與測試專案基底。 |
| 測試框架 | xUnit | 用於 Workflow、StateMachine、Adapter Mock、Config Validator 測試。 |
| Log 實作 | Interface + FileLogWriter | 第一版先自製簡單 Log Interface,避免過早綁定第三方套件;未來可新增 Serilog 實作。 |
| 設定格式 | JSON | 第一版使用 devices.json、workflows.json、appsettings.json。 |
| 主要 Host | ConsoleHost | 第一階段以 ConsoleHost 驗證流程、狀態、Log 與測試案例。 |
專案命名
| 專案 | 用途 |
|---|---|
| HS.DeviceControl.Core | Workflow、StateMachine、TaskEngine、Result、Error、Log Interface。 |
| HS.DeviceControl.Adapters | IDeviceAdapter、DeviceCommand、Mock Adapter 與未來設備 Adapter。 |
| HS.DeviceControl.ConsoleHost | 第一階段流程模擬與 Debug 入口。 |
| HS.DeviceControl.Core.Tests | Core、Workflow、StateMachine 測試。 |
| HS.DeviceControl.Adapters.Tests | Mock Adapter 與命令結果測試。 |
| HS.DeviceControl.WorkflowSimulation.Tests | 代表流程與整合式模擬測試。 |
六、第一個代表流程
第一階段以「燈號導引 + Sensor 驗證」作為代表流程。這個流程足以驗證設備命令、節點順序、Timeout、Retry、FailNextNode、Log 與錯誤代碼。
| 順序 | 節點 | 命令 / 驗證 | 失敗處理 |
|---|---|---|---|
| 1 | 檢查設備連線 | CheckDeviceOnline | 設備離線時回傳 DEV-0001。 |
| 2 | 開啟指定燈號 | OpenLight,Payload 指定燈號與顏色。 | 命令失敗時重試一次,仍失敗則進入 FailNextNode。 |
| 3 | 等待 Sensor 觸發 | WaitSensor,TimeoutMs 依節點設定。 | 逾時回傳 WF-0001,依 RetryCount 重試。 |
| 4 | 關閉燈號 | CloseLight。 | 關閉失敗需寫入 DEV-0002,並進入 error_handling。 |
| 5 | 回寫結果 | WriteResult 或 MockApiCallback。 | API 回寫失敗保留 RawRequest / RawResponse。 |
七、核心資料模型
| 模型 | 用途 | 重要欄位 |
|---|---|---|
| TaskDefinition | 任務模板 | TaskType、WorkflowId、Description、Version。 |
| TaskInstance | 實際執行任務 | TaskId、Status、CurrentNodeId、CreatedAt、StartedAt、EndedAt、Operator。 |
| WorkflowDefinition | 流程定義 | WorkflowId、WorkflowName、Version、StartNodeId、Nodes。 |
| WorkflowNode | 節點定義 | NodeId、NodeName、TimeoutMs、RetryCount、ExecuteCommand、SuccessNextNodeId、FailNextNodeId。 |
| DeviceCommand | 設備命令 | CommandId、DeviceId、CommandName、Payload、TimeoutMs、CorrelationId。 |
| ExecuteResult | 執行結果 | Success、Code、Message、Data、RawRequest、RawResponse、TimeTakenMs。 |
| ErrorInfo | 錯誤資料 | ErrorCode、ErrorMessage、ExceptionType、StackTrace、NodeId、DeviceId。 |
| LogEntry | Log 資料 | TaskId、NodeId、DeviceName、CommandName、Status、ErrorCode、HostName、AppVersion。 |
八、Result 標準格式
Core、Adapter、Workflow 與 TaskEngine 的回傳結果應盡量一致,避免只有 bool 或只有字串訊息,造成現場無法追蹤。
{
"Success": false,
"Code": "WF-0001",
"Message": "Node timeout",
"Data": null,
"Error": {
"ErrorCode": "WF-0001",
"ErrorMessage": "等待 Sensor 觸發逾時",
"NodeId": "N003",
"DeviceId": "SENSOR_001"
},
"TimeTakenMs": 3000
}
| 欄位 | 規則 |
|---|---|
| Success | 代表操作是否成功,不可取代 Code 與 Error。 |
| Code | 成功可用 OK;失敗必須使用標準錯誤代碼。 |
| Message | 人類可讀訊息,需能協助現場判斷。 |
| Data | 成功或部分成功時的結果資料。 |
| Error | 失敗時保存 ErrorInfo,可為 null。 |
| TimeTakenMs | 必填,用於 Debug 與效能追蹤。 |
九、Adapter 命令契約
DeviceCommand
{
"CommandId": "CMD-20260520-0001",
"DeviceId": "LED_001",
"CommandName": "OpenLight",
"Payload": { "LightNo": 1, "Color": "Green" },
"TimeoutMs": 3000,
"CorrelationId": "TASK-001-NODE-N003"
}
ExecuteResult
{
"Success": true,
"Code": "OK",
"Message": "Command completed",
"Data": { "DeviceStatus": "Online" },
"RawRequest": "...",
"RawResponse": "...",
"TimeTakenMs": 42
}
十、設定檔規格
| 檔案 | 用途 | 驗證重點 |
|---|---|---|
| devices.json | 設備清單與連線資訊 | DeviceId 不可重複;DeviceType、ConnectionType、Timeout 必填。 |
| workflows.json | 流程與節點定義 | WorkflowId、StartNodeId、Nodes 必填;NextNodeId 必須存在。 |
| appsettings.json | Log、Service、Debug、Watchdog 設定 | Log Path、KeepDays、Debug.UseMockDevice、Watchdog.TimeoutMs 必填。 |
十一、Workflow 規格
- 每個 Workflow 必須有 StartNodeId。
- 每個 NodeId 在同一 Workflow 內不可重複。
- SuccessNextNodeId / FailNextNodeId 若有值,必須指向存在的 NodeId 或保留結束代號。
- TimeoutMs 必須大於 0。
- RetryCount 不可小於 0。
- 節點不得直接寫死設備連線資訊,只能引用 DeviceId 或 CommandName。
十二、狀態轉換表
| 目前狀態 | 允許轉換 | 禁止或注意事項 |
|---|---|---|
| created | queued、cancelled | 不可直接 completed。 |
| queued | running、cancelled | 不可回 created。 |
| running | paused、completed、failed、cancelled、error_handling | 狀態轉換需由 TaskEngine 發起。 |
| paused | running、cancelled | 暫停中不可執行新節點。 |
| error_handling | failed、cancelled | 第一階段不自動復歸為 running。 |
| completed | 無 | 不可回 running。 |
| failed | 無 | 需建立新任務才能重跑。 |
| cancelled | 無 | 取消後不得再執行後續節點。 |
十三、錯誤代碼與 Log
| 代碼 | 說明 | 處理方向 |
|---|---|---|
| CFG-0001 | 設定檔缺少必填欄位。 | 指出檔案、節點與欄位名稱。 |
| CFG-0002 | Workflow NodeId 重複。 | 停止載入該 Workflow。 |
| WF-0001 | 節點執行逾時。 | 依 RetryCount 重試或走 FailNextNodeId。 |
| WF-0002 | 非法狀態轉換。 | 拒絕轉換並寫入 Error Log。 |
| DEV-0001 | 設備離線。 | 停止該命令,回傳標準 ExecuteResult。 |
| DEV-0002 | 設備命令失敗。 | 保留 RawRequest / RawResponse。 |
| SYS-0001 | 未預期例外。 | 保留 ExceptionType、Message、StackTrace。 |
十四、任務並行與安全收尾
- 同一 DeviceId 預設同一時間只允許一個命令執行。
- 不同 DeviceId 可並行,但需透過 TaskEngine 控制與 Log 追蹤。
- CancelTask 時,WorkflowEngine 必須停止後續節點,必要時呼叫 Adapter 的安全收尾命令。
- Timeout 後不得無限等待,必須進入 Retry、FailNextNode 或 error_handling。
- 未來真實硬體階段需補 Emergency Stop 與設備復歸策略。
十五、測試矩陣
| 測試情境 | 預期結果 |
|---|---|
| 三節點成功流程 | 任務 completed,每節點 success,Log 完整。 |
| 設備離線 | 回傳 DEV-0001,任務依 FailNextNodeId 處理。 |
| 節點逾時 | 回傳 WF-0001,依 RetryCount 重試。 |
| 重試後成功 | CurrentRetry 正確增加,最終 success。 |
| 重試後仍失敗 | 任務 failed 或進入 FailNextNodeId。 |
| 取消任務 | 任務 cancelled,不執行後續節點。 |
| 非法狀態轉換 | 轉換被拒絕並寫入 WF-0002。 |
| 設定檔缺欄位 | Config Validator 回報 CFG-0001。 |
十六、部署與回滾
第一階段以開發環境與 ConsoleHost 為主,仍需先建立日後部署規則。
- 版本號使用 SemVer,例如 0.1.0、0.2.0。
- 設定檔放置於 config/,Log 放置於 logs/。
- 每次交付需保留版本紀錄、修改摘要、測試結果。
- 未來 ServiceHost 階段需補 Windows Service 安裝、停止、更新、回滾流程。
十七、前導完成條件
以下項目確認完成後,才視為前導作業完成,可以正式進入第一階段實作。
架構方向文件完成並確認
第一階段開工規格完成並確認
代表流程確認為燈號導引 + Sensor 驗證
.NET 5.0、xUnit、Interface + FileLogWriter 決策確認
專案命名規範確認
核心資料模型與 Result 標準格式確認
狀態轉換表確認
測試矩陣確認
AGENTS.md 正式專案規則完成
首頁與文件可手機閱讀、可匯出 PDF
十八、AI / Codex 工作規則
新增工作規則:Codex 在回答問題、完成分析或提出建議後,需主動詢問使用者下一步要進行哪一項,除非使用者已明確指定下一步。
- 修改前先閱讀 README.md、AGENTS.md、架構方向與開工規格。
- 不得破壞 Core / Adapter / Host / Infrastructure 分層。
- 不得自行修改既有 API 路由、JSON 欄位、returnData 結構與 Log 格式。
- 不得將 UI 邏輯寫入 Core,或將硬體通訊寫入 WorkflowEngine。
- 每次程式修改後需回報新增檔案、修改檔案、測試方式、影響範圍與後續建議。
- 若需求不明確,先列出需確認問題;問完問題後,主動詢問下一步。