Bỏ qua và tới nội dung chính
Thiết kế contract và DSL

Scenarios trong contract giúp đội kỹ thuật và nghiệp vụ nói cùng một ngôn ngữ ra sao

Scenarios trong contract giúp kỹ thuật và nghiệp vụ chốt cùng một cách hiểu về luồng xử lý, ràng buộc và đầu ra, để contract thật sự dùng được cho thi công thay vì chỉ là tài liệu tham khảo.

Huỳnh Kim Đạt Huỳnh Kim Đạt
7 lượt xem 8 phút đọc
Scenarios trong contract giúp đội kỹ thuật và nghiệp vụ nói cùng một ngôn ngữ ra sao

TL;DR

Scenarios là cầu nối giữa nghiệp vụ và kỹ thuật trong contract. Chúng chỉ có giá trị khi được viết với phạm vi rõ, ngôn ngữ thống nhất và liên kết chặt với domain, rule, workflow, policy và API contract.

Key Takeaways

  • Scenarios giúp các bên chốt cùng một cách hiểu về tình huống nghiệp vụ cụ thể.
  • Scenarios không thay thế domain, rule, workflow, policy hay API contract mà liên kết chúng lại.
  • Một scenario dùng được cho thi công phải có mục tiêu, actor, tiền điều kiện, kích hoạt, dòng chính, ngoại lệ và hậu điều kiện.
  • Phần ảnh hưởng đến code, test và vận hành phải rõ ràng, có cấu trúc và truy vết được.
  • Contract tốt làm cho code đầu ra ít bất ngờ hơn và giảm lệch nghĩa giữa các đội.

Scenarios là phần làm cho contract trở nên sống được trong thực tế. Khi viết đúng, scenarios giúp đội kỹ thuật và đội nghiệp vụ cùng nhìn vào một tình huống cụ thể, cùng thống nhất điều gì được phép xảy ra, dữ liệu nào cần có, ai được làm gì và kết quả cuối cùng phải như thế nào. Khi viết sai, contract rất dễ biến thành giấy tờ dài dòng, đọc xong vẫn không ai chắc hệ thống sẽ chạy ra sao.

Điểm quan trọng là scenarios không dùng để kể chuyện cho hay. Chúng dùng để khóa cách hiểu. Một scenario tốt khiến người làm sản phẩm, BA, QA, developer và người vận hành đọc xong đều có thể trả lời giống nhau cho cùng một câu hỏi: trong tình huống này hệ thống phải làm gì, không làm gì và vì sao.

Scenarios đứng ở đâu trong hệ contract

Để scenarios phát huy tác dụng, cần đặt chúng đúng trong các lớp contract cốt lõi thay vì dồn mọi thứ vào một nơi.

  • Domain contract: định nghĩa khái niệm nghiệp vụ, thực thể, trạng thái, từ vựng và các bất biến cốt lõi.
  • App contract: mô tả khả năng của hệ thống ở mức use case, ai kích hoạt và đầu ra mong đợi.
  • Rule contract: ghi rõ các điều kiện, công thức, ràng buộc kiểm tra và quy tắc quyết định.
  • Workflow contract: mô tả trình tự bước, điểm chuyển trạng thái, xử lý thành công, lỗi và ngoại lệ.
  • Policy contract: xác định quyền hạn, RBAC, điều kiện phê duyệt, giới hạn truy cập và tuân thủ.
  • API contract: chốt giao diện tích hợp, schema dữ liệu vào ra, mã lỗi, idempotency và tương thích.

Scenarios không thay thế các lớp trên. Chúng là lớp liên kết để chứng minh các contract đó gặp nhau như thế nào trong một tình huống có thật. Nói ngắn gọn, domain cho ta từ vựng, rule cho ta logic, workflow cho ta trình tự, policy cho ta quyền, API cho ta điểm chạm kỹ thuật, còn scenario cho ta ngữ cảnh đủ cụ thể để các bên nói cùng một ngôn ngữ.

Khóa phạm vi và khóa ngôn ngữ để contract dùng được cho thi công

Một nguyên nhân phổ biến khiến contract vô dụng là phạm vi quá rộng. Tài liệu cố ôm toàn bộ sản phẩm, quá nhiều trường hợp, quá nhiều biến thể, dẫn tới mỗi người đọc hiểu theo một cách. Cách tốt hơn là khóa phạm vi theo từng năng lực nhỏ và từng tình huống rõ ràng.

