Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 44 — FRD (Functional Requirements Document): chi tiết functional

Kiến Thức Cơ Bản BA: Thu Thập Yêu Cầu Hiệu Quả Bài 44/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn vừa bàn giao một bản BRD (Business Requirements Document) đẹp đẽ cho team phát triển. Trong đó ghi rõ: "Doanh nghiệp cần giảm tỷ lệ khách bỏ giỏ hàng từ 70% xuống còn 50% trong vòng 6 tháng." Lập trình viên đọc xong, ngẩng đầu lên hỏi bạn: "Ờ... rồi giờ em code cái gì?". Đó chính là khoảng trống mà FRD — Functional Requirements Document — sinh ra để lấp.

BRD nói về cái gì doanh nghiệp muốn và tại sao. FRD nói về hệ thống phải làm gì để đạt được điều đó. Nếu BRD là "chúng ta muốn giảm tỷ lệ bỏ giỏ hàng", thì FRD là "hệ thống phải gửi email nhắc nhở sau 1 giờ kể từ khi khách rời giỏ hàng, kèm mã giảm giá 10%, tối đa 3 lần nhắc trong 72 giờ".

Trong nghề BA, FRD là tài liệu "đắt giá" nhất theo nghĩa: nó là cầu nối trực tiếp giữa thế giới nghiệp vụ và thế giới kỹ thuật. Một FRD viết tốt giúp dev biết chính xác phải xây gì, QA biết phải test gì, và architect biết phải thiết kế hệ thống ra sao. Một FRD viết tồi sẽ sinh ra hàng tá câu hỏi qua lại, hiểu lầm, và những tính năng "đúng nhưng không trúng". Bài này sẽ giúp bạn nắm vững bản chất của FRD và viết được một FRD mà dev đọc xong là code được ngay, không cần chạy đi hỏi lại.

Khái niệm cốt lõi

FRD là gì và phục vụ ai

