init git
This commit is contained in:
176
.claude/skills/sa-2-architecture/templates/interface-catalog.md
Normal file
176
.claude/skills/sa-2-architecture/templates/interface-catalog.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# ICD — Integration & Interface Catalog — <PROJECT>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Version** | 1.0 |
|
||||
| **Date** | YYYY-MM-DD |
|
||||
| **Author** | <SA> (skill sa-2-architecture) |
|
||||
| **Status** | 🟡 Draft |
|
||||
| **Approved by** | Tech Lead: — · BE Lead: — |
|
||||
| **Source** | SAD_… v1.0 · API_… của BA · tài liệu API của … |
|
||||
| **Scope** | |
|
||||
| **Confidence** | 🟡 |
|
||||
|
||||
## Change Log
|
||||
|
||||
| Version | Date | Người sửa | Thay đổi | ADR |
|
||||
|---|---|---|---|---|
|
||||
| 1.0 | | | Bản đầu | — |
|
||||
|
||||
> 🔴 **Tài liệu này thắng `API` contract của bộ BA khi hai bên lệch.** BA viết contract đề
|
||||
> xuất và đánh dấu *"chờ BE xác nhận"* — đây là chỗ xác nhận. Mọi chỗ lệch phải báo lại để BA
|
||||
> cập nhật SRS.
|
||||
|
||||
---
|
||||
|
||||
## 1. Ba quy ước chốt một lần cho toàn hệ thống
|
||||
|
||||
*Ba chỗ này gây bug nhiều nhất và thường không ai hỏi. Chốt ở đây, ghi thành `ADR`.*
|
||||
|
||||
| # | Vấn đề | Quyết định | `ADR` | Vì sao |
|
||||
|---|---|---|---|---|
|
||||
| 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ố hỏng **im lặng** |
|
||||
| 2 | **Thời gian** định dạng gì, múi giờ nào | ISO-8601 UTC / … | | Trộn local time và UTC là bug không ai tìm ra |
|
||||
| 3 | **Phân trang** kiểu gì | offset (`page`,`size`) / cursor | | Offset không trả `hasNext` ⇒ nút "trang sau" hỏng |
|
||||
|
||||
Bổ sung khi áp dụng:
|
||||
|
||||
| # | Vấn đề | Quyết định | `ADR` |
|
||||
|---|---|---|---|
|
||||
| 4 | Định dạng phản hồi chung | `{ code, message, data }` / … | |
|
||||
| 5 | Lỗi nghiệp vụ trả HTTP nào | **4xx**, không phải 200 kèm cờ lỗi | |
|
||||
| 6 | Ngôn ngữ thông điệp lỗi | trả mã (client tự dịch) / trả text theo header | |
|
||||
| 7 | Khoá idempotency | tên header, cách sinh, giữ bao lâu | |
|
||||
| 8 | Correlation id | tên header, truyền xuyên suốt thế nào | |
|
||||
|
||||
🔴 **Lỗi nghiệp vụ trả 200 kèm cờ lỗi là bug im lặng**: tầng gọi API coi là thành công và giao
|
||||
diện không hiện lỗi. Chốt 4xx ngay ở đây.
|
||||
|
||||
---
|
||||
|
||||
## 2. Danh mục interface — `IF-nnn`
|
||||
|
||||
*Mọi lời gọi vượt ranh giới container phải có một dòng.*
|
||||
|
||||
| ID | Từ | Đến | Giao thức | Sync/Async | **Ai sở hữu contract** | Contract ở đâu | Versioning | Đầu kia hỏng thì sao | `FAIL` |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| `IF-001` | `CMP-01` | `CMP-03` | HTTP/JSON | sync | team … | `openapi/orders.yaml` | URL path `/v1` | degrade: … | `FM-03` |
|
||||
| `IF-002` | `CMP-03` | Kafka | AsyncAPI | async | team … | `asyncapi/settlement.yaml` | schema registry, backward | buffer + retry | `FM-05` |
|
||||
|
||||
🔴 **Interface không biết ai sở hữu là interface sẽ bị đổi mà không ai báo.** Cột này không
|
||||
được để trống, kể cả với hệ thống nội bộ.
|
||||
|
||||
### 2.1 Interface với hệ thống ngoài
|
||||
|
||||
| ID | Hệ thống | Ai liên hệ được | **SLA của họ** | Giới hạn tốc độ | Cơ chế xác thực | Môi trường thử | Đã gọi thử chưa |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `IF-0nn` | | tên + kênh | uptime … · p95 … | … req/phút | | có/không | ☐ |
|
||||
|
||||
🔴 Hệ thống ngoài **không có SLA** ⇒ thiết kế như thể nó có thể hỏng bất cứ lúc nào, và ghi
|
||||
`ARISK`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Chi tiết từng interface
|
||||
|
||||
### 3.1 `IF-001` — <tên>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Mục đích** | |
|
||||
| **Từ → Đến** | `CMP-01` → `CMP-03` |
|
||||
| **Giao thức** | |
|
||||
| **Đồng bộ?** | sync · timeout … ms |
|
||||
| **Quyền** | `ROLE-nn` *(map ở `SEC` §3)* |
|
||||
| **Idempotent** | có/không · khoá: … |
|
||||
| **Tần suất dự kiến** | … req/s trung bình, … đỉnh · nguồn: `QAS-nnn` |
|
||||
|
||||
**Contract**
|
||||
|
||||
Nguồn sự thật: `<đường dẫn file OpenAPI/AsyncAPI/proto>` — **không chép nội dung contract vào
|
||||
đây**, chỉ ghi những điểm cần chú ý:
|
||||
|
||||
| Điểm cần chú ý | Quyết định |
|
||||
|---|---|
|
||||
| Trường nào là số lớn ⇒ string | |
|
||||
| Trường nào có thể null và ý nghĩa của null | |
|
||||
| Enum có mở rộng về sau không ⇒ client xử lý giá trị lạ thế nào | |
|
||||
|
||||
**Mã lỗi**
|
||||
|
||||
| HTTP | `code` | Khi nào | Client làm gì | Mã lỗi SRS của BA |
|
||||
|---|---|---|---|---|
|
||||
| 400 | `INVALID_PARAM` | | hiện lỗi tại field | `E-…-0010` |
|
||||
| 403 | `FORBIDDEN` | | không xoá dữ liệu đã nhập | `E-…-0403` |
|
||||
| 409 | | | | |
|
||||
| 5xx | | | cho thử lại, **giữ nguyên dữ liệu đã nhập** | |
|
||||
|
||||
**Chính sách phiên bản**
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Cách đánh phiên bản | URL path / header / schema registry |
|
||||
| Thay đổi nào là breaking | *(bỏ trường, đổi kiểu, thêm trường bắt buộc, thu hẹp enum)* |
|
||||
| Hỗ trợ bản cũ bao lâu | |
|
||||
| Cách báo trước | |
|
||||
|
||||
### 3.2 `IF-002` — <tên>
|
||||
|
||||
*(cùng cấu trúc)*
|
||||
|
||||
---
|
||||
|
||||
## 4. Hợp đồng sự kiện *(nếu có async)*
|
||||
|
||||
| Sự kiện | Nhà phát | Người nhận | Schema | Thứ tự có quan trọng | At-least-once? | Trùng thì sao |
|
||||
|---|---|---|---|---|---|---|
|
||||
| | | | | | | khoá khử trùng: … |
|
||||
|
||||
🔴 **Hầu hết message broker đảm bảo at-least-once, không phải exactly-once.** Mọi người nhận
|
||||
phải khử trùng được. Ghi rõ khoá khử trùng và cửa sổ thời gian.
|
||||
|
||||
| Vấn đề | Quyết định |
|
||||
|---|---|
|
||||
| Message hỏng (poison message) xử lý thế nào | DLQ · giữ bao lâu · ai xử lý |
|
||||
| Đọc lại từ đầu (replay) có được không | |
|
||||
| Thứ tự đảm bảo trong phạm vi nào | *(partition key là gì)* |
|
||||
|
||||
---
|
||||
|
||||
## 5. Đối chiếu với `API` của bộ BA
|
||||
|
||||
| Endpoint trong `API` của BA | `IF-nnn` | Khớp | Lệch ở đâu | Hành động |
|
||||
|---|---|---|---|---|
|
||||
| `GET /api/v1/…` | `IF-001` | ✅ | | |
|
||||
| `POST /api/v1/…` | `IF-003` | ❌ | BA đề xuất `id: number`, `ICD` chốt `string` | BA cập nhật SRS §… |
|
||||
|
||||
Endpoint trong `API` không có `IF-nnn` ⇒ hoặc BA đề xuất một endpoint không tồn tại, hoặc `ICD`
|
||||
bỏ sót. Phải xử lý, không để treo.
|
||||
|
||||
## 6. Hành vi giao diện khi API lỗi
|
||||
|
||||
| Tình huống | Giao diện làm gì | `QAS`/`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** | |
|
||||
| 5xx / timeout | Hiện lỗi, cho thử lại, **giữ nguyên dữ liệu đã nhập** | |
|
||||
| Mạng chậm | Trạng thái đang tải, **khoá nút gửi** để tránh gửi hai lần | |
|
||||
|
||||
🔴 Không khoá nút gửi ⇒ người dùng bấm hai lần tạo hai bản ghi. Đây là bug xuất hiện ở gần như
|
||||
mọi hệ thống không chốt điểm này từ đầu.
|
||||
|
||||
## 7. Giả định & Ngoài phạm vi
|
||||
|
||||
**Giả định:**
|
||||
|
||||
| ID | Giả định | Cách xác minh | Nếu sai |
|
||||
|---|---|---|---|
|
||||
|
||||
**Ngoài phạm vi:**
|
||||
|
||||
-
|
||||
|
||||
## 8. Open Questions
|
||||
|
||||
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | Hệ quả nếu trả lời ngược |
|
||||
|---|---|---|---|---|---|
|
||||
Reference in New Issue
Block a user