Với mỗi scenario, nên xác định tối thiểu các phần sau:

  1. Mục tiêu: tình huống này cần đạt kết quả gì.
  2. Actor: ai tham gia, vai trò nào chịu trách nhiệm chính.
  3. Tiền điều kiện: hệ thống và dữ liệu phải ở trạng thái nào trước khi chạy.
  4. Kích hoạt: sự kiện hoặc thao tác bắt đầu scenario.
  5. Dòng chính: các bước chuẩn khi mọi thứ diễn ra bình thường.
  6. Biến thể và ngoại lệ: các nhánh sai khác có ý nghĩa nghiệp vụ.
  7. Hậu điều kiện: dữ liệu, trạng thái, log, thông báo hoặc tích hợp nào phải được tạo ra.
  8. Contract liên quan: domain, rule, workflow, policy, API nào đang được áp dụng.

Bên cạnh phạm vi, ngôn ngữ cũng phải được khóa. Nếu tài liệu vừa dùng từ kinh doanh, vừa dùng từ code, vừa dùng từ UI, khả năng lệch nghĩa là rất cao. Contract nên ưu tiên một bộ từ vựng thống nhất ở tầng domain. Ví dụ, nếu nghiệp vụ gọi là yêu cầu phê duyệt thì không nên chỗ khác gọi là task, request hay ticket mà không định nghĩa rõ. DSL contract càng phát huy giá trị khi ép được cách đặt tên và cấu trúc mô tả theo một chuẩn duy nhất.

Phần nào nên viết ngắn, phần nào bắt buộc phải rõ và có cấu trúc

Không phải phần nào trong contract cũng cần dài. Viết dài ở chỗ không cần thiết chỉ làm mờ chỗ quan trọng.

Nên viết ngắn ở các phần sau:

  • Tóm tắt bối cảnh.
  • Mô tả mục tiêu của scenario.
  • Ghi chú triển khai không ảnh hưởng tới hành vi.
  • Ví dụ minh họa phụ.

Bắt buộc phải rõ và có cấu trúc ở các phần sau:

  • Điều kiện đầu vào và trạng thái dữ liệu.
  • Quy tắc quyết định và điều kiện rẽ nhánh.
  • Quyền truy cập theo vai trò.
  • Chuyển trạng thái workflow.
  • Định dạng dữ liệu vào ra và mã lỗi API.
  • Những gì được coi là thành công, thất bại hoặc cần rollback.
  • Dấu vết phục vụ traceability như event, log nghiệp vụ, mã tham chiếu.

Nếu một phần có thể ảnh hưởng tới code đầu ra, kiểm thử đầu ra hoặc vận hành đầu ra, phần đó không nên viết mơ hồ. Đây là chỗ contract-first và traceability có ý nghĩa thật sự: cùng một mô tả phải lần được sang rule, test case, API, phân quyền và hành vi vận hành.

Lỗi thường gặp khi viết scenarios trong contract

  • Ôm hết mọi thứ vào một scenario: một scenario chứa quá nhiều nhánh sẽ làm mất khả năng dùng để đối chiếu và kiểm thử.
  • Bám sát code quá mức: contract biến thành mô tả class, method, table hoặc framework, khiến nghiệp vụ không còn đọc được.
  • Chỉ kể happy path: tài liệu đẹp nhưng không xử lý trường hợp từ chối, thiếu dữ liệu, sai quyền, quá hạn hoặc xung đột trạng thái.
  • Không tách rule khỏi workflow: người đọc không biết đâu là quy tắc nghiệp vụ ổn định, đâu là cách tổ chức quy trình có thể thay đổi.
  • Thiếu policy và RBAC contract: nghiệp vụ hiểu luồng nhưng hệ thống không rõ ai được thực hiện bước nào.
  • Thiếu API contract hoặc schema rõ ràng: các đội tích hợp dùng mỗi nơi một cấu trúc dữ liệu.
  • Dùng từ không nhất quán: cùng một khái niệm nhưng đổi tên liên tục giữa tài liệu, UI và code.

Ví dụ một contract tốt và một contract tệ khác nhau ở đâu

Contract tệ thường viết kiểu:

Khi người dùng gửi yêu cầu thì hệ thống kiểm tra rồi xử lý theo quy định. Nếu hợp lệ thì chuyển tiếp, nếu không thì báo lỗi. Quản lý có thể duyệt khi cần.

Đoạn này nghe có vẻ đúng nhưng gần như không dùng được để thi công. Không rõ người dùng là ai, hợp lệ là gì, quy định nào áp dụng, khi nào cần quản lý, trạng thái nào được chuyển, dữ liệu nào phải lưu, API nào trả lỗi gì.

Contract tốt sẽ viết theo cấu trúc rõ ràng hơn:

  • Scenario: Nhân viên tạo yêu cầu tạm ứng chi phí công tác.
  • Actor chính: Nhân viên.
  • Tiền điều kiện: Nhân viên đang hoạt động; hạn mức quý còn đủ; chuyến công tác đã được phê duyệt.
  • Kích hoạt: Nhân viên gửi biểu mẫu tạm ứng.
  • Rule contract: Số tiền không vượt quá hạn mức theo cấp bậc; hóa đơn dự kiến là bắt buộc nếu vượt ngưỡng X.
  • Policy contract: Nhân viên được tạo yêu cầu của chính mình; trưởng bộ phận được duyệt yêu cầu dưới ngưỡng A; tài chính duyệt từ ngưỡng A trở lên.
  • Workflow contract: Draft - Submitted - ManagerApproved - FinanceApproved - Disbursed hoặc Rejected.
  • API contract: POST /advance-requests trả về mã 201 khi tạo thành công; 422 khi vi phạm rule; 403 khi sai quyền; response chứa request_id và current_state.
  • Hậu điều kiện: Tạo bản ghi yêu cầu, phát event AdvanceRequestSubmitted, ghi audit log, thông báo cho người duyệt kế tiếp.

Ở ví dụ tốt, người nghiệp vụ kiểm tra được logic, kỹ thuật triển khai được flow, QA viết test được, đội tích hợp hiểu API, đội vận hành theo dõi được traceability. Đó chính là giá trị của scenarios khi được neo vào các lớp contract phù hợp.

Gợi ý cấu trúc DSL contract cho scenarios

Nếu tổ chức đang theo hướng software factory hoặc contract coding như Midi Coder, nên chuẩn hóa scenarios bằng một DSL ngắn gọn, đọc được bởi cả người và máy. Ví dụ cấu trúc tối thiểu có thể gồm:

  • Tên scenario.
  • Mục tiêu nghiệp vụ.
  • Actors và vai trò.
  • Preconditions.
  • Trigger.
  • Main flow.
  • Alternative flows.
  • Rules tham chiếu.
  • Policies tham chiếu.
  • API hoặc message contracts liên quan.
  • Expected outputs.
  • Traceability artifacts.

Khi đó, contract không còn là văn bản rời rạc mà trở thành đầu vào có thể nối sang sinh test, kiểm tra schema, rà soát phân quyền, theo dõi workflow và giảm bất ngờ ở code đầu ra.

Kết luận

Scenarios giúp đội kỹ thuật và nghiệp vụ nói cùng một ngôn ngữ không phải vì chúng mô tả nhiều hơn, mà vì chúng mô tả đúng trọng tâm hơn. Một contract tốt không ôm hết mọi thứ và cũng không dính chặt vào chi tiết code. Nó khóa được từ vựng, phạm vi, quy tắc, quyền hạn, luồng xử lý và đầu ra theo cách đủ rõ để đem đi thi công. Khi làm được điều đó, code sinh ra sẽ ít bất ngờ hơn, kiểm thử dễ hơn và toàn đội phối hợp trơn tru hơn.

Frequently Asked Questions

Scenarios trong contract khác gì với user story?

User story thường nêu nhu cầu ở mức ngắn gọn, còn scenario trong contract mô tả tình huống có cấu trúc để khóa cách hiểu về điều kiện, luồng xử lý, quyền hạn, dữ liệu và kết quả mong đợi.

Có nên đưa chi tiết code vào scenario không?

Không nên bám sát code quá mức. Scenario nên đứng ở mức hành vi và quy tắc nghiệp vụ, chỉ chi tiết đến mức đủ để thi công, kiểm thử và tích hợp mà không làm người nghiệp vụ mất khả năng đọc hiểu.

Vì sao scenario phải gắn với rule, workflow, policy và API contract?

Vì một tình huống thực tế luôn liên quan đồng thời đến quy tắc quyết định, trình tự xử lý, quyền truy cập và giao diện tích hợp. Nếu thiếu một trong các lớp này, contract dễ mơ hồ hoặc không dùng được cho triển khai.

Dấu hiệu nào cho thấy contract đang trở thành giấy tờ vô dụng?

Dấu hiệu thường gặp là phạm vi quá rộng, ngôn ngữ không thống nhất, chỉ có happy path, thiếu nhánh lỗi, thiếu phân quyền, thiếu schema rõ ràng và đọc xong các bên vẫn trả lời khác nhau về hành vi hệ thống.