update skill and docs
This commit is contained in:
118
.claude/skills/sa-2-architecture/templates/contract-index.md
Normal file
118
.claude/skills/sa-2-architecture/templates/contract-index.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# CTR — Contract Files Index — <PROJECT>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Version** | 1.0 |
|
||||
| **Date** | YYYY-MM-DD |
|
||||
| **Author** | <SA> (skill sa-2-architecture) |
|
||||
| **Status** | 🟡 Draft |
|
||||
| **Approved by** | Tech Lead: — · BE Lead: — · FE Lead: — |
|
||||
| **Source** | ICD_… v1.0 · API_… của BA · SRS_… §4.1 (mã lỗi) · DOM_… §5 (event) · SEC_… §3 |
|
||||
| **Scope** | |
|
||||
| **Confidence** | 🟡 |
|
||||
|
||||
## Change Log
|
||||
|
||||
| Version | Date | Người sửa | Thay đổi | ADR |
|
||||
|---|---|---|---|---|
|
||||
| 1.0 | | | Bản đầu | — |
|
||||
|
||||
> **Thẩm quyền:** file trong `02-architecture/contracts/` **thắng** mọi bảng mô tả endpoint — ở `ICD`,
|
||||
> ở `API` của BA, ở đây. Tài liệu này là **mục lục và biên bản lint**, không chép nội dung contract.
|
||||
>
|
||||
> **Vì sao có tài liệu này:** `ICD` mô tả interface bằng bảng, `API` của BA cũng bằng bảng. Dev phải
|
||||
> tự viết lại OpenAPI từ bảng, FE và BE viết hai bản khác nhau, mock server không dựng được, contract
|
||||
> test không có gì để chạy. File máy đọc đóng đúng lỗ đó.
|
||||
|
||||
---
|
||||
|
||||
## 1. Quy ước
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **REST** | OpenAPI **3.1** · một file mỗi module/bounded context · `contracts/openapi/<module>.yaml` |
|
||||
| **Event** | AsyncAPI **3.0** · một file mỗi domain event group · `contracts/asyncapi/<domain>-events.yaml` |
|
||||
| **gRPC** *(nếu có)* | `contracts/proto/<service>.proto` · versioning theo package |
|
||||
| **Đối tác ngoài** | `contracts/partners/<ten>.yaml` — **mirror** tài liệu đối tác, ghi rõ nguồn + ngày lấy; không tự viết thay đối tác |
|
||||
| **operationId** | `<module>.<động từ><DanhTừ>` — ví dụ `cartOrder.getCart`, `cartOrder.checkout`; **duy nhất toàn dự án** |
|
||||
| **Mã lỗi** | schema `Error { code, message, details? }`; `code` là `E-<DOMAIN>-nnnn` của SRS §4.1, liệt kê trong `x-error-codes` mỗi operation |
|
||||
| **Ba quy ước chốt** (`ICD` §1) | số lớn `type: string`; thời gian `format: date-time` UTC; phân trang theo `ADR-nnn` — khai báo một lần trong `components/` và `$ref` |
|
||||
| **Ví dụ** | mỗi operation ≥ 1 `example` thành công + 1 ví dụ lỗi 4xx |
|
||||
| **Lint** | `spectral lint` với ruleset `contracts/.spectral.yaml` nếu có; không có ⇒ kiểm cấu trúc bằng script ở §4 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Mục lục file — `CTR-nn`
|
||||
|
||||
| `CTR` | File | Loại | Phủ `IF-nnn` | Owner (`ICD` §2) | Version contract | Lint | Ngày lint |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `CTR-01` | `contracts/openapi/cart-order.yaml` | OpenAPI 3.1 | `IF-002` | BE Nhóm Giao dịch | `1.0.0` | ☐ | |
|
||||
| `CTR-02` | `contracts/asyncapi/order-events.yaml` | AsyncAPI 3.0 | `IF-009` | BE Nhóm Giao dịch (publish) | `1.0.0` | ☐ | |
|
||||
| `CTR-03` | `contracts/partners/vnpay.yaml` | mirror | `IF-007` | VNPay — 🔴 chưa có tài liệu thật (`ARISK-03`) | — | — | |
|
||||
|
||||
---
|
||||
|
||||
## 3. Ánh xạ `IF` → operation → BA
|
||||
|
||||
*Bảng `sa-conformance` đọc. Mỗi `IF-nnn` sync trong `ICD` §2 phải có ≥ 1 dòng; mỗi endpoint trong
|
||||
`API` của BA phải có `operationId`.*
|
||||
|
||||
| `IF-nnn` | `operationId` / channel | Method + path / topic | Endpoint `API` của BA | `AC` liên quan | Mã lỗi (`E-…`) trong schema | `ROLE` (`SEC` §3) |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `IF-002` | `cartOrder.getCart` | `GET /v1/cart` | `API_US002-003 §3.1` | `AC-US002-01..03` | `E-CART-0401`, `E-CART-0503` | `ROLE-01`, Guest |
|
||||
| `IF-002` | `cartOrder.checkout` | `POST /v1/checkout` | `API_US002-003 §3.4` | `AC-US003-01..10` | `E-CHK-0409`, `E-CHK-0422`, `E-CHK-0503` | `ROLE-01`, Guest |
|
||||
| `IF-009` | `OrderPlaced` | topic `order.placed.v1` | — | — | — | publish `CMP-04` |
|
||||
|
||||
🔴 Endpoint có trong `API` của BA mà không có `operationId` ⇒ hoặc BA đề xuất endpoint không tồn tại,
|
||||
hoặc `CTR` bỏ sót. Xử lý ngay, báo BA qua `baSyncIssues`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Kết quả lint và kiểm cấu trúc
|
||||
|
||||
*Người điều phối (có Bash) chạy, chép nguyên văn vào đây. Runner không có Bash ⇒ ghi "chưa lint".*
|
||||
|
||||
```bash
|
||||
# có spectral
|
||||
npx @stoplight/spectral-cli lint contracts/openapi/*.yaml contracts/asyncapi/*.yaml
|
||||
# không có spectral — kiểm cấu trúc tối thiểu
|
||||
node .claude/skills/sa-2-architecture/scripts/contract-check.mjs --dir sa-output/<P>/02-architecture/contracts \
|
||||
--icd sa-output/<P>/02-architecture/ICD_<P>_v1.0.md --srs ba-output/<P>/03-specification/SRS_*.md
|
||||
```
|
||||
|
||||
| Kiểm | Kết quả | Chi tiết |
|
||||
|---|---|---|
|
||||
| Mọi file parse được, `openapi: 3.1.x` / `asyncapi: 3.0.x` | ☐ | |
|
||||
| Mọi `operationId` duy nhất | ☐ | |
|
||||
| Mọi `IF-nnn` sync của `ICD` §2 có operation | ☐ | |
|
||||
| Mọi mã lỗi `E-…` trong SRS §4.1 xuất hiện trong ≥ 1 `x-error-codes` | ☐ | |
|
||||
| Số lớn là `string`, thời gian `format: date-time` | ☐ | |
|
||||
| Mỗi operation có `example` thành công + lỗi | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
## 5. Sinh code và mock từ contract *(khuyến nghị cho `AGD`)*
|
||||
|
||||
| Việc | Công cụ gợi ý | Ai | Ghi ở |
|
||||
|---|---|---|---|
|
||||
| Sinh client/server stub | openapi-generator · orval · oapi-codegen | BE/FE | `AGD` §2 reference implementation |
|
||||
| Mock server cho FE | Prism · MSW từ OpenAPI | FE | `AGD` |
|
||||
| Contract test | Pact · schemathesis | QA/BE | `FIT-nn` |
|
||||
|
||||
---
|
||||
|
||||
## 6. 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:**
|
||||
|
||||
- *(ví dụ: không viết contract cho interface in-process cùng module — thuộc `AGD`)*
|
||||
|
||||
## 7. 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