FRD (Functional Requirements Document — Tài liệu Yêu cầu Chức năng) là tài liệu đặc tả chi tiết hệ thống PHẢI LÀM GÌ (what the system does), chứ không phải làm như thế nào về mặt kỹ thuật (how it's implemented).

Đối tượng đọc FRD chủ yếu là:

  • Developer: để biết logic, hành vi cần code.
  • QA/Tester: để xây test case dựa trên các hành vi đã đặc tả.
  • Solution Architect: để thiết kế kiến trúc đáp ứng các chức năng.
  • BA peers và PM: để rà soát, đối chiếu với mục tiêu nghiệp vụ.
Điểm mấu chốt — và cũng là lỗi kinh điển của BA mới — là phải phân biệt rõ ranh giới whathow. FRD nói: "Hệ thống phải xác thực số điện thoại của người dùng bằng mã OTP gồm 6 chữ số, mã có hiệu lực 5 phút." FRD KHÔNG nói: "Dùng Twilio API để gửi SMS, lưu OTP trong Redis với TTL 300 giây." Phần "dùng Twilio, lưu Redis" thuộc về tài liệu thiết kế kỹ thuật (Technical Design) — đó là việc của architect và dev quyết định.

FRD nằm ở đâu trong dòng chảy tài liệu

Để định vị FRD, hãy hình dung chuỗi: Business Need → BRD → FRD → Technical Design → Code.

  • BRD trả lời "Tại sao" và "Mục tiêu nghiệp vụ là gì".
  • FRD trả lời "Hệ thống phải có những chức năng gì và mỗi chức năng cư xử ra sao".
  • Technical Design trả lời "Triển khai bằng công nghệ gì".
Trong nhiều tổ chức, đặc biệt làm theo Waterfall hoặc hybrid, FRD là tài liệu trung tâm mà BA dành nhiều thời gian nhất. Lưu ý: trong môi trường Agile thuần, FRD thường được thay thế hoặc bổ sung bằng User Stories và Acceptance Criteria (bài 46, 48 sẽ bàn). Nhưng kể cả Agile, kỹ năng tư duy theo "functional requirement" vẫn cực kỳ quan trọng khi gặp tính năng phức tạp.

Functional vs Non-functional

Một functional requirement mô tả một hành vi: hệ thống nhận input gì, xử lý ra sao, trả về output gì. Ví dụ: "Khi người dùng nhập sai mật khẩu 5 lần liên tiếp, hệ thống khóa tài khoản trong 30 phút."

Trái lại, non-functional requirement mô tả chất lượng của hệ thống: hiệu năng, bảo mật, khả năng mở rộng. Ví dụ: "Trang chủ phải tải xong trong 2 giây với 95% request." FRD tập trung vào functional, nhưng một FRD chuyên nghiệp thường có một mục riêng tham chiếu hoặc liệt kê các yêu cầu phi chức năng liên quan tới từng chức năng.

Cấu trúc một functional requirement chuẩn

Mỗi yêu cầu chức năng nên có các thành phần sau:

  • ID: mã định danh duy nhất, ví dụ FR-AUTH-001. ID giúp truy vết (traceability) về sau.
  • Tên/Mô tả: phát biểu ngắn gọn chức năng.
  • Tác nhân (Actor): ai/cái gì kích hoạt chức năng.
  • Tiền điều kiện (Precondition): trạng thái cần có trước khi chức năng chạy.
  • Luồng chính (Main flow): chuỗi hành vi khi mọi thứ suôn sẻ.
  • Luồng thay thế/ngoại lệ (Alternate/Exception flow): xử lý khi có lỗi, ngoại lệ.
  • Hậu điều kiện (Postcondition): trạng thái hệ thống sau khi hoàn tất.
  • Business rules: các quy tắc nghiệp vụ ràng buộc.
  • Tham chiếu (Source/Trace): liên kết về yêu cầu nghiệp vụ trong BRD.

Nguyên tắc "SMART" cho mỗi yêu cầu

Một yêu cầu chức năng tốt phải rõ ràng, có thể kiểm thử, không mơ hồ, đơn nhất. Hãy luôn tự hỏi: "QA có viết được test case từ câu này không?". Nếu câu đặc tả là "Hệ thống phải xử lý đơn hàng nhanh chóng và thân thiện" — đó là rác, vì không ai test được "nhanh chóng" hay "thân thiện" là bao nhiêu. Phải viết: "Hệ thống hiển thị xác nhận đơn hàng trong vòng 3 giây sau khi người dùng bấm Thanh toán."

Tình huống thực tế

Ví dụ 1 — Tiki: chức năng "Đặt lại mật khẩu"

Giả sử bạn là BA tại một sàn thương mại điện tử lớn như Tiki, và team Security yêu cầu xây tính năng "Quên mật khẩu". BRD chỉ ghi một dòng: "Người dùng phải tự khôi phục được tài khoản khi quên mật khẩu, đảm bảo an toàn."

Một BA non tay sẽ viết FRD kiểu: "Hệ thống cho phép người dùng đặt lại mật khẩu qua email." Dev đọc xong sẽ có 10 câu hỏi: Link có hết hạn không? Hết hạn bao lâu? Dùng được mấy lần? Nếu email không tồn tại thì sao?

Một BA giỏi sẽ viết:

> FR-AUTH-014 — Đặt lại mật khẩu qua email > - Actor: Người dùng đã đăng ký. > - Precondition: Người dùng đang ở màn hình đăng nhập. > - Main flow: > 1. Người dùng bấm "Quên mật khẩu", nhập email. > 2. Hệ thống kiểm tra email tồn tại trong hệ thống. > 3. Hệ thống gửi email chứa link đặt lại, link có hiệu lực 15 phút và chỉ dùng được 1 lần. > 4. Người dùng bấm link, nhập mật khẩu mới (tối thiểu 8 ký tự, có chữ hoa, số). > 5. Hệ thống cập nhật mật khẩu và vô hiệu hóa tất cả phiên đăng nhập đang hoạt động. > - Exception flow: > - 2a. Nếu email không tồn tại: hệ thống vẫn hiển thị thông báo "Nếu email tồn tại, link đã được gửi" (chống dò email). > - 3a. Nếu link đã hết hạn hoặc đã dùng: hiển thị "Link không hợp lệ, vui lòng yêu cầu lại". > - Business rule: BR-SEC-07 — không tiết lộ email có tồn tại hay không.

Bài học rút ra: Chính những exception flow và business rule mới phân biệt FRD chuyên nghiệp với mô tả sơ sài. Câu "vẫn hiển thị thông báo chung dù email không tồn tại" là một quyết định bảo mật quan trọng mà nếu BA không ghi rõ, dev có thể vô tình tạo lỗ hổng dò tài khoản.

Ví dụ 2 — Ngân hàng VPBank: chuyển khoản liên ngân hàng

Một BA tại ngân hàng đặc tả chức năng chuyển khoản liên ngân hàng qua Napas. BRD nói: "Khách hàng cá nhân chuyển tiền tới ngân hàng khác, hạn mức theo quy định." Đây là một chức năng đầy business rule, và đó là lúc FRD tỏa sáng.

BA viết yêu cầu FR-TRANS-022 với phần business rules cực kỳ chi tiết:

  • BR-01: Hạn mức một giao dịch tối đa 500 triệu VND; hạn mức ngày tối đa 1 tỷ VND.
  • BR-02: Giao dịch trên 10 triệu VND bắt buộc xác thực bằng Smart OTP (không dùng SMS OTP).
  • BR-03: Phí chuyển khoản: 0đ với giao dịch dưới 2 triệu, 0,02% (tối thiểu 5.000đ) với giao dịch lớn hơn.
  • BR-04: Ngoài giờ làm việc của Napas (sau 21h), giao dịch chuyển sang xử lý vào phiên kế tiếp và hiển thị cảnh báo cho khách.
Khi QA cầm FRD này, họ có thể tạo ngay bảng test: giao dịch 9 triệu (SMS OTP), 11 triệu (Smart OTP), 501 triệu (bị chặn vì vượt hạn mức), giao dịch lúc 21h30 (chuyển phiên sau)...

Bài học rút ra: Trong lĩnh vực ngân hàng/fintech, phần lớn "độ khó" của FRD nằm ở business rules và các ngưỡng số (threshold). BA phải làm việc sát với phòng tuân thủ (compliance) để con số chính xác. Một con số sai trong FRD — ví dụ ghi nhầm hạn mức — có thể gây hậu quả pháp lý nghiêm trọng. Đây cũng là lý do FRD trong ngân hàng thường phải qua nhiều vòng review và ký duyệt (sign-off).

Ví dụ 3 — Startup giao đồ ăn: khi FRD thiếu khiến dự án trễ 3 tuần

Một startup giao đồ ăn ở TP.HCM (gọi là "FoodGo") làm theo kiểu "vừa làm vừa nói". BA chỉ viết user story sơ sài: "Là tài xế, tôi muốn nhận đơn để giao hàng." Không có FRD chi tiết. Khi dev code xong tính năng nhận đơn, hàng loạt tình huống không được định nghĩa lộ ra trong lúc test thực địa: Nếu 2 tài xế cùng bấm nhận một đơn trong cùng tích tắc thì ai được? Nếu tài xế nhận đơn rồi tắt app thì sao? Bao lâu không phản hồi thì đơn tự động chuyển sang tài xế khác?

Vì không có ai đặc tả các luồng ngoại lệ này từ đầu, team phải họp khẩn, ra quyết định gấp, sửa code, test lại — dự án trễ 3 tuần và phát sinh một bug nghiêm trọng khi 2 tài xế cùng nhận một đơn ngoài thực tế, gây tranh chấp với khách.

Bài học rút ra: FRD không phải thủ tục giấy tờ rườm rà — nó là nơi BA suy nghĩ trước về mọi luồng ngoại lệ thay vì để dev "phát hiện" trong lúc code. Chi phí bỏ ra để viết kỹ một trang FRD luôn rẻ hơn rất nhiều so với chi phí sửa lỗi và họp khẩn về sau.

Hướng dẫn từng bước

Bước 1 — Bắt đầu từ BRD và scope. Đọc kỹ BRD, xác định mỗi mục tiêu nghiệp vụ sẽ cần những chức năng nào. Vẽ một danh sách chức năng cấp cao (feature list) trước khi đi vào chi tiết. Đừng viết FRD cho thứ nằm ngoài scope — ghi rõ phần "Out of scope" để tránh hiểu lầm.

Bước 2 — Nhóm chức năng theo module. Gom các chức năng thành nhóm logic: Authentication, Order, Payment, Notification... Mỗi nhóm sẽ có tiền tố ID riêng (FR-AUTH-, FR-PAY-). Việc này giúp tài liệu dễ đọc và dễ truy vết.

Bước 3 — Viết từng yêu cầu theo cấu trúc chuẩn. Với mỗi chức năng, điền đủ: ID, actor, precondition, main flow, exception flow, postcondition, business rules. Viết main flow dưới dạng các bước đánh số. Luôn tự hỏi sau mỗi bước: "Có thể fail ở đây không? Nếu fail thì sao?".

Bước 4 — Đặc tả input và output cụ thể. Với mỗi trường dữ liệu, ghi rõ: kiểu dữ liệu, bắt buộc hay không, ràng buộc (độ dài, định dạng, giá trị hợp lệ). Ví dụ: "Số điện thoại: bắt buộc, 10 chữ số, bắt đầu bằng 0." Có thể dùng bảng để liệt kê.

Bước 5 — Bổ sung mockup/wireframe và sơ đồ. Đính kèm wireframe (bài 32) hoặc process flow (bài 50, activity diagram) để minh họa. Một hình vẽ luồng đôi khi tiết kiệm cả trang chữ. FRD không nhất thiết toàn chữ.

Bước 6 — Liên kết traceability. Gắn mỗi FR với yêu cầu nghiệp vụ tương ứng trong BRD. Việc này chuẩn bị cho traceability matrix (bài 55), giúp đảm bảo không có yêu cầu nào bị bỏ sót và không có chức năng "thừa" không phục vụ mục tiêu nào.

Bước 7 — Review và sign-off. Tổ chức buổi walkthrough với dev, QA, architect. Hỏi thẳng: "Có chỗ nào các bạn đọc mà chưa code/test được không?". Sửa theo phản hồi, rồi xin ký duyệt chính thức để baseline tài liệu (bài 56).

Lỗi thường gặp & mẹo

Lỗi 1 — Lẫn lộn "what" và "how". Viết "Hệ thống dùng MongoDB để lưu đơn hàng" là sai — đó là việc của technical design. Mẹo: nếu câu của bạn nhắc tới công nghệ, framework, hay cấu trúc database cụ thể, hãy bỏ nó khỏi FRD.

Lỗi 2 — Bỏ quên exception flow. BA hay chỉ viết "happy path". Mẹo: với mỗi bước trong main flow, ép bản thân nghĩ ít nhất một tình huống có thể sai. Mất mạng, timeout, dữ liệu trùng, người dùng bấm nút 2 lần — đó là nơi bug ẩn nấp.

Lỗi 3 — Dùng từ mơ hồ. "Nhanh", "thân thiện", "phù hợp", "v.v.", "và những thứ tương tự" đều là kẻ thù. Mẹo: thay mọi tính từ định tính bằng con số đo được. Cấm tuyệt đối chữ "v.v." trong FRD vì nó để ngỏ vô số diễn giải.

Lỗi 4 — Một yêu cầu gộp nhiều ý. Câu "Hệ thống phải gửi email VÀ SMS khi đơn được xác nhận" nên tách thành 2 yêu cầu, vì có thể test/triển khai độc lập. Mẹo: nếu thấy chữ "và" nối hai hành vi, cân nhắc tách.

Lỗi 5 — Không cập nhật khi yêu cầu thay đổi. FRD lỗi thời còn nguy hiểm hơn không có FRD. Mẹo: gắn version, ngày cập nhật, và áp dụng change control (bài 56) cho mọi thay đổi sau khi đã baseline.

Mẹo vàng: Sau khi viết xong một yêu cầu, đưa cho một dev đọc thử trong 2 phút và hỏi "Em hiểu phải code gì chưa?". Phản hồi của họ là thước đo chất lượng FRD trung thực nhất.

Bài tập thực hành

  • Chọn một tính năng quen thuộc — ví dụ "đăng nhập bằng Google" trên một app bạn hay dùng. Viết một functional requirement đầy đủ theo cấu trúc chuẩn (ID, actor, precondition, main flow, exception flow, postcondition, business rules). Cố gắng nghĩ ra ít nhất 3 exception flow.
  • Tìm lỗi mơ hồ: Lấy câu sau và viết lại cho rõ ràng, có thể kiểm thử: "Hệ thống phải hiển thị danh sách sản phẩm một cách nhanh chóng và sắp xếp hợp lý." Hãy bổ sung con số, tiêu chí sắp xếp cụ thể, và hành vi khi không có sản phẩm nào.
  • Phân biệt what vs how: Cho 5 câu sau, đánh dấu câu nào thuộc FRD (what) và câu nào thuộc technical design (how): (a) "Hệ thống gửi OTP 6 số có hiệu lực 5 phút"; (b) "Lưu OTP trong Redis"; (c) "Khách chỉ thử sai OTP tối đa 3 lần"; (d) "Dùng RabbitMQ để xử lý hàng đợi email"; (e) "Email xác nhận gửi trong vòng 1 phút sau khi đặt hàng".
  • Viết mini-FRD: Cho một module "Giỏ hàng" của sàn TMĐT, viết FRD cho 3 chức năng: thêm sản phẩm vào giỏ, cập nhật số lượng, áp mã giảm giá. Gắn ID theo nhóm và thêm ít nhất 2 business rule cho mỗi chức năng.

Tóm tắt

FRD là tài liệu đặc tả hệ thống phải làm gì, phục vụ trực tiếp dev, QA và architect — đứng giữa BRD (cái gì/tại sao) và Technical Design (làm thế nào về kỹ thuật). Sức mạnh của một FRD tốt nằm ở ba thứ: cấu trúc rõ ràng cho từng yêu cầu (ID, actor, luồng chính, luồng ngoại lệ, business rules), ngôn ngữ chính xác có thể kiểm thử, và việc suy nghĩ trước về mọi tình huống ngoại lệ thay vì để dev phát hiện khi code.

Hãy luôn giữ ranh giới "what — không phải how": đừng để công nghệ cụ thể lọt vào FRD. Hãy diệt mọi từ mơ hồ bằng con số đo được. Hãy ép bản thân viết exception flow cho từng bước. Và hãy nhớ thước đo cuối cùng: một dev đọc xong FRD của bạn phải biết ngay phải code gì, một QA phải viết được test case ngay — không cần chạy đi hỏi lại. Khi đạt được điều đó, bạn đã viết một FRD đáng giá.