222 lines
12 KiB
Markdown
222 lines
12 KiB
Markdown
# 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ơ đồ)
|