6.0 KiB
Ví dụ minh hoạ — ba-3-specification
Tách khỏi SKILL.md để quy trình không lẫn ví dụ của một ngành cụ thể. Mỗi bước minh hoạ ở
nhiều domain và nhiều PRODUCT — cùng một quy tắc, khác cách áp.
Bước 3 · Bảng ràng buộc — cùng nguyên tắc, bốn hình dạng
Nguyên tắc chung: giới hạn · mặc định · nguồn giá trị · hành vi khi sai đều phải có.
screen — bán lẻ, form tạo cửa hàng
| ID | Field | Kiểu | Bắt buộc | Giới hạn | Default | Nguồn giá trị | Validation | Message khi sai |
|---|---|---|---|---|---|---|---|---|
| F01 | Mã cửa hàng | Text | ✅ | 3–20 ký tự (code point UTF-8) | — | Người dùng nhập | ^[A-Z0-9-]+$, không trùng |
E-STR-0001 |
| F02 | Loại | Chọn 1 | ✅ | — | "Thường" | API /store-types, lọc active=true, sắp theo order |
thuộc danh sách | E-STR-0002 |
api-service — y tế, đặt lịch khám
| Tên | Kiểu | Vị trí | Bắt buộc | Mặc định | Ràng buộc | BR |
|---|---|---|---|---|---|---|
patientId |
string | body | ✅ | — | 19 chữ số, string vì vượt 2^53 | BR-004 |
slotStart |
string | body | ✅ | — | ISO-8601 UTC, phải ≥ now+2h, thuộc giờ làm việc của phòng khám | BR-011 |
channel |
enum | body | ❌ | WEB |
WEB|APP|CALL — giá trị lạ ⇒ 400, không âm thầm bỏ qua |
BR-012 |
data-pipeline — logistics, nạp sự kiện quét kho
| Trường đích | Từ nguồn | Phép biến đổi | Nguồn null | Nguồn sai định dạng |
|---|---|---|---|---|
warehouse_code |
wh.id |
upper(trim(x)) |
→ UNKNOWN, đếm vào DQ-02 |
→ quarantine |
scanned_at |
ts |
epoch ms → timestamp UTC | 🛑 dừng luồng (không suy ra được) | → quarantine |
qty |
quantity |
ép số nguyên | → 0 | → quarantine |
ml-model — tài chính, chấm điểm rủi ro khoản vay
| ID | Metric | Đo trên | Ngưỡng | Baseline | Truy về chi phí nghiệp vụ |
|---|---|---|---|---|---|
| M-01 | Precision @ 0.7 | Test giữ lại | ≥ 0,85 | Quy tắc tay: 0,62 | Mỗi FP tốn ~25 phút thẩm định tay |
| M-02 | Recall | Test giữ lại | ≥ 0,70 | 0,45 | Mỗi FN ≈ 40 triệu nợ xấu trung bình |
🔴 Cột cuối là cột phân biệt một ngưỡng có căn cứ với một con số ai đó thấy đẹp.
Bước 4 · AC bốn nhóm — ví dụ nhóm 3 (lỗi hệ thống)
Nhóm hay bị bỏ nhất, ở mọi domain.
Y tế · screen · form đặt lịch:
Given tôi đã điền đầy đủ form đặt lịch hợp lệ
When tôi bấm Xác nhận và request bị timeout sau 30 giây
Then hiện thông báo "Không kết nối được, vui lòng thử lại"
And nút Xác nhận bấm lại được
And 🔴 toàn bộ thông tin tôi đã nhập được giữ nguyên
And 🔴 nếu lịch đã được tạo ở phía server, lần bấm lại KHÔNG tạo lịch thứ hai
Dòng cuối là chỗ AC nhóm 3 gặp api-service: cần idempotency key, và nó phải nằm trong spec
chứ không phải để dev tự nghĩ ra.
Logistics · batch-job · job đối soát tồn kho đêm:
Given job đang xử lý dở 12.000/50.000 bản ghi
When tiến trình bị ngắt
Then lần chạy tiếp theo bắt đầu từ checkpoint bản ghi 12.000
And không bản ghi nào bị xử lý hai lần
And không bản ghi nào bị bỏ sót
Bước 5 · Phân biệt "không có gì" với "không lấy được"
Cùng một lỗi tư duy, bốn biểu hiện:
Domain · PRODUCT |
❌ Gộp làm một | ✅ Phân biệt |
|---|---|---|
Bán lẻ · screen |
Cả hai đều hiện "Không có dữ liệu" | "Chưa có bản ghi nào" (nút Tạo mới) ↔ "Không khớp bộ lọc" (nút Xoá lọc) |
Y tế · api-service |
Cả hai trả 404 | Không còn slot trống: 200 + [] ↔ phòng khám không tồn tại: 404 |
Logistics · data-pipeline |
Cả hai nạp 0 bản ghi, báo thành công | Chủ nhật không phát sinh: 0 bản ghi + nhãn "không có hoạt động" ↔ API kho không phản hồi: 🔴 cảnh báo |
Tài chính · batch-job |
Job báo "thành công, 0 bản ghi" | Không có giao dịch cần đối soát ↔ job trước chưa xong nên chưa có đầu vào |
Ba dòng cuối là chế độ hỏng im lặng: hệ thống báo thành công trong khi dữ liệu không tới.
Bước 6 · NFR có số đo — ba domain
| ❌ Khẩu hiệu | ✅ Yêu cầu |
|---|---|
| "Màn hình danh sách phải nhanh" | "Trả về ≤ 2s (p95) với 100.000 bản ghi và 20 người dùng đồng thời, trên staging. Verify: k6 kịch bản S1 trước mỗi release" |
| "Dữ liệu phải cập nhật kịp thời" | "Dữ liệu ngày D sẵn sàng trước D+1 08:00. Trễ > 2h ⇒ cảnh báo cho nhóm vận hành. Người dùng thấy nhãn 'dữ liệu tới <ngày>' khi chưa có số mới" |
| "Mô hình phải chạy nhanh" | "Dự đoán đồng bộ ≤ 300ms (p99) cho 1 hồ sơ; quá hạn ⇒ trả fallback 'cần thẩm định tay' và ghi log" |
Bẫy "bịa giá trị nghe hợp lý"
Bốn con số này xuất hiện ở mọi domain và gần như luôn là bịa:
| Con số | Vì sao nguy hiểm | Thay bằng |
|---|---|---|
255 ký tự |
Là giới hạn mặc định của DB, không phải yêu cầu nghiệp vụ | OQ: tên dài nhất thực tế là bao nhiêu? |
timeout 30 giây |
Chọn theo thói quen | OQ: người dùng chờ bao lâu thì bỏ cuộc? |
giữ log 90 ngày |
Nghe hợp lý nên không ai chất vấn | OQ: quy định lưu trữ của tổ chức là gì? |
precision ≥ 0.85 |
Con số tròn, trông chuyên nghiệp | OQ: mỗi lần sai tốn bao nhiêu? |
Chúng nguy hiểm chính vì nghe hợp lý — không ai chất vấn, và sai thì phát hiện rất muộn.