cover

一個功能從需求到上線:完整走讀

流程概覽

flowchart LR
    A[需求釐清] --> B[技術設計]
    B --> C[開發準備]
    C --> D[開發]
    D --> E[Code Review]
    E --> F[CI/CD 部署]
    F --> G[上線後營運]

    style A fill:#4CAF50,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#9C27B0,color:#fff
    style E fill:#F44336,color:#fff
    style F fill:#009688,color:#fff
    style G fill:#607D8B,color:#fff

文章概覽

在本篇文章中,您將學習到:

  • 一個功能從 PM 提出到上線 Production,到底經歷了哪些階段
  • 每個階段的輸入、輸出、負責角色是什麼
  • 如何把這個系列(方法論、Infra、DevOps、Git)的文章串起來使用
  • 一張完整的 Mermaid 流程圖,視覺化整個生命週期
  • 功能上線前的最終 Checklist

我們會用一個具體的功能——「使用者可以用 Google 帳號登入」——作為貫穿全文的案例。每個階段都會拿這個功能來示範,讓你看到理論是怎麼落地的。


引言:為什麼需要這篇文章?

這個方法論系列已經寫了十篇,涵蓋系統規劃、API 設計、測試策略、事故管理、Proto 規劃、Release 流程等等。但這些文章各自獨立,讀者可能會問:這些東西到底在什麼時間點、以什麼順序被使用?

這篇文章的目的,就是把所有環節串成一條線。你可以把它想成是這個系列的「導覽地圖」——跟著一個功能走一遍,你就知道每篇文章在整個開發流程中的位置。

我們的主角功能:

作為一個使用者,我想要用 Google 帳號登入,以便不用記另一組帳號密碼。

看起來很簡單對吧?但從 PM 腦中的一句話,到使用者真的能在 Production 上按下那個「Sign in with Google」按鈕,中間要經歷的事情比你想像的多。

讓我們開始走讀。


Phase 1:需求釐清

在這個階段,你要做的事:確認「我們到底要做什麼」,交付一份需求文件(PRD)。

PM 在某次會議上說:「我們要讓使用者可以用 Google 帳號登入。」

工程師聽到這句話,第一反應不應該是打開 IDE 開始寫 code。而是要問一系列問題:

1.1 工程師該問的問題

問題為什麼要問
只支援 Google 嗎?還是未來要加 Apple、GitHub?影響架構設計。如果未來要擴展,現在就該用通用的 OAuth 抽象層
已有帳號的使用者用 Google 登入,要自動綁定嗎?帳號合併邏輯是個大坑,不先釐清會爆炸
Google 登入失敗時,使用者看到什麼?UX 層面必須定義
有沒有時程壓力?決定是先做 MVP 還是一次到位
需要支援哪些平台?Web only?還是 App 也要?技術實作完全不同

這些問題不是在刁難 PM,而是在幫整個團隊省下後續的重工時間。

1.2 需求文件(PRD)長什麼樣

一份最小可用的 PRD 應該包含:背景說明、User Story、範圍定義、驗收標準(Acceptance Criteria)。以我們的 Google 登入為例:

## PRD: Google 帳號登入
 
### 背景
目前系統只支援 Email + 密碼登入。用戶研究顯示 40% 的使用者
在註冊流程中放棄,主因是「不想再記一組帳密」。
 
### User Story
- 作為新使用者,我想用 Google 帳號一鍵註冊 + 登入
- 作為舊使用者,我想綁定 Google 帳號,下次直接用 Google 登入
- 作為管理員,我要能在後台看到哪些使用者用 Google 登入
 
### 範圍定義
- In Scope: Google OAuth 2.0 登入、帳號自動綁定(以 email 比對)、解除綁定
- Out of Scope: Apple / GitHub 登入(Phase 2)、變更 Google 帳號的 email
 
### Acceptance Criteria
1. 使用者點擊「Sign in with Google」按鈕,完成授權後自動登入系統
2. 如果系統已有相同 email 的帳號,自動綁定,不建新帳號
3. 使用者可以在設定頁解除 Google 綁定
4. Google API 不可用時,顯示友善的錯誤訊息,不影響其他登入方式
5. 登入流程全程 < 3 秒(不含 Google 授權頁面)

想了解更完整的需求收集方法,請參考 好產品的定義。一個好的需求文件,就是在強迫所有人對「做什麼」和「不做什麼」達成共識。


Phase 2:技術設計

在這個階段,你要做的事:決定「怎麼做」,交付一份技術設計文件(Technical Spec)。

需求確認了,接下來是工程師的主場。

2.1 架構決策

Google 登入的技術選項其實不多,核心是 OAuth 2.0 Authorization Code Flow。

先看完整的 OAuth 2.0 Authorization Code Flow:

sequenceDiagram
    participant U as 使用者
    participant F as Frontend
    participant B as Backend
    participant G as Google

    U->>F: 點擊 Sign in with Google
    F->>G: 導向 Google OAuth Consent
    G->>U: 顯示授權頁面
    U->>G: 同意授權
    G->>F: Redirect + Authorization Code
    F->>B: POST /api/auth/google {code}
    B->>G: 用 code 換 access_token
    G->>B: 回傳 access_token + user info
    B->>B: 查找/建立使用者、簽發 JWT
    B->>F: Set-Cookie: token (HttpOnly)
    F->>U: 登入成功,跳轉首頁

幾個關鍵決策點:

決策選擇理由
Token 格式JWT(Access Token + Refresh Token)Stateless,適合分散式架構
Token 存放位置HttpOnly Cookie防 XSS
OAuth Library後端用 Google 官方 SDK不自己造輪子
帳號綁定策略Email match 自動綁定PRD 要求,需要處理衝突情境

2.2 API 設計

根據 RESTful 最佳實踐(詳見 API 設計與認證機制),我們需要以下 endpoint:

POST /api/auth/google          # 用 authorization code 換 JWT
POST /api/auth/google/link     # 已登入使用者綁定 Google 帳號
DELETE /api/auth/google/link   # 解除 Google 帳號綁定
GET  /api/auth/me              # 取得當前使用者資訊(含綁定狀態)

API Spec 要寫進 OpenAPI 文件,前後端依此對齊。這不是可選的,這是必須的——前後端同時開發的前提,就是有一份雙方都同意的合約。

關於系統規劃的更完整方法論,請參考 系統規劃方法論


Phase 3:開發準備

在這個階段,你要做的事:準備好開發環境和分支,確保團隊可以平行開發。

3.1 專案初始化

如果這是一個全新專案,你應該從 Proto clone 出來,而不是從零開始(詳見 Proto 規劃)。Proto 已經幫你處理好:

  • 專案結構與資料夾規範
  • ESLint / Prettier / EditorConfig
  • Docker + docker-compose
  • CI/CD Pipeline 骨架
  • 環境變數管理(.env.example
  • 錯誤處理與 Log 格式
  • 測試框架設定

如果是既有專案加新功能(我們的 Google 登入案例更可能是這種),那就跳到分支策略。

3.2 分支策略

根據團隊的 Git Flow 規範(詳見 Git Flow),開一個 feature branch:

git checkout develop
git pull origin develop
git checkout -b feature/google-oauth

分支命名規範:feature/<功能名稱>。不要用 feat-1234 這種只有你自己看得懂的名字。

3.3 環境變數

Google OAuth 需要的環境變數,先加到 .env.example

GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost:3000/auth/google/callback

注意:.env.example 只放 key,不放 value。實際的 secret 透過安全的方式(如 Vault、雲端 Secret Manager)分發,絕對不進 Git。


Phase 4:開發

在這個階段,你要做的事:寫 code、寫測試、保持好的 commit 紀律。

這是整個流程中最長的階段,也是最容易失控的階段。

4.1 前後端分工

有了 Phase 2 的 API Spec,前後端可以平行開發。平行開發的關鍵在於:雙方都信任 API Spec。如果 Spec 變了,要同步通知。

4.2 寫測試

不管你是不是 TDD 的信徒,至少要寫 unit test

以我們的 Google 登入為例,後端至少要測這些:

// auth.service.spec.ts
describe('GoogleAuthService', () => {
  describe('authenticateWithGoogle', () => {
    it('should create new user when email not found', async () => {
      // Arrange: mock Google API 回傳新 email
      const mockGoogleUser = { email: 'new@gmail.com', name: 'New User' };
      googleApiMock.getUserInfo.mockResolvedValue(mockGoogleUser);
      userRepo.findByEmail.mockResolvedValue(null);
 
      // Act
      const result = await service.authenticateWithGoogle('auth-code-123');
 
      // Assert
      expect(userRepo.create).toHaveBeenCalledWith(
        expect.objectContaining({ email: 'new@gmail.com' })
      );
      expect(result.token).toBeDefined();
      expect(result.isNewUser).toBe(true);
    });
 
    it('should link to existing user when email matches', async () => {
      const existingUser = { id: 'user-1', email: 'exists@gmail.com' };
      userRepo.findByEmail.mockResolvedValue(existingUser);
      const result = await service.authenticateWithGoogle('auth-code-456');
      expect(userRepo.create).not.toHaveBeenCalled();
      expect(result.isNewUser).toBe(false);
    });
 
    it('should throw when Google returns no email', async () => {
      googleApiMock.getUserInfo.mockResolvedValue({ email: null });
      await expect(service.authenticateWithGoogle('code'))
        .rejects.toThrow(AuthenticationError);
    });
 
    it('should handle Google API timeout gracefully', async () => {
      googleApiMock.getUserInfo.mockRejectedValue(new TimeoutError());
      await expect(service.authenticateWithGoogle('code'))
        .rejects.toThrow(ExternalServiceError);
    });
  });
});

測試策略的完整方法論,請參考 測試策略。記住 Test Pyramid:unit test 多、integration test 適量、E2E test 少但關鍵路徑必須覆蓋。

4.3 Commit 規範

每個 commit 都應該遵循 Conventional Commits 規範(詳見 CommitLint):

feat(auth): add Google OAuth login endpoint
feat(auth): implement account linking by email match
feat(ui): add Google Sign-In button component
test(auth): add unit tests for Google OAuth flow
fix(auth): handle edge case when Google returns no email

好的 commit 紀錄不只是好看——它是未來 debug 和 code review 的重要線索。


Phase 5:Code Review

在這個階段,你要做的事:開 PR、接受 review、merge 進主線。

5.1 怎麼寫 PR

一個好的 PR 不是把所有 code 丟上去然後寫「please review」。它應該有明確的結構:

## Summary
實作 Google OAuth 2.0 登入功能,包含後端 API、前端元件、帳號自動綁定邏輯。
 
## 設計決策
- Token 存放在 HttpOnly Cookie(而不是 localStorage)以防止 XSS
- 帳號綁定採用 email match,當衝突時要求使用者手動確認
- OAuth state parameter 用 crypto.randomUUID() 生成,防 CSRF
 
## 測試清單
- [x] Unit Test: 12 tests passing (auth service + button component)
- [x] Integration Test: 3 tests passing (full OAuth flow with mock Google)
- [x] Manual Test: 截圖如下
 
## 相關連結
- PRD: [link]
- Tech Spec: [link]
- Figma: [link]

5.2 Reviewer 看什麼

好的 reviewer 不只看 code 有沒有 bug,還會看:

面向具體檢查項目
安全性OAuth state parameter 有沒有做 CSRF 防護?Token 有沒有設 expiry?Secret 有沒有 hardcode?
錯誤處理Google API 掛了怎麼辦?Token 過期怎麼辦?網路 timeout 怎麼辦?
邊界情境同一個 Google 帳號綁定兩個系統帳號?Google 不回傳 email 的情境?
效能JWT 有沒有放太多東西?每次 request 都打 Google API 驗證嗎?
可維護性未來加 Apple / GitHub 登入時,現在的架構好擴展嗎?
測試覆蓋關鍵路徑都有測到嗎?有沒有只測 happy path?

Code Review 的完整方法論,未來會寫在 Code Review 方法論


Phase 6:CI/CD 與部署

在這個階段,你要做的事:確保 Pipeline 全綠,部署到各環境。

6.1 Pipeline 跑什麼

PR merge 之後(或甚至在 PR 階段),CI/CD Pipeline 會自動執行:

flowchart LR
    L[Lint] --> UT[Unit Test]
    UT --> IT[Integration Test]
    IT --> B[Build]
    B --> DD[Deploy Dev]
    DD --> E2E[E2E Test]
    E2E --> DS[Deploy Staging]
    DS --> QA[Manual QA]
    QA --> DP[Deploy Production]

    style L fill:#FFD54F,color:#333
    style UT fill:#81C784,color:#333
    style IT fill:#64B5F6,color:#333
    style B fill:#BA68C8,color:#fff
    style DD fill:#FF8A65,color:#333
    style E2E fill:#4DB6AC,color:#333
    style DS fill:#9575CD,color:#fff
    style QA fill:#F06292,color:#fff
    style DP fill:#E53935,color:#fff

每個步驟的具體內容:

步驟做什麼失敗的後果
LintESLint + Prettier 檢查格式不一致、潛在錯誤
Unit Test跑所有 unit test邏輯錯誤
Integration TestAPI 層級測試(含 DB)元件整合問題
Build編譯 + 打包編譯錯誤、依賴問題
E2E TestPlaywright / Cypress 跑使用者流程斷裂
Deploy to Staging部署到預發環境環境差異問題
Manual QAPM / QA 手動驗收UX 不符預期

CI/CD 的完整設計,請參考 CD

6.2 環境分離

對 Google 登入來說,不同環境要用不同的 Google OAuth credentials:

環境Google Client IDRedirect URI用途
Devdev-client-idhttp://localhost:3000/callback本地開發
Stagingstaging-client-idhttps://staging.example.com/callbackQA 驗收
Productionprod-client-idhttps://example.com/callback正式環境

環境分離的完整策略,請參考 環境分離

重點:絕對不要用 Production 的 Google credentials 來跑測試


Phase 7:上線後

在這個階段,你要做的事:確認功能正常運作,準備好出事時的應對方案。

功能上線了,但工作還沒結束。上線才是真正的開始。

7.1 監控與告警

指標正常值告警閾值說明
Google OAuth 成功率> 95%< 90%低於這個值代表 Google API 或我們的 callback 有問題
登入 API 回應時間(p99)< 500ms> 1000msOAuth flow 本身有網路延遲,但不應該太慢
JWT 簽發失敗率0%> 0.1%任何簽發失敗都是嚴重問題

監控的完整建置方法,請參考 監控

7.2 Log 追蹤

每一次 Google 登入,都應該留下可追蹤的 log。關鍵:每個 request 都要有 traceId,這樣當使用者回報問題時,你可以用這個 ID 把前端、後端、Google API 的整條路徑串起來。

一個好的登入 log 應該長這樣:

{
  "timestamp": "2025-02-09T10:23:45.123Z",
  "level": "info",
  "traceId": "abc-123-def-456",
  "event": "google_oauth_login",
  "userId": "user_789",
  "action": "account_linked",
  "googleEmail": "user@gmail.com",
  "isNewUser": false,
  "latencyMs": 342,
  "metadata": {
    "provider": "google",
    "clientVersion": "1.2.0",
    "userAgent": "Mozilla/5.0..."
  }
}

這種 structured log 讓你可以輕鬆查詢:「過去一小時有多少登入失敗?」「這個使用者的登入路徑是什麼?」而不是在茫茫多的文字 log 裡撈針。

Log 管理的完整策略,請參考 Log 管理

7.3 如果出事了

上線第二天,告警響了:Google 登入成功率從 97% 掉到 60%。

這時候就是事故管理流程登場的時候(詳見 事故管理):

  1. 確認影響範圍:只有 Google 登入受影響,還是整個登入系統都掛了?
  2. 檢查 Log:用 traceId 追蹤失敗的 request
  3. 快速判斷:是我們的 code 有 bug?是 Google API 在維護?是 SSL 憑證過期了?
  4. 應急處理:如果是我們的問題,考慮 rollback 到上一個版本
  5. Post-mortem:事後寫檢討報告,確保同樣的問題不會再發生

如果你有完善的 Debug 方法論,步驟 2 和 3 會快很多。系統化的除錯流程,讓你不會在恐慌中亂試。


完整流程圖

把上面七個階段串在一起:

flowchart TD
    subgraph Phase1["Phase 1:需求釐清"]
        A1[PM 提出需求] --> A2[工程師提問釐清]
        A2 --> A3[撰寫 PRD]
        A3 --> A4[團隊 Review PRD]
    end
    subgraph Phase2["Phase 2:技術設計"]
        B1[架構決策] --> B2[API Spec 設計]
        B2 --> B3[撰寫 Technical Spec]
        B3 --> B4[Tech Lead Review]
    end
    subgraph Phase3["Phase 3:開發準備"]
        C1[建立 Feature Branch] --> C2[設定環境變數]
        C2 --> C3[前後端確認 API 合約]
    end
    subgraph Phase4["Phase 4:開發"]
        D1[前後端平行開發] --> D2[撰寫 Unit Test]
        D2 --> D3[遵守 Commit 規範]
    end
    subgraph Phase5["Phase 5:Code Review"]
        E1[開 Pull Request] --> E2[Reviewer 檢查]
        E2 --> E3[修改 and Approve]
        E3 --> E4[Merge]
    end
    subgraph Phase6["Phase 6:CI/CD 部署"]
        F1[Pipeline 自動執行] --> F2[Deploy to Dev]
        F2 --> F3[Deploy to Staging]
        F3 --> F4[QA 驗收]
        F4 --> F5[Deploy to Production]
    end
    subgraph Phase7["Phase 7:上線後營運"]
        G1[監控指標] --> G2[Log 追蹤]
        G2 --> G3[告警機制]
        G3 --> G4[事故處理]
    end
    Phase1 --> Phase2
    Phase2 --> Phase3
    Phase3 --> Phase4
    Phase4 --> Phase5
    Phase5 --> Phase6
    Phase6 --> Phase7

Checklist:功能上線前的最後確認

在你按下「Deploy to Production」之前,過一遍這個清單:

需求與設計

  • PRD 已經過 PM 和工程師共同 review
  • 所有 acceptance criteria 都有對應的測試
  • Technical Spec 已經過 Tech Lead review
  • API Spec 前後端已對齊,沒有歧義

程式碼品質

  • 所有 unit test 通過
  • Integration test 通過
  • E2E test 覆蓋關鍵路徑(登入成功、登入失敗、取消授權)
  • Code Review 已通過,無 blocker 等級的 comment
  • 沒有 hardcoded secret 或 credential
  • 錯誤處理覆蓋所有已知的邊界情境

CI/CD 與部署

  • CI Pipeline 全綠(lint + test + build)
  • Staging 環境已部署且 QA 通過
  • 環境變數在 Production 已正確設定
  • 資料庫 migration 已準備好(如果有的話)
  • Rollback 計畫已確認(知道怎麼退版)

監控與運維

  • 監控 Dashboard 已建好,關鍵指標有圖表
  • 告警規則已設定(成功率、回應時間、錯誤率)
  • Log 格式正確,包含 traceId
  • Runbook 已更新
  • On-call 工程師知道這個功能即將上線

溝通與文件

  • Release Note 已撰寫
  • 相關的內部文件已更新(API 文件、架構圖)
  • PM / stakeholder 已通知上線時程
  • 如果是 breaking change,下游團隊已同步

回顧:每個階段對應的文章

Phase對應文章核心觀念
需求釐清好產品的定義需求不只是功能列表,要定義「好」的標準
技術設計系統規劃結構化的設計流程,避免「邊做邊想」
技術設計API 設計RESTful 最佳實踐、OAuth、JWT
開發準備Proto 規劃不從零開始,用 Proto 加速
開發準備Git Flow分支策略決定團隊協作效率
開發測試策略Test Pyramid,至少寫 unit test
開發CommitLintCommit 規範不是潔癖,是溝通工具
Code ReviewCode Review 方法論(即將推出)Review 不只找 bug,更看設計與可維護性
CI/CD 部署CD自動化是品質的保證
CI/CD 部署環境分離Dev / Staging / Production 各司其職
上線後監控沒有監控 = 瞎子開車
上線後Log 管理出事時,Log 是你唯一的線索
上線後事故管理出事不可怕,沒有流程才可怕
上線後Debug 方法論系統化除錯,不怕線上事故
Release 流程Release 方法論Feature Freeze / QA / Staging / Production

延伸閱讀

方法論系列

Infra 系列

DevOps 系列

Git 系列


結語

一個「使用者可以用 Google 帳號登入」的功能,從 PM 腦中的一個念頭,到使用者真的能在 Production 上按下那個按鈕,中間經歷了七個階段、牽涉到至少十幾篇文章中的知識。

這不是在說每個功能都要搞這麼大的陣仗。小功能可以壓縮流程,但每個階段的思考不能省略——需求要釐清、設計要思考、測試要寫、review 要做、部署要自動化、監控要到位。

差別只在於:小功能可能每個階段花五分鐘思考,大功能每個階段花一週。但流程是一樣的。

方法論不是枷鎖,是護欄。 它不會讓你走得更慢,它會讓你走得更穩。