Theme / v0.21.4

Oh My Codex (OMX)

Codex CLI 工作流增強層

實戰範例

實戰範例 002:將 WCF 服務自動遷移至 ASP.NET Core Web API

實戰展示 OMX v0.21.x 如何以 $deep-interview → $ralplan → $ultragoal 的 staged flow,將老舊 WCF 服務重構為 ASP.NET Core Web API。

實戰背景

在許多企業級遺留專案中,通訊層可能依然採用了十年前的 Windows Communication Foundation (WCF) 服務。這類服務的配置極其複雜(需要大量的 XML bindings),且無法在 Linux 環境下運行。

痛點與問題描述: 我們需要將一個 C# 工控系統中的 WCF 通訊模組 PlcControlService.svc 全面升級遷移至現代的 ASP.NET Core Controller Web API。 這項改動涉及:

  1. 刪除所有 WCF 的 [ServiceContract][OperationContract] 屬性。
  2. 建立 ASP.NET Core 控制器。
  3. 修改所有呼叫了 WCF 客戶端代理(Client Proxy)的上游代碼。 這是一個龐大且需要高度一致性的修改任務。我們將向 Oh My Codex (OMX) 下達一個 $ultragoal 任務,來全自動完成這項遷移。

規格定義

本次變更計畫的 ID 為 wcf-to-webapi-migration。我們在 OpenSpec 規格中定義了以下驗收標準:

# 實戰範例 002:openspec/changes/wcf-to-webapi-migration/specs/api-migration/spec.md

## ADDED/MODIFIED Requirements

### Requirement: Modernized HTTP endpoint for PLC control
系統必須(SHALL)使用 ASP.NET Core Web API 暴露 `/api/plc/control` 端點以替代 WCF。
- 新的控制器必須(SHALL)接收 POST 請求並返回 `OperationResult`
- 舊的 WCF `.svc` 檔案必須(SHALL)被安全刪除。

#### Scenario: Verify API execution
- **WHEN** 發送 HTTP POST 請求至 `/api/plc/control`
- **THEN** 系統必須(SHALL)無錯執行,且上游 UI 專案編譯通過,改呼叫新的 HttpClient。

端到端 8 輪 AI 協作紀錄

以下是 You (開發者) 與 OMX 之間進行 API 遷移時的完整對話歷史。

── 第 1 輪:下達 $ultragoal 宣告與訪談 ──

  • You:
    omx $ultragoal "將 PlcControlService 從 WCF 遷移至 ASP.NET Core Web API,更新所有上游呼叫端"
  • AI:

    [OMX] Received $ultragoal: 遷移 WCF 至 ASP.NET Core Web API

    為了確保遷移方案的正確收斂,我將啟動 $deep-interview 需求澄清。請簡短回覆以下兩點:

    1. 控制器風格

      • [A] (推薦) 使用傳統的 ControllerBase 路由控制器。
      • [B] 使用 .NET 8 的 Minimal APIs 聲明式路由。
    2. 上游 HttpClient 注入

      • [A] 使用全域單例的 HttpClient
      • [B] 透過依賴注入 IHttpClientFactory 獲取。

    請輸入您的選擇。


── 第 2 輪:完成訪談、進入 $ralplan 審查,再生成執行任務 ──

  • You:
    我們選擇 1A(ControllerBase)與 2B(IHttpClientFactory)。先用 $ralplan 審查遷移計畫,確認後再進入 $ultragoal。
  • AI:

    收到。$ralplan 先由 Planner → Architect → Critic 檢查 WCF removal、HttpClient migration 與 rollback / acceptance evidence;此結果是 advisory,不自動取得 execution authority。

    計畫確認後,$ultragoal 建立以下執行 missions:

    • Mission 1:刪除 PlcControlService.svc 與其 IPlcControlService 的 WCF 契約標記。
    • Mission 2:建立 PlcControlController.cs 繼承自 ControllerBase
    • Mission 3:重構 UI 專案中的 PlcServiceClient,改為使用 IHttpClientFactory 發送 POST 請求。
    • Mission 4:執行建置驗證與自愈。

    任務已成功加載!我將啟動 Autopilot 自動駕駛模式。

    OMX orchestration: $deep-interview → $ralplan → $ultragoal 執行階段: Autopilot engaged. Starting Mission 1.


── 第 3 輪:執行任務 1 (刪除 WCF 契約) ──

  • You:
    請報告任務 1 的執行日誌與程式碼變更。
  • AI:

    Implementing: wcf-to-webapi-migration (Autopilot)

    正在處理任務 1/4:清除舊 WCF 契約標記。

    我已自動刪除了 PlcControlService.svc,並重構了 IPlcControlService.cs,移除了所有 [ServiceContract] 標籤:

    // src/Core/IPlcControlService.cs
    - [ServiceContract]
      public interface IPlcControlService
      {
    -     [OperationContract]
          Task<bool> ExecuteCommand(int cmdId, string params);
      }

    ✓ 任務 1 完成!自動進入任務 2。


── 第 4 輪:建立提案 ──

  • You:
    /opsx:propose "自動化將老舊 WCF 服務遷移至 Web API,重構上游 Client 呼叫"
  • AI:

    好的,提案 wcf-to-webapi-migration 已經正式在 OpenSpec 註冊!

    • proposal.md: 說明 WCF 遷移 Web API 的架構價值。
    • specs/api-migration/spec.md: 定義 Web API 曝露與 HttpClient 驗收標準。
    • tasks.md: 已與 OMX 任務清單完成同步。

    請輸入 /opsx:apply 讓 Autopilot 繼續執行任務 2「建立 Web API 控制器」。


── 第 5 輪:建立 Web API 控制器 (Task 2) ──

  • You:
    /opsx:apply
  • AI:

    Implementing: wcf-to-webapi-migration (schema: spec-driven)

    正在處理任務 2/4 (Autopilot):建立 PlcControlController.cs

    我已在 src/API/Controllers/PlcControlController.cs 中建立了現代 Web API 控制器:

    [ApiController]
    [Route("api/plc")]
    public class PlcControlController : ControllerBase
    {
        private readonly IPlcControlService _service;
        public PlcControlController(IPlcControlService service) => _service = service;
    
        [HttpPost("control")]
        public async Task<IActionResult> Control([FromBody] ControlRequest req)
        {
            var ok = await _service.ExecuteCommand(req.CmdId, req.Params);
            return Ok(new { success = ok });
        }
    }

    ✓ 任務 2 實作完成!自動進入任務 3。


── 第 6 輪:重構上游 Client 呼叫 (Task 3) ──

  • You:
    繼續任務 3,將 UI 專案中的 Client 改為 HttpClient。
  • AI:

    Implementing: wcf-to-webapi-migration

    正在處理任務 3/4 (Autopilot):重構上游 PlcServiceClient.cs

    我已將 UI 專案中的 WCF Client Proxy 完全移除,改為透過 IHttpClientFactory 發送 POST 請求:

    public class PlcServiceClient
    {
        private readonly HttpClient _client;
        public PlcServiceClient(IHttpClientFactory factory) => _client = factory.CreateClient();
    
        public async Task<bool> SendCommandAsync(int cmdId, string parameters)
        {
            var response = await _client.PostAsJsonAsync("api/plc/control", new { cmdId, params = parameters });
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadFromJsonAsync<ControlResponse>();
            return result.Success;
        }
    }

    ✓ 任務 3 實作完成!自動進入任務 4。


── 第 7 輪:執行驗收測試與自修復 (Task 4) ──

  • You:
    繼續任務 4,執行建置,確認編譯成功。
  • AI:

    Implementing: wcf-to-webapi-migration

    正在處理任務 4/4 (Autopilot):建置驗收與自修復。

    我在背景執行了 dotnet build首次建置失敗PlcServiceClient.cs(18,30): error CS0246: 找不到型別或命名空間名稱 'IHttpClientFactory'

    $plan(自動修復中): 偵測到命名空間缺失。我自動在 PlcServiceClient.cs 頂部補上了 using System.Net.Http;

    第二次建置Build Succeeded. 0 Error(s).

    ✓ 任務 4 建置成功!測試模擬發送控制指令,API 控制器順利接收並驅動 PLC,重構圓滿成功!

    已將變更同步至主規格並歸檔。

    Archive Complete

    變更計畫已成功歸檔!


── 第 8 輪:重構價值評估 ──

  • You:
    總結這次 API 遷移的價值。
  • AI:

    本次 API 遷移成功將老舊的 WCF 去除,帶來了巨大的架構紅利:

    1. 跨平台支援:去除 WCF 依賴後,系統主程式現在可以順利在 Linux 容器中進行 Docker 部署,大幅降低運維成本。
    2. 安全性提昇:改用標準的 HTTP POST 與 JSON,便於進行 OAuth2 授權認證,提高了工控系統的安全防護能力。
    3. 無痛重構:利用 OMX 的自動駕駛,僅用 3 分鐘就完成了 4 個專案的程式碼修改與編譯自愈,極大節省了人力。