5.4 KiB
API — Contract đề xuất —
| Version | 1.0 |
| Date | YYYY-MM-DD |
| Author | (skill ba-3-specification) |
| Status | 🟡 Draft |
| Nguồn contract | ⚠️ BA đề xuất — chờ BE xác nhận / ✅ BE cung cấp |
| Approved by | BE Lead: — |
| Source | SRS_… v1.0 |
| Scope | US-0nn |
🔴 Đọc dòng
Nguồn contracttrước. Contract do BA đề xuất là giả định, không phải sự thật — dev phải đối chiếu với tài liệu BE trước khi code. Contract do BE cung cấp mới là ràng buộc.
1. Ba điểm phải chốt trước tiên
Ba chỗ này gây bug nhiều nhất và thường không ai hỏi.
| # | Vấn đề | Quyết định | Lý do |
|---|---|---|---|
| 1 | Số lớn (id, số tiền) truyền dạng gì | string / number |
Vượt 2^53 thì JavaScript làm tròn sai ⇒ id 19 chữ số bị hỏng |
| 2 | Thời gian định dạng gì, múi giờ nào | ISO-8601 UTC / … | |
| 3 | Phân trang kiểu gì | offset (page,size) / cursor |
Có trả total không? Có hasNext không? |
🔴 Điểm 3: nếu API kiểu offset mà không trả hasNext, giao diện không biết còn trang sau
hay không — nút "Trang sau" sẽ hỏng. Chốt ngay ở đây.
2. Quy ước chung
| Base URL | |
| Xác thực | |
| Định dạng phản hồi | { code, message, data } / … |
| Mã HTTP dùng | 200 · 400 · 401 · 403 · 404 · 409 · 500 |
| Ngôn ngữ thông điệp | Trả mã lỗi (FE tự dịch) / Trả text đã dịch theo header |
🔴 Lỗi nghiệp vụ phải trả mã HTTP 4xx, không phải 200 kèm cờ lỗi trong body. Trả 200 khiến tầng gọi API coi là thành công và giao diện không hiện lỗi — bug im lặng, rất khó phát hiện.
3. Endpoint
3.1 GET /api/v1/<resource> — Lấy danh sách
| Mục đích | |
| Màn hình | SCR-01 |
| Quyền | ROLE-01 (🔶 chỉ cửa hàng phụ trách), ROLE-02, ROLE-04 |
Query parameters
| Tên | Kiểu | Bắt buộc | Mặc định | Ràng buộc | Ghi chú |
|---|---|---|---|---|---|
keyword |
string | ❌ | — | ≤ 100 ký tự | Tìm theo mã hoặc tên |
status |
enum | ❌ | tất cả | DRAFT|ACTIVE |
|
page |
int | ❌ | 0 | ≥ 0 | 0-based hay 1-based? ← chốt rõ |
size |
int | ❌ | 20 | 1–100 | |
sort |
string | ❌ | code,asc |
Response 200
{
"code": "SUCCESS",
"message": null,
"data": {
"items": [
{
"id": "1234567890123456789",
"code": "STR-001",
"name": "…",
"status": "ACTIVE",
"createdAt": "2026-08-30T07:05:00Z"
}
],
"page": { "page": 0, "size": 20, "total": 137, "hasNext": true }
}
}
Từng trường
| Trường | Kiểu | Có thể null | Nguồn | Ghi chú |
|---|---|---|---|---|
id |
string | ❌ | String vì là số 19 chữ số | |
createdAt |
string | ❌ | ISO-8601, UTC |
Response lỗi
| HTTP | code |
Khi nào | Mã lỗi SRS |
|---|---|---|---|
| 400 | INVALID_PARAM |
Tham số sai định dạng | E-STL-0010 |
| 403 | FORBIDDEN |
Không đủ quyền | E-STL-0403 |
3.2 POST /api/v1/<resource> — Tạo mới
Request body
{ "code": "STR-001", "name": "…", "typeId": "12345" }
| Trường | Kiểu | Bắt buộc | Ràng buộc | Field SRS |
|---|---|---|---|---|
code |
string | ✅ | 3–20 ký tự, ^[A-Z0-9-]+$ |
F01 |
🔴 Ràng buộc ở API phải khớp với bảng field trong SRS. Lệch nhau ⇒ giao diện chặn một kiểu, backend chặn kiểu khác, người dùng gặp lỗi khó hiểu.
Response 200 / lỗi
| HTTP | code |
Khi nào | Mã lỗi SRS |
|---|---|---|---|
| 409 | DUPLICATE_CODE |
Mã đã tồn tại | E-STL-0001 |
4. Bảng đối chiếu mã lỗi
Mọi mã lỗi trong SRS §4.1 phải có một dòng ở đây, và ngược lại.
| Mã lỗi SRS | Endpoint | HTTP | code của API |
☐ Khớp |
|---|---|---|---|---|
E-STL-0001 |
POST /stores | 409 | DUPLICATE_CODE |
☐ |
Mã lỗi SRS không có endpoint nào sinh ra ⇒ hoặc lỗi chỉ ở giao diện (ghi rõ), hoặc bị bỏ sót.
5. Điểm cần BE xác nhận
Chỉ dùng khi contract do BA đề xuất.
| # | Điểm cần chốt | Đề xuất của BA | BE trả lời | Ngày |
|---|---|---|---|---|
| 1 | id trả string hay number |
string | ||
| 2 | page 0-based hay 1-based |
0-based | ||
| 3 | Có trả hasNext không |
Có | ||
| 4 | Lỗi nghiệp vụ trả 4xx hay 200 | 4xx |
6. Hành vi khi API lỗi (giao diện phải làm gì)
| Tình huống | Giao diện làm gì | AC |
|---|---|---|
| 401 hết phiên | Chuyển về đăng nhập, giữ đường dẫn để quay lại | |
| 403 | Hiện thông báo không đủ quyền, không xoá dữ liệu đã nhập | AC-12 |
| 5xx / timeout | Hiện lỗi, cho thử lại, giữ nguyên dữ liệu đã nhập | AC-09 |
| Mạng chậm | Hiện trạng thái đang tải, khoá nút gửi để tránh gửi hai lần |
🔴 Khoá nút gửi khi đang xử lý — không có nó thì người dùng bấm hai lần tạo ra hai bản ghi.
7. Open Questions
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì |
|---|