# AGD — Architecture Guidelines — | | | |---|---| | **Version** | 1.0 | | **Date** | YYYY-MM-DD | | **Author** | (skill sa-3-enablement) | | **Status** | 🟡 Draft | | **Approved by** | Tech Lead: — | | **Source** | SAD_… v1.0 · ADR-001..0nn · ICD_… v1.0 · FAIL_… v1.0 | | **Scope** | | | **Confidence** | 🟢 | ## Change Log | Version | Date | Người sửa | Thay đổi | ADR | |---|---|---|---|---| | 1.0 | | | Bản đầu | — | > **Tài liệu này chỉ chứa thứ truy được về một `ADR` hoặc `QAS`.** Quy ước đặt tên biến, thứ > tự import, độ dài hàm thuộc Tech Lead và nằm ở tài liệu khác. Trộn hai loại làm dev ngừng > phân biệt cái nào quan trọng. --- ## 1. Đọc gì trước | Bạn là | Đọc theo thứ tự | |---|---| | Dev mới vào dự án | §2 → reference implementation → `SAD` §4 | | Dev thêm một tính năng | §3 (ràng buộc) → `ICD` cho interface liên quan | | Dev sửa một bug | §4 (đường lỗi) → `FAIL` | | Người review PR | §3 + bảng `FIT` | ## 2. Reference implementation | | | |---|---| | **Đường dẫn** | `/` | | **Chạy thử** | `` | | **Thể hiện các quyết định** | `ADR-002`, `ADR-004`, `ADR-007` | Module mẫu thể hiện đủ sáu thứ. Thiếu thứ nào thì dev sẽ tự bịa thứ đó: | # | Thể hiện | Ở file nào | |---|---|---| | 1 | Cấu trúc module chuẩn | | | 2 | Xử lý lỗi + mã lỗi theo `ICD` §3 | | | 3 | Log có correlation id | | | 4 | Gọi phụ thuộc ngoài có timeout/retry theo `FAIL` | | | 5 | Kiểm tra quyền theo `SEC` §3 | | | 6 | Kiểm thử ở đủ các mức | | 🔴 **Code luôn thắng văn bản về khả năng được đọc.** Mọi thứ giải thích dài hơn 10 dòng nên chuyển thành code mẫu. ## 3. Ràng buộc kiến trúc *Bốn cột bắt buộc. Ràng buộc không có nguồn là sở thích cá nhân, và team sẽ nhận ra.* ### 3.1 Ranh giới module & phụ thuộc | # | Ràng buộc | Nguồn | Ví dụ đúng / sai | Cách kiểm | |---|---|---|---|---| | 1 | Tầng domain không import tầng infra | `ADR-002` | ✅ `domain/Order.ts` không import `infra/` · ❌ import `infra/db` | `FIT-01` | | 2 | Module chỉ giao tiếp qua interface công khai | `ADR-004` | | `FIT-02` | ### 3.2 Dữ liệu | # | Ràng buộc | Nguồn | Ví dụ đúng / sai | Cách kiểm | |---|---|---|---|---| | | Chỉ hệ thống chủ được ghi thực thể X | `DAT` §1 | | | | | Truy vấn danh sách phải có phân trang | `QAS-001` | | | | | Không dùng dữ liệu production ở non-prod | `SEC` §5 | | `FIT-nn` | ### 3.3 Interface & contract | # | Ràng buộc | Nguồn | Ví dụ đúng / sai | Cách kiểm | |---|---|---|---|---| | | Số lớn (id, tiền) truyền dạng `string` | `ICD` §1 | ✅ `"1234567890123456789"` · ❌ `1234567890123456789` | `FIT-nn` | | | Thời gian dùng ISO-8601 UTC | `ICD` §1 | | | | | Lỗi nghiệp vụ trả HTTP 4xx | `ICD` §1 | ❌ 200 kèm `{success:false}` | | | | Đổi contract breaking phải qua `ADR` | `ICD` §3 | | `FIT-nn` (Pact) | ### 3.4 Bảo mật | # | Ràng buộc | Nguồn | Ví dụ đúng / sai | Cách kiểm | |---|---|---|---|---| | | Không có secret trong mã nguồn | `SEC` §6 | | `FIT-nn` | | | Kiểm quyền ở tầng service, không chỉ ở gateway | `SEC` §3 | | ⚠️ Khuyến nghị | | | Không log dữ liệu PII | `SEC` §5 | | ⚠️ Khuyến nghị | ### 3.5 Ràng buộc chỉ là khuyến nghị *Quy tắc `D8`: không kiểm tự động được ⇒ phải ghi nhãn, kèm cách kiểm thủ công.* | Ràng buộc | Vì sao không tự kiểm được | Kiểm thủ công thế nào | Tần suất | |---|---|---|---| --- ## 4. Đường lỗi — dev phải làm gì *Trích từ `FAIL`. Đây là chỗ dev hay tự bịa nhất, nên viết cực cụ thể.* | Gọi tới | Timeout | Retry | Idempotent | Hết retry | Người dùng thấy gì | |---|---|---|---|---|---| | CSDL chính | … ms | 0 | — | trả 503 | | | API ngoài … | … ms | 3 · mũ + jitter | ✅ khoá … | vào hàng đợi | | **Mẫu code chuẩn:** `<đường dẫn trong reference implementation>` 🔴 **Không tự đặt timeout.** Ngân sách timeout theo tầng ở `FAIL` §2 — đặt sai một tầng làm sai cả chuỗi. ## 5. Log, metric, trace | | Quy tắc | Nguồn | |---|---|---| | Định dạng log | JSON, các trường bắt buộc: `ts`, `level`, `correlationId`, `service`, `msg` | `SAD` §9 | | Correlation id | lấy từ header `…`, truyền xuống mọi lời gọi | `SAD` §9 | | Mức log | `error` cho lỗi cần người xử lý · `warn` cho lỗi tự hồi phục | | | **Cấm log** | PII, secret, toàn bộ request body | `SEC` §5 | | Metric bắt buộc mỗi endpoint | số request, tỉ lệ lỗi, phân vị độ trễ | `QAS` | ## 6. Kiểm thử | Mức | Kiểm gì | Bắt buộc khi nào | Ngưỡng | |---|---|---|---| | Đơn vị | logic nghiệp vụ thuần | mọi rule trong `BR` của BA | | | Tích hợp | ranh giới với CSDL/hàng đợi | mọi repository | | | Contract | `IF-nnn` không đổi breaking | mọi interface công khai | `FIT-nn` | | Hiệu năng | `QAS` mức Must | trước mỗi release | `FIT-nn` | ## 7. Khi nào phải hỏi SA *Ranh giới rõ ràng giúp team không bị chặn, và SA không thành nút thắt.* | Tình huống | Quyết định bởi | |---|---| | Đặt tên, cấu trúc thư mục trong module, chọn thư viện tiện ích | **Dev / Tech Lead** — không cần hỏi | | Thêm một bảng vào CSDL của chính module mình | Tech Lead | | Thêm một endpoint theo đúng chuẩn `ICD` | Tech Lead | | Gọi trực tiếp dữ liệu của module khác | **Hỏi SA** — chạm `ADR-004` | | Thêm một phụ thuộc hạ tầng mới (cache, queue, dịch vụ ngoài) | **Hỏi SA** | | Đổi contract công khai theo hướng breaking | **Hỏi SA** — cần `ADR` | | Bỏ qua một ràng buộc ở §3 vì gấp | **Hỏi SA** — thành `TD-nn` có hạn | Chấm nhanh: `../../sa-lifecycle/references/decision-radar.md` §2. Điểm ≥ 5 ⇒ hỏi SA. ## 8. Ngoài phạm vi *Những gì tài liệu này KHÔNG quy định:* - Quy ước đặt tên, format code, độ dài hàm ⟶ tài liệu của Tech Lead - Quy trình Git, đặt tên nhánh, mẫu commit ⟶ tài liệu quy trình - Thiết kế giao diện, design system ⟶ tài liệu thiết kế ## 9. Open Questions | ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | |---|---|---|---|---|