# CTR — Contract Files Index — | | | |---|---| | **Version** | 1.0 | | **Date** | YYYY-MM-DD | | **Author** | (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/.yaml` | | **Event** | AsyncAPI **3.0** · một file mỗi domain event group · `contracts/asyncapi/-events.yaml` | | **gRPC** *(nếu có)* | `contracts/proto/.proto` · versioning theo package | | **Đối tác ngoài** | `contracts/partners/.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** | `.<động từ>` — ví dụ `cartOrder.getCart`, `cartOrder.checkout`; **duy nhất toàn dự án** | | **Mã lỗi** | schema `Error { code, message, details? }`; `code` là `E--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/

/02-architecture/contracts \ --icd sa-output/

/02-architecture/ICD_

_v1.0.md --srs ba-output/

/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 | |---|---|---|---|---|---|