❯❯ 雙軌入口:api-spec.yml(後端先行)vs .feature+ui-config.yaml(前端先行)
📍 流水線位置|【入口】 → flow → 型別 → mock → 測試 → UI → vibe → 上線

在理想的工程世界裡,專案啟動時後端總能準時交付一份完美的 API 規格文件。然而在真實的開發現場,我們最常撞見的往往是以下兩種困境:
為涵蓋這兩種開發開局,且避免「資料結構對不上而重寫」的工程損耗,本流水線於前端設計了雙軌接入機制。不論採用何種入口,不論從哪一種開局切入,進入系統後通通銜接至同一套標準化的自動化建構流程。
api-spec.yml(後端先行情境)對於後端已定義 API 規格的專案,流水線直接以 OpenAPI 規格為單一真理來源,存放於 spec/api/api-spec.yml。後續的強型別定義、Mock Server 與 API Client 均由此自動生成,前端無須自行推測資料欄位。
此為預設的優先路徑。跨團隊協作時,後端已簽署的 API 規格是雙方溝通與對接的客觀基準。
本篇的示範素材集中在第二扇門:婚禮專案正是從那裡進場。第一扇門的實戰情境(後端規格更新後的增量同步),將於 Day 13 以公司專案的案例展開。
.feature + ui-config.yaml(僅業務規格、Mock 先行情境)婚禮專案(EverAfter)採行此入口。專案啟動初期缺乏後端與 API 文件,僅具備結構化的業務行為規格。
專案於 spec/gherkin-feature/ 目錄下包含 55 個 .feature 檔案,各檔案對應明確的業務行為(例如 AddGuest、AddTable、ApproveBlessing)。內容採用 Gherkin 語法(Given / When / Then)進行描述:
Feature: 新增喜餅款式
Rule: 成功新增喜餅款式
Scenario: 成功新增喜餅款式
Given no prior events
When Admin sends AddCakeBoxType:
"""
{ "name": "經典禮盒", "isDefault": true, ... }
"""
Then the CakeBoxTypeAdded event is emitted
這段規格明確定義了系統行為:在無前置狀態下,當管理員發出「新增喜餅款式」命令時,系統必須觸發對應的事件。
仔細審視其結構:系統接收命令(AddCakeBoxType),並斷言觸發事件(CakeBoxTypeAdded)。在 DDD 領域建模中,命令代表「發起的意圖/請求」,可能因業務規則不符而被拒絕;事件代表「系統已發生的事實」,一旦成立後便不可變更。上游 Event Storming 產出的命令與事件對,正是以這種型態輸入至我們的流水線中。
過去在缺乏 API 規格時,傳統做法為於前端編寫未經約束的假資料(Mock Data)。然而,若假資料未具備合約約束,前端隨手定義的 { user_id: 1 } 在後端實作時可能變更為 { userId: "UUID" },這種隱形差異最終會在系統整合階段引發嚴重的型別與邏輯衝突。
這正是「第二扇門」要解決的核心痛點。在後端尚未實作前,我們直接將 Gherkin 規格轉化為「預先簽署的業務合約」。透過將命令(Command)與事件(Event)確立為強型別結構,使 Mock Server 能嚴格依據規格精確運作。這不僅讓前端能全速進行獨立開發,也為後續進場的後端提供了無可爭議的實作約束。
此外,這套機制有助於快速建構可互動的 Prototype 來進行需求驗證:
畢竟非技術利益相關者(Stakeholders)往往難以僅憑純文字規格想像畫面細節與操作流。若依循傳統流程(討論規格 → 等待後端 API → 前端繪製畫面 → 展示),溝通週期極長且修改成本高昂。透過第二扇門,團隊能以「業務規格正確」為基底,在短時間內生成可運行的 Prototype,作為對齊需求的客觀基準,進而縮短規格確認與會議拉扯的週期。
如 Day 03 所述,上游匯入的規格檔案標頭均包含以下註解:
# auto-generated by scripts/codegen/shared/gherkin.ts — do not edit by hand
這項標記確認檔案是由上游工具自動生成,流水線僅讀取快照而不直接修改原始規格。
針對 UI 層面,由於 .feature 僅定義業務行為而非視覺呈現,畫面配置另外抽離至 spec/ui-config/ui-config.yaml 進行設定:
project:
name: "EverAfter"
description: "Every love story deserves a beautiful EverAfter.
每段愛情,都值得擁有美好的幸福結局"
locale: "zh-TW"
這份 YAML 同樣不是工程端從零手寫的產物:PM 在 ui-config-pm.yaml 中以業務語言填寫功能需求,例如「是否需要拖拽排序」只需填 true/false;流水線透過 codegen 轉寫進 ui-config.yaml 後,工程端仍須在此檔案中完成選型與確認(如套件、實作方式),後續整條流水線也一律以 ui-config.yaml 為執行基底。
系統名稱與基礎語系皆定義於此設定檔中。這種將「業務行為」與「視覺配置」徹底解耦的架構優勢,我們會在 Day 18 的 UI 治理章節中做更深入的展現。
事實上,不論專案選擇由何種入口切入,下一步都會順暢銜接至 /feature-to-flow,將業務規格轉譯為自動化測試流程。後續從強型別衍生、Mock Server 建構、E2E 測試、UI 渲染,一路到最終的部署門禁,全數共享同一套自動化流水線。
這種將「開局型態差異」封裝在入口層的設計,帶來了極高的工程靈活性:無論你的專案是屬於擁有成熟 API 規格的大型架構(第一扇門),抑或是從零開始、快速迭代的 Side Project(第二扇門),只要跨過入口,後續整套自動化防守機制與指令集都能 100% 完全複用。
| 評估維度 | 第一扇門(API 先行) | 第二扇門(規格先行) |
|---|---|---|
| 核心輸入檔 | spec/api/api-spec.yml |
*.feature + ui-config.yaml |
| 適用情境 | 後端已有合約、跨團隊對接 | 後端未動工、前端先行 |
| 婚禮專案採行 | 否 | ✓(55 個 feature 檔) |
簡單來說,團隊的決策原則非常明確:若後端已經交付了嚴謹的 OpenAPI 規格,直接走第一扇門,避免重複定義合約;反之,若目前手頭只有業務規格且後端尚未動工,則果斷採用第二扇門,確保前端能獲得強型別合約的庇護並全速開發。
搞定入口之後,下一篇將討論進入流水線後的第一站:如何從規格中萃取「不隨 UI 變更而破壞」的底層邏輯約束(Invariants)。
📎 本篇證據|
spec/gherkin-feature/(55 個.feature檔)・spec/ui-config/ui-config.yaml