Files
2026-09-22 13:46:36 +07:00

222 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Hướng dẫn sử dụng — `sa-2-architecture` (Giai đoạn 2)
## Giai đoạn này giải quyết gì
Đầu vào là một phương án đã chọn (`OPT` qua AG1). Đầu ra là **bộ thiết kế đủ để dev bắt tay
code, QA biết đo cái gì, SRE biết vận hành thế nào** — không ai phải quay lại hỏi "cái này để
đâu, gọi ai, hỏng thì sao".
**Không làm ở giai đoạn này:** viết code sản phẩm, chọn thư viện tiện ích, quy ước đặt tên,
cấu trúc thư mục. Những thứ đó thuộc `sa-3-enablement` và Tech Lead.
## Đây là giai đoạn dài nhất — đừng chạy một lần
12 artifact là công việc **nhiều tuần**, không phải một buổi. Cách chạy đúng:
```
Tuần 1 /sa-2-architecture <P> --focus qas → lượng hoá NFR (làm TRƯỚC mọi thứ)
/sa-2-architecture <P> --focus asr → chưng cất ASR
Tuần 2 /sa-2-architecture <P> --focus sad → phân rã + C4 + ADR kiểu kiến trúc
Tuần 3 --focus icd · --focus dat → chạy song song được
Tuần 4 --focus sec · --focus inf · --focus fail
Tuần 5 --focus dom · --focus ctr · --focus pdm → lớp bàn giao dev: class diagram, OpenAPI/AsyncAPI, schema + DDL/migration
Liên tục --focus adr → viết ADR mỗi khi có quyết định
```
🔴 **Không có `CTR` và `PDM` thì dev vẫn phải tự viết contract và schema** — đúng hai chỗ FE/BE lệch
nhau nhiều nhất. AG2 chặn khi thiếu.
🔴 **Thứ tự 1→2→3 là bắt buộc.** Vẽ sơ đồ trước khi có con số thì sơ đồ đó sẽ được bảo vệ
bằng mọi giá về sau, kể cả khi con số nói nó sai.
## Khi nào gọi
| Tình huống | Có nên gọi |
|---|---|
| Đã qua AG1, bắt đầu thiết kế | ✅ Chạy theo lịch trên |
| Thêm tính năng có endpoint mới, không đổi dữ liệu | ✅ Rút gọn: `--focus icd` + `--focus qas` |
| Đổi mô hình dữ liệu / thêm tích hợp ngoài | ✅ Bắt buộc `--focus dat` + `--focus icd` + ADR |
| Cần một quyết định được ghi lại | ✅ `--focus adr` |
| Dev hỏi "chỗ này thiết kế thế nào" | ❌ Nếu đã có `SAD` — sang `sa-3-enablement` |
| Chưa qua AG1 | ⚠️ Chạy được nhưng mọi `Confidence` là 🔴 |
| Thêm một màn hình dùng API đã có | ❌ Không cần SA |
## Cú pháp
```
/sa-2-architecture <PROJECT> [--focus qas|asr|sad|adr|icd|dat|sec|inf|fail|dom|ctr|pdm|all] [--out <path>] [go]
```
| `--focus` | Sinh ra | Cần có trước |
|---|---|---|
| `qas` | `QAS` — NFR lượng hoá | `CTX`, `OPT` |
| `asr` | `ASR` — yêu cầu định hình kiến trúc | `QAS` |
| `sad` | `SAD` + ADR kiểu kiến trúc | `ASR` |
| `icd` | `ICD` — interface catalog | `SAD` |
| `dat` | `DAT` — kiến trúc dữ liệu | `SAD` |
| `sec` | `SEC` — threat model + authz | `SAD`, `DAT`, `RBAC` của BA |
| `inf` | `INF` — hạ tầng, HA/DR | `SAD`, `QAS`, `TCO` |
| `fail` | `FAIL` — đường lỗi | `SAD`, `ICD` |
| `adr` | Một `ADR` mới | — |
| `dom` | `DOM` — domain model, class diagram theo bounded context, invariant ↔ `BR` | `SAD`, `DAT`, `BR` của BA |
| `ctr` | `CTR` + **file thật** `contracts/openapi/*.yaml`, `contracts/asyncapi/*.yaml` | `ICD`, `API` + SRS §4.1 của BA |
| `pdm` | `PDM` + **file thật** `schema/<kho>/V001__*.sql` (+ `.down.sql`, seed) | `DAT`, `DOM`, bảng field SRS, `SEC` §5 |
| `all` | Cả 12 *(cảnh báo: rất dài)* | |
Viết một ADR cụ thể:
```
/sa-2-architecture Settlement --focus adr
"quyết định dùng outbox pattern thay vì 2PC cho ghi đơn + phát event"
```
## Chuẩn bị gì trước khi gọi
| Cho bước | Chuẩn bị | Không có thì |
|---|---|---|
| `qas` | Số tải thật (`CTX` §4.4), ngưỡng chấp nhận của PO, ngân sách lỗi | `QAS` thành ước lượng 🔴 |
| `asr` | `BR` của bộ BA (rule nào ép consistency/audit/retention) | Bỏ sót ràng buộc nghiệp vụ |
| `sad` | Cơ cấu team (`CON-04`), ai release độc lập với ai | Chia service trái Conway |
| `icd` | `API` contract đề xuất của BA, tài liệu API hệ thống ngoài | Contract lệch nhau ngay từ đầu |
| `dat` | Schema hiện tại, khối lượng dữ liệu legacy, yêu cầu pháp lý | Migration không rollback được |
| `sec` | `RBAC` của BA, chính sách bảo mật doanh nghiệp, **người của Security** | Bị phủ quyết ở AG2 |
| `inf` | Báo giá cloud, `TCO`, năng lực đội SRE | `INF` lệch `TCO` |
| `fail` | SLA của mọi hệ thống ngoài | Không biết degrade thế nào |
| `dom` | `BR` đã qua G2, `DAT` §1 ownership | Aggregate vẽ theo bảng, invariant kiểm sai chỗ |
| `ctr` | `ICD` xong, `API` + mã lỗi SRS của BA, tài liệu API đối tác thật | Contract "dự kiến", FE/BE mỗi bên một bản |
| `pdm` | `DAT`, `DOM`, bảng field `FLD-*` của SRS, công cụ migration team dùng | UI chặn 40 ký tự, DB nhận 255 — dữ liệu bẩn |
🔴 **Bước `sec` cần một người thật từ Security ngồi cùng.** Skill dựng được threat model,
nhưng người có quyền phủ quyết phải tham gia từ đầu, không phải lúc trình gate.
## Bạn sẽ nhận được gì
```
sa-output/<PROJECT>/02-architecture/
├── ASR_<PROJECT>_v1.0.md
├── QAS_<PROJECT>_v1.0.md ← QA và SRE dùng cái này để đo
├── SAD_<PROJECT>_v1.0.md ← tài liệu chính, Tech Lead ký
├── ICD_<PROJECT>_v1.0.md ← dev BE/FE và đối tác dùng cái này
├── DAT_<PROJECT>_v1.0.md
├── SEC_<PROJECT>_v1.0.md ← Security ký
├── INF_<PROJECT>_v1.0.md ← SRE ký
├── FAIL_<PROJECT>_v1.0.md
├── DOM_<PROJECT>_v1.0.md ← class diagram theo bounded context, dev BE đọc
├── CTR_<PROJECT>_v1.0.md ← mục lục + biên bản lint contract
├── PDM_<PROJECT>_v1.0.md ← schema vật lý đủ cột, DBA + dev BE ký
├── contracts/
│ ├── openapi/<module>.yaml ← OpenAPI 3.1 — nguồn sự thật, thắng mọi bảng
│ ├── asyncapi/<domain>-events.yaml
│ └── partners/<ten>.yaml ← mirror tài liệu đối tác (ghi nguồn)
├── schema/<kho>/
│ ├── V001__init_<schema>.sql · V001__init_<schema>.down.sql
│ └── seed/R__reference_data.sql
├── diagrams/ ← spec Archify (.json) + HTML đã deliver, một cặp mỗi sơ đồ
└── adr/
├── ADR-001_kieu-kien-truc.md
├── ADR-002_chon-csdl-chinh.md
└── …
```
Cộng bốn bảng in ra màn hình: Gate AG2 · quy tắc D1–D12 · **đối chiếu với bộ BA** · `OQ` mở.
## Đọc một `QAS` thế nào
```
QAS-004 · Thông lượng đối soát · Must
Kích thích : job nửa đêm, 1,2 triệu bản ghi POS của một ngày
Môi trường : giờ thấp điểm, 1 node worker, DB không tải khác
Phản hồi : đối soát xong + sinh báo cáo chênh lệch
Đo lường : ≤ 45 phút (p95 trong 30 lần chạy)
Đo thế nào : perf/settlement-batch.js trên stg, dữ liệu sinh 1,2M bản ghi
Ai đo : QA + SRE, trước mỗi release
```
Thiếu dòng "Đo thế nào" thì `QAS` này **không dùng được**: AG3 yêu cầu bài đo thật cho mọi
`QAS` mức Must, và không ai biết phải đo gì.
## Ví dụ hội thoại
```
Bạn: /sa-2-architecture Settlement --focus qas
Claude: [Bước 0]
Input: CTX v1.0 ✅, OPT v1.0 ✅ (P2 tự xây, AG1 đã ký 2026-08-28),
BRIEF §NFR của BA (5 mục, cả 5 đều định tính)
AG1: ✅ đã qua.
Tôi đọc được 5 NFR của BA, cả 5 chưa lượng hoá được:
| NFR-01 "màn hình phải nhanh" | cần: thao tác nào, tải nào, p95 bao nhiêu |
| NFR-02 "hệ thống ổn định" | cần: % uptime ⇒ ngân sách lỗi phút/tháng |
| NFR-03 "bảo mật dữ liệu POS" | cần: mối đe doạ nào, kiểm chứng thế nào |
| NFR-04 "chịu được tăng trưởng" | cần: tăng bao nhiêu trong bao lâu |
| NFR-05 "dễ bảo trì" | không đo được ⇒ đề xuất bỏ hoặc đổi thành
"onboard dev mới ≤ 3 ngày" |
Câu tôi cần bạn hỏi PO — mỗi câu quyết định một phần kiến trúc và chi phí:
1. Hệ thống dừng 43 phút/tháng (99.9%) hay 4 phút/tháng (99.99%)?
→ chênh lệch chi phí hạ tầng khoảng 2,5×
2. Job đối soát chạy xong trước mấy giờ sáng thì chấp nhận được?
3. Chênh lệch số liệu được phép trễ bao lâu mới hiển thị? (0 giây hay 5 phút)
→ quyết định có dùng eventual consistency được không
Xác nhận giúp tôi ghi vào sa-output/Settlement/02-architecture/QAS_…_v1.0.md
với các mục chưa có câu trả lời để Confidence 🔴.
```
## Lỗi thường gặp
**"PO không trả lời được câu hỏi về uptime."**
Đừng hỏi bằng phần trăm. Hỏi bằng hệ quả: *"Nếu hệ thống dừng 40 phút vào ngày chốt sổ thì
chuyện gì xảy ra?"* — PO trả lời được câu đó. Từ câu trả lời suy ra mức SLA, rồi trình kèm
chênh lệch chi phí để PO chốt.
**"Không đo được vì chưa có hệ thống."**
Đúng, và không sao. `QAS` ở GĐ2 là **mục tiêu** kèm **cách đo đã thiết kế**. Bài đo thật chạy
ở GĐ3 (AG3). Cái phải có ngay bây giờ là con số mục tiêu và tên bài đo, không phải kết quả.
**"Chia service thế nào là đúng?"**
Không có đáp án phổ quát. Ba câu hỏi loại bớt 90% phương án sai: (1) hai phần này có bao giờ
release riêng không? (2) chúng có dùng chung dữ liệu ghi không? (3) đội vận hành có chịu nổi
thêm một service nữa không? Ba lần "không" ⇒ đừng tách.
**"Sơ đồ của tôi trông giống mọi sơ đồ khác."**
Kiểm tra: che phần chữ đi, sơ đồ còn nói được gì không? Mũi tên không nhãn giao thức, không
phân biệt sync/async là mũi tên trang trí. Thêm nhãn, hoặc bỏ mũi tên.
**"ADR nhiều quá, không ai đọc."**
Đang viết ADR cho quyết định không đạt ngưỡng. Chấm lại theo
`../sa-lifecycle/references/decision-radar.md` §2 — điểm 3–4 chỉ cần một dòng `DEC-nn`, không
cần ADR. Sổ ADR chỉ có giá trị khi mọi mục trong đó đều đáng đọc.
**"Security bảo phải làm lại toàn bộ tầng dữ liệu."**
Kinh điển, và tránh được: mời Security vào từ bước `sec`, không phải lúc trình AG2. Chi phí
sửa ở GĐ2 là vài ngày; ở GĐ3 là vài tuần.
## Ra khỏi giai đoạn này khi nào
Đủ cả năm:
1. Bảng tự chấm AG2 toàn ✅
2. **Tech Lead + Security + Ops/SRE** đã ký (`Approved by` trong header từng tài liệu)
3. Không còn `QAS` nào định tính; mọi `QAS` Must có tên bài đo
4. Mọi `ADR` điểm radar ≥ 8 đã có POC chạy xong
5. Bảng đối chiếu với bộ BA không còn dòng lệch chưa xử lý
Rồi chạy `/sa-3-enablement <PROJECT>`.
## Liên quan
- Tiêu chí gate AG2: `../sa-lifecycle/references/workflow.md` §2
- Quyết định nào cần ADR: `../sa-lifecycle/references/decision-radar.md`
- Quy tắc viết: `../sa-lifecycle/references/design-rules.md`
- Đối chiếu với bộ BA: `../sa-lifecycle/references/artifact-map.md` §7
- Template: `templates/quality-scenarios.md` · `templates/sad.md` · `templates/adr.md` ·
`templates/interface-catalog.md` · `templates/data-architecture.md` ·
`templates/security-architecture.md` · `templates/infrastructure-design.md` ·
`templates/failure-mode.md` · `templates/domain-model.md` · `templates/contract-index.md` (+
`templates/contracts/*.template.yaml`) · `templates/physical-data-model.md`
- Chuẩn sơ đồ Archify: `../ba-lifecycle/references/diagram-rules.md`; spec mẫu `templates/diagrams/`
- Kiểm bằng máy: `scripts/contract-check.mjs` (CTR) · `../ba-lifecycle/scripts/diagram-check.mjs` (sơ đồ)