
先講結論
FRD 的目標只有一個:讓拿到文件的人,不需要問你就能做出正確的東西。
做不到這個,格式再漂亮都沒用。大多數 FRD 失敗不是格式問題,而是這些情況:
- 需求寫的是「UI 長相」,不是「系統行為」
- 沒有寫例外流程,只寫了快樂路徑
- 欄位規則含糊(「輸入合法資料」這種描述毫無意義)
- 沒有優先級,開發不知道哪個先做
FRD 的定位
FRD(Functional Requirements Document)描述系統要做什麼,不描述系統怎麼做。
| 文件 | 描述的層次 |
|---|---|
| BRD | 業務要什麼、為什麼做 |
| FRD | 系統要做什麼、功能規則是什麼 |
| SDD | 技術上怎麼設計和實作 |
| API Spec | 介面的具體格式 |
FRD 的讀者是:SA / PM(撰寫)、工程師(實作依據)、QA(測試依據)、業務主管(需求確認)。
文件結構
一份完整的 FRD 包含以下結構:
1. 文件基本資訊
2. 系統概述
2.1 系統背景
2.2 使用者角色
3. 功能需求(核心)
FR-[模組]-[編號]
├─ 優先級
├─ 觸發條件
├─ 前置條件
├─ 主要流程
├─ 例外流程
├─ 欄位規則
└─ 後置條件
4. 非功能性需求
4.1 效能
4.2 安全
4.3 瀏覽器相容性
5. 系統限制與假設
6. 版本歷史
功能需求怎麼寫
命名規則
FR-[模組代碼]-[編號]
FR-AUTH-001 → 認證模組第一個功能需求
FR-ORD-003 → 訂單模組第三個功能需求
FR-INV-012 → 庫存模組第十二個功能需求
模組代碼建議 2-4 個大寫英文字母,不超過 5 個。
優先級
| 優先級 | 說明 |
|---|---|
| P1 | 上線必須有,缺了系統無法使用 |
| P2 | 重要功能,當次 Sprint 應完成 |
| P3 | 加分功能,可延後 |
五段式結構
每個功能需求用以下五個部分描述:
1. 觸發條件(Trigger)
什麼事件讓這個功能開始執行。
✓ 使用者點擊「登入」按鈕
✓ 系統每日 00:00 執行排程
✓ 管理員透過後台手動觸發
✗ 使用者要登入(太模糊)
2. 前置條件(Precondition)
執行這個功能時,系統/資料的預設狀態。
✓ 使用者帳號已存在且已驗證
✓ 訂單狀態為 pending
✓ 無(任何人都能進行這個操作)
✗ 使用者已登入(這屬於系統行為,要在主流程裡說明驗證)
3. 主要流程(Main Flow)
一步步列出正常執行的步驟,用數字編號。
1. 使用者輸入 Email + 密碼
2. 系統驗證輸入格式
3. 系統查詢資料庫確認帳號存在
4. 系統比對密碼雜湊值
5. 系統建立 Session(有效期 30 分鐘)
6. 系統回傳登入成功,導向首頁
原則:
- 每步只做一件事
- 明確說明「誰」做了「什麼」
- 不要跳步(第 1 步到第 3 步中間還有第 2 步的事)
4. 例外流程(Exception Flow / Alternative Flow)
這是 FRD 最常被忽略的部分,也是最重要的部分。系統的複雜度都藏在這裡。
例外 1:Email 格式錯誤
→ 系統顯示「Email 格式不正確」,停留在登入頁,不送出請求
例外 2:帳號不存在
→ 系統顯示「帳號或密碼錯誤」(不能透露帳號是否存在)
例外 3:密碼錯誤
→ 系統顯示「帳號或密碼錯誤」
→ 系統累計錯誤次數 +1
例外 4:連續錯誤 5 次
→ 系統鎖定帳號 30 分鐘
→ 系統顯示「帳號已鎖定,請 30 分鐘後再試」
例外 5:帳號未驗證
→ 系統顯示「Email 尚未驗證,是否重新發送驗證信?」
寫例外流程的思考框架:
- 輸入值非法 → 怎麼處理?
- 依賴的資源不存在 → 怎麼處理?
- 權限不足 → 怎麼處理?
- 第三方服務掛掉 → 怎麼處理?
- 超時/逾時 → 怎麼處理?
5. 欄位規則(Field Rules)
用表格描述每個輸入欄位的規則。
| 欄位 | 必填 | 格式 | 長度/範圍 | 其他規則 |
|---|---|---|---|---|
| 是 | Email 格式 | 最長 255 字元 | 系統內唯一值 | |
| 密碼 | 是 | 文字 | 8-20 字元 | 須含大小寫英文及數字 |
| 記住我 | 否 | Boolean | - | 預設 false;勾選後 Session 延長至 7 天 |
欄位規則的常見錯誤:
✗ 輸入合法資料 → 什麼是合法?
✗ 不超過最大字數 → 最大字數是多少?
✗ 正確的格式 → 正確格式的定義是什麼?
完整範例:訂單建立功能
FR-ORD-001 建立訂單
優先級:P1
觸發條件:使用者點擊「確認下單」按鈕
前置條件:使用者已登入 / 購物車內至少有 1 件商品
主要流程:
1. 系統驗證使用者登入狀態
2. 系統取得購物車內所有商品
3. 系統向庫存服務確認各商品庫存充足
4. 系統建立訂單記錄(狀態:pending)
5. 系統扣除各商品庫存數量
6. 系統顯示訂單確認頁,包含訂單編號
7. 系統發送「訂單建立成功」確認信至使用者 Email
例外流程:
例外 1:使用者未登入
→ 系統導向登入頁,登入後回到購物車
例外 2:購物車為空
→ 按鈕不可點擊(Grey out)
例外 3:部分商品庫存不足
→ 系統顯示「以下商品庫存不足:[商品名稱](剩餘 X 件)」
→ 訂單不建立,返回購物車,庫存不足的商品標注警告
例外 4:庫存服務無回應(逾時 3 秒)
→ 系統顯示「服務暫時無法使用,請稍後再試」
→ 訂單不建立
例外 5:訂單建立成功但發信失敗
→ 系統記錄發信失敗,加入重試佇列(不阻擋主流程)
→ 使用者仍可在「我的訂單」查詢
欄位規則:
商品數量:必填,整數,最小 1,最大 999
備注:選填,文字,最長 500 字元
後置條件:訂單狀態為 pending / 庫存已扣除 / 確認信已排程發送
非功能性需求
功能需求只描述「做什麼」,非功能性需求描述「做到什麼程度」。
效能需求
| 項目 | 指標 |
|---|---|
| 頁面載入時間 | < 2 秒(正常網路環境) |
| API 回應時間 | < 500ms(P95) |
| 並發使用者 | 支援 500 人同時操作 |
| 資料庫查詢 | 單次查詢 < 100ms |
安全性需求
- 密碼雜湊儲存(bcrypt,cost factor ≥ 12)
- Session 逾時:30 分鐘無操作自動登出
- 敏感資料傳輸使用 HTTPS
- SQL Injection / XSS 防護
- 登入錯誤不透露帳號是否存在
瀏覽器相容性
- Chrome、Firefox、Safari、Edge 最新版
- 行動裝置:iOS Safari 16+、Android Chrome 最新版
常見錯誤模式
| 錯誤 | 正確做法 |
|---|---|
| 需求描述 UI 細節(「按鈕要紅色」) | FRD 描述行為,UI 規格在設計稿 |
| 只寫快樂路徑,忽略例外 | 思考每個可能的錯誤狀態 |
| 欄位規則含糊(「正確格式」) | 明確定義允許的值/格式/長度 |
| 把實作細節寫進 FRD(「用 Redis 快取」) | 實作決策是 SDD 的範疇 |
| 需求沒有優先級 | 每個功能必須標 P1/P2/P3 |
| 沒有版本歷史 | 每次修改必須記錄變更和原因 |
輕量版 FRD(Agile 環境)
如果你的團隊用 Scrum,不需要完整的 FRD。以下是最小可用版本:
User Story:
作為 [角色],我想要 [功能],以便 [目的]
Acceptance Criteria(驗收標準):
Given [前置狀態]
When [使用者動作]
Then [系統行為]
範例:
Given 使用者已登入
When 使用者輸入正確的 Email 和密碼並點擊登入
Then 系統建立 Session 並導向首頁
例外案例:
Given 使用者輸入錯誤密碼 5 次
When 再次嘗試登入
Then 系統顯示鎖定訊息,30 分鐘後才能重試
欄位規則:(簡表)
這就夠了。能讓工程師和 QA 對需求有共同理解,就達到目的了。
