Files
sys-analysis-design/sa-output/e-commerce/02-architecture/QAS_e-commerce_v1.0.md
Canhchimlac 343ad8bbbc save
2026-09-15 16:02:30 +07:00

284 lines
35 KiB
Markdown
Raw 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.

# QAS + ASR — Quality Attribute Scenarios & Architecturally Significant Requirements — e-commerce
| | |
|---|---|
| **Version** | 1.0 |
| **Date** | 2026-09-14 |
| **Author** | SA (skill sa-2-architecture, chế độ `go`, hoạt động `qas`) |
| **Status** | 🟡 Draft *(duyệt từng phần — xem `Approved by`; AG2 cần cả ba vai trò (Tech Lead/Security/Ops-SRE) ký, mới có một chữ ký thay có điều kiện — **chưa đủ điều kiện chuyển `🔵 Approved`**)* |
| **Approved by** | Tech Lead: **Điều phối dự án** (uỷ quyền, chế độ chạy thử — ký thay theo ngoại lệ `DEC-01`, **không phải chữ ký Tech Lead thật**) — duyệt **từng phần** bản v1.0 · 2026-09-14: chấp nhận 14 `QAS-001…014` đủ 6 phần và cách đo (Phần A); chấp nhận **TẠM** các số SA tự đề xuất — `QAS-003` p95 ≤500ms, `QAS-004` p95 ≤300ms, `QAS-007` loại trừ bảo trì ≤2 giờ/tháng, `QAS-014` đối soát ≤15 phút — làm baseline tạm để GĐ2 không nghẽn; `OQ-018…021` **giữ nguyên mở**, chờ PO/Tech Lead thật xác nhận số cuối cùng. Chốt thêm điều kiện: diễn tập DR (`QAS-008`) **phải thực hiện trước khi ký AG2** — xem `OQ-022` (đã cập nhật) và ghi làm điều kiện tiên quyết của AG2, cũng là input bắt buộc cho hoạt động `inf` khi tới lượt. Ghi thêm `DEC-12`. · Security: — *(chưa ký)* · Ops/SRE: — *(chưa ký, kể cả điều kiện diễn tập DR ở `OQ-022` cũng do Ops/SRE xác nhận, chưa có)*. `OQ-004` (tính hợp lệ ký thay) vẫn mở. `Confidence` **giữ nguyên** 🔴 — duyệt từng phần không phải bằng chứng nguồn mới, không nâng `Confidence`. Status **giữ** 🟡 Draft — AG2 chưa đủ ba chữ ký thật/hợp lệ. |
| **Source** | `sa-output/e-commerce/01-context/CTX_e-commerce_v1.0.md` (v1.2) §2 (`DRV-01…09`), §3 (`CON-nn`) · `01-context/OPT_e-commerce_v1.0.md` §1, §8 (`ASM-07…09`, chọn P2) · `01-context/TCO_e-commerce_v1.0.md` §2 (kịch bản tải A/B, `ASM-10`) · `01-context/ARISK_e-commerce_v1.0.md` §3 (`ARISK-01…10`), §6 (`POC-01`, `POC-02`) · `00-index/OQ_e-commerce.md` v1.7 · `00-index/DEC_e-commerce.md` v1.8 · `ba-output/e-commerce/03-specification/NFR_US002-003_v1.0.md` (`NFR-PERF-01/02`, `NFR-SEC-01…03`, `NFR-AVL-01/02`, `OQ-033`) · `ba-output/e-commerce/03-specification/SRS_US002-003_v1.0.md` · `ba-output/e-commerce/03-specification/API_US002-003_v1.0.md` · `ba-output/e-commerce/01-discovery/BRIEF_CartCheckout_v1.0.md` §4 (`GOAL-01/02`) · `e-commerce/docs/sections/02-phan-tich-yeu-cau.md` (`NFR-01…08`) · `e-commerce/docs/SAD.md` §5.3.2, §9.4.1, §9.5.2 (RTO/RPO, ngưỡng alert — kế thừa, chưa thiết kế lại) |
| **Scope** | Toàn sàn e-commerce theo phương án **P2** (modular monolith + managed AWS, tách riêng Payment — `DEC-06`/`OQ-011`, **chưa** phải `ADR` chính thức). Chi tiết nhất: module **Giỏ hàng & Checkout** (US-002/003, `SCR-04`) — nơi BA đã có `NFR_US002-003`. Chỉ hoạt động 1/9 của `sa-2-architecture` (**QAS**) — không tạo `ASR`/`SAD`/`ADR` ở lượt này (xem Phần B, để trống có chủ đích). |
| **Confidence** | 🔴 Giả định chưa xác minh — AG1 (gate GĐ1 SA) chưa có chữ ký PO/Tech Lead thật (chỉ "PO uỷ quyền — điều phối dự án" ký từng phần dưới ngoại lệ `DEC-01…10`); `POC-01`/`POC-02` (đo throughput SQS/EventBridge, RDS gộp tải) **chưa chạy**; BA chưa ký G1 cho `BRIEF_CartCheckout`. Toàn bộ `QAS` trong tài liệu này giữ mức thấp nhất cho tới khi: (a) PO/Tech Lead ký AG1 thật, (b) `POC-01`/`POC-02` chạy xong, (c) các con số do SA **đề xuất** (chưa có nguồn PO/Tech Lead) ở mục A3 được xác nhận — xem `DEC-11`. |
## Change Log
| Version | Date | Người sửa | Thay đổi | ADR/DEC |
|---|---|---|---|---|
| 1.0 | 2026-09-14 | SA (qua skill sa-2-architecture, chế độ `go`, hoạt động `qas`) | Bản đầu — lượng hoá toàn bộ `NFR-01…08` (SAD/docs) và `NFR-PERF/SEC/AVL` (BA, `NFR_US002-003`) thành 14 `QAS-nnn` đủ sáu phần, rà đủ 7 nhóm thuộc tính (Bảo trì đánh dấu N/A có lý do). Mọi `QAS` truy vết về `DRV`/`ARISK`/`NFR` nguồn. Chạy dưới ngoại lệ gate AG1 chưa qua — ghi `DEC-11` (SA), tiếp nối `DEC-01…10`. Không tạo `ASR`/`SAD`/`ADR` ở lượt này theo yêu cầu điều phối — Phần B để trống có ghi chú. | `DEC-11` |
| 1.0 | 2026-09-14 | Điều phối dự án (thay mặt Tech Lead, ngoại lệ `DEC-01`) — tác vụ **sign/approve** | Duyệt **từng phần**: chấp nhận 14 `QAS` đủ 6 phần và cách đo; chấp nhận **TẠM** các số SA đề xuất (`QAS-003` ≤500ms, `QAS-004` ≤300ms, `QAS-007` loại trừ bảo trì ≤2h/tháng, `QAS-014` đối soát ≤15 phút) làm baseline tạm — `OQ-018…021` **giữ nguyên mở** chờ PO/Tech Lead thật. Chốt điều kiện mới: diễn tập DR (`QAS-008`) phải thực hiện **trước khi ký AG2** (cập nhật `OQ-022`, ghi thành điều kiện tiên quyết AG2 và input bắt buộc cho `INF`). Không đổi nội dung chuyên môn. Security/Ops chưa ký; `OQ-004` mở; `Confidence` giữ 🔴; Status giữ 🟡 Draft; AG2 **chưa** ký. Ghi thêm `DEC-12`. | `DEC-12` |
> Sơ đồ thắng về **quan hệ và luồng** — tài liệu này không có sơ đồ (chỉ bảng lượng hoá).
> Bảng/văn bản thắng về **ràng buộc và con số**. Mâu thuẫn ngoài hai loại này là lỗi tài liệu,
> phải sửa chứ không chọn bên (`D12`).
---
## 0. Ghi chú Preflight & ngoại lệ gate — bắt buộc đọc trước
**AG1 (gate GĐ1 SA) chưa được ký chính thức.** Audit gần nhất (2026-09-12, xem
`ARISK_e-commerce_v1.0.md` §Tự chấm, `DTM_e-commerce.md` §12): AG1 đủ cấu trúc 4/4 artifact
(`CTX`/`OPT`/`TCO`/`ARISK`, mỗi file tự chấm 7/7 tiêu chí **cấu trúc**), nhưng:
- Mọi phê duyệt đều là **"PO uỷ quyền — Điều phối dự án"**, không phải chữ ký PO/Tech Lead thật
(`OQ-004` còn mở).
- Hai `POC` bắt buộc — `POC-01` (throughput SQS/EventBridge, hạ `ARISK-01`) và `POC-02` (RDS gộp
tải, hạ `ARISK-02`) — **chưa chạy**, chỉ mới có kế hoạch + tiêu chí PASS/FAIL viết trước.
- BA chưa ký G1 chính thức cho `BRIEF_CartCheckout` (`OQ-001` của BA còn mở).
Người dùng (vai điều phối dự án chạy thử) đã được cảnh báo lại về tình trạng này và **khẳng định
muốn tiếp tục** sang GĐ2 (`sa-2-architecture`), hoạt động 1/9 (`QAS`), tham chiếu mô hình ngoại lệ
đã dùng xuyên suốt GĐ1 (`DEC-01…10`). Quyết định ngoại lệ này được ghi nhận dưới đây và tại sổ
`00-index/DEC_e-commerce.md`.
> **DEC-11 (SA)** — Bắt đầu `sa-2-architecture` (hoạt động 1 — `QAS`) cho e-commerce trong khi
> AG1 (gate GĐ1 SA) chưa có chữ ký PO/Tech Lead thật (audit 2026-09-12: AG1 🟠 — 4 artifact GĐ1
> duyệt từng phần bởi PO uỷ quyền, `Confidence` 🔴 toàn bộ; `POC-01`/`POC-02` chưa chạy; BA chưa
> ký G1 cho `BRIEF_CartCheckout`). Tiếp nối `DEC-01…10`.
> **Quyết định:** Tiếp tục lượng hoá `NFR` thành `QAS` dưới ngoại lệ gate. Mọi `QAS` giữ
> `Confidence` 🔴 cho tới khi: (a) PO/Tech Lead ký AG1 thật; (b) `POC-01`/`POC-02` chạy xong và
> kết quả được ghi vào `ARISK`; (c) các con số **SA đề xuất** (chưa có nguồn PO/Tech Lead —
> đánh dấu rõ trong mục A3) được PO/Tech Lead xác nhận qua các `OQ` mới (`OQ-018…023`).
> **Người quyết:** Điều phối dự án (đại diện PO, dự án chạy thử).
> **Radar (ước lượng):** ~4 — chi phí đảo ngược thấp (sửa lại `QAS` khi có số thật không tốn
> nhiều, đây là tài liệu chưa phải cam kết thi công) · bán kính ảnh hưởng: toàn bộ GĐ2 phụ thuộc
> `QAS` này, nhưng bản thân *việc ghi tài liệu dưới ngoại lệ* thì nhỏ · **có** chạm `QAS` Must
> trực tiếp (đang tạo chính `QAS`, không phải quyết định kiến trúc đã cam kết dựa trên nó) ·
> không ràng buộc dài hạn (ngoại lệ tạm thời, tiếp nối tiền lệ) · không tranh cãi mới → **ghi
> `DEC-nn`, không cần `ADR` riêng cho việc chạy dưới ngoại lệ** (`decision-radar.md §1–§2`) — khác
> với `ADR` cho quyết định kiểu kiến trúc P2, việc đó vẫn phải làm ở hoạt động `asr`/`adr` kế tiếp
> (đã cảnh báo ở `DTM §11` "🟠 Nợ #1").
> **Hệ quả nếu không chấp nhận ngoại lệ:** dừng GĐ2 hoàn toàn cho tới khi AG1 ký thật và
> `POC-01`/`POC-02` chạy xong — chậm tiến độ chạy thử tương ứng thời gian PO/Tech Lead xử lý các
> `OQ` đang mở (`OQ-004/005/006/007/008/010/012` của GĐ1 cộng `OQ-018…023` mới của tài liệu này).
🔴 **Nhắc quan trọng cho người đọc:** đây **chỉ là hoạt động 1/9** của `sa-2-architecture`.
`ASR` (hoạt động 2), `SAD` (hoạt động 3), `ADR`, `ICD`, `DAT`, `SEC`, `INF`, `FAIL` **chưa được
tạo** — theo đúng yêu cầu điều phối ("Không tạo ASR/SAD/ADR ở lượt này"). Thứ tự bắt buộc của
GĐ2 (`SKILL.md`: 1→2→3 trước khi làm 4–8) vẫn được tôn trọng: đây đúng là bước đầu tiên.
---
# PHẦN A — Quality Attribute Scenarios
## A1. Tóm tắt
| Nhóm thuộc tính | Số `QAS` | Must | Đã có cách đo | Đã đo thật |
|---|---|---|---|---|
| Hiệu năng | 4 (`QAS-001…004`) | 4/4 | 4/4 (k6/artillery, kịch bản cụ thể) | 0/4 |
| Thông lượng | 2 (`QAS-005/006`) | 2/2 | 2/2 (`POC-01`/`POC-02`, tiêu chí đã viết trước) | 0/2 |
| Sẵn sàng | 2 (`QAS-007/008`) | 2/2 | 2/2 (uptime monitor · diễn tập DR) | 0/2 |
| Mở rộng | 1 (`QAS-009`) | 1/1 | 1/1 *(một phần — phụ thuộc `POC-01`/`POC-02` + hoạt động `inf` chưa chạy)* | 0/1 |
| Bảo mật | 3 (`QAS-010…012`) | 3/3 | 3/3 | 0/3 |
| Bảo trì | 0 | — | — | — |
| Quan sát được | 2 (`QAS-013/014`) | 2/2 | 2/2 | 0/2 |
| **Tổng** | **14** | **14/14** | **14/14** | **0/14** |
**Nhóm không áp dụng:**
- **Bảo trì (Maintainability)** — không áp dụng ở giai đoạn `QAS` này. Lý do: mẫu đo chuẩn của
nhóm này ("một dev mới onboard và sửa được một bug thật trong ≤3 ngày", theo
`templates/quality-scenarios.md` A2) đòi hỏi **một đội thi công thật** đang làm việc trên
codebase thật — dự án chưa có đội thi công thật được xác nhận (`OQ-010` của `OPT` còn mở,
`CON-05` vẫn là giả định "team MVP chuẩn" theo `DEC-02`). Không có bài đo nào chạy được trước
khi có đội thật và có codebase để đo — theo đúng quy tắc "không đo được ⇒ bỏ hẳn, đừng ghi định
tính" (`SKILL.md` mục 1). `NFR-07` (kiến trúc module hoá để các nhóm phát triển độc lập) không
bị bỏ qua — nó là ứng viên `ASR` (ép cấu trúc modular monolith theo domain, xem `OPT §3` P2) sẽ
được xử lý ở hoạt động `asr` kế tiếp, không phải một `QAS` đo bằng con số thời gian.
**Hành động:** đo lại nhóm này trong sprint đầu tiên sau khi có đội thi công thật + codebase đủ
lớn để chọn một bug thật làm bài đo (không phải việc của lượt chạy này).
---
## A2. Mẫu một `QAS` *(tham chiếu — xem cấu trúc đầy đủ ở `templates/quality-scenarios.md`)*
---
## A3. Danh sách `QAS`
### Hiệu năng
| ID | Tên | Kích thích + môi trường | Đo lường | Đo bằng cách nào | Ai đo | Mức | Nguồn |
|---|---|---|---|---|---|---|---|
| `QAS-001` | Latency danh mục/tìm kiếm | Guest/Customer gọi `GET /v1/catalog/search`; môi trường giờ cao điểm flash sale, tải kịch bản B (10.000 concurrent user, `TCO §2` `ASM-10`) | **p95 ≤ 2 giây** | k6/artillery, kịch bản `GET /v1/catalog/search` tại 10.000 concurrent user, staging cấu hình giống production, chạy trước mỗi major release | QA + SRE | Must | `DRV-04`, `NFR-01` |
| `QAS-002` | Latency checkout | Customer/Guest gọi `POST /v1/checkout` (giỏ 2–3 seller); môi trường giờ cao điểm, tải kịch bản B | **p95 ≤ 3 giây** (bao gồm tách đơn theo seller + gọi Payment) | k6 kịch bản `POST /v1/checkout` với payload giỏ đa seller mô phỏng, tải đỉnh kịch bản B, staging, trước mỗi release | QA + SRE | Must | `DRV-01`, `DRV-02`, `NFR-01` |
| `QAS-003` | Latency tải giỏ hàng | Customer/Guest mở `SCR-04` → `GET /v1/cart`; giỏ ≤ 50 dòng (đề xuất BA, `ASM-16` mới); tải bình thường lẫn giờ cao điểm | **p95 ≤ 500ms** *(🔴 đề xuất của SA — chưa PO/Tech Lead xác nhận, nối `OQ-033` của BA, xem `OQ-018`)* | k6 kịch bản `GET /v1/cart`, 1 user và tải đồng thời tương ứng kịch bản A/B, staging | QA | Must | `NFR-PERF-01` (BA), `DRV-04` |
| `QAS-004` | Latency sửa/xoá dòng giỏ hàng | Customer/Guest gọi `PATCH`/`DELETE /v1/cart/items`; 1 request ghi đơn lẻ | **p95 ≤ 300ms** *(🔴 đề xuất của SA — chưa xác nhận, nối `OQ-033` của BA, xem `OQ-019`)* | k6 kịch bản `PATCH`/`DELETE /v1/cart/items` đơn lẻ + tải đồng thời tương ứng, staging | QA | Must | `NFR-PERF-02` (BA), `DRV-04` |
🔴 Mọi ngưỡng trên **kế thừa nguyên trạng "giả định mặc định đã chốt trong brief"** (ghi chú cuối
`docs/sections/02-phan-tich-yeu-cau.md` §2.2) — **chưa phải SLA hợp đồng**. `QAS-003`/`QAS-004`
là số **SA tự đề xuất** (không có trong `NFR_US002-003` của BA, vốn để trống chờ `OQ-033`) —
không bịa, đã gắn `ASM`/`OQ` tương ứng.
### Thông lượng
| ID | Tên | Kích thích + môi trường | Đo lường | Đo bằng cách nào | Ai đo | Mức | Nguồn |
|---|---|---|---|---|---|---|---|
| `QAS-005` | Thông lượng message bus `OrderPlaced`/`PaymentConfirmed` | Burst event publish tại đỉnh flash sale — ước ~21 event/giây trung bình (15.000 đơn/giờ × ~5 event/đơn, `TCO` kịch bản B) × biên an toàn ×5; SQS FIFO per-seller message group + EventBridge fan-out ≥ 5 consumer rule, AWS `ap-southeast-1` thật | Thông lượng **sustained ≥ 100 msg/s** trong 30 phút; **p99 độ trễ publish→consume ≤ 2 giây**; **0 message mất**; fan-out lag ≤ 5 giây | **`POC-01`** (đã lập ở `ARISK §6`) — k6/artillery load generator, AWS thật, tối đa 5 ngày làm việc, **chưa chạy** | Tech Lead + 1 DevOps | Must | `DRV-04`, `ARISK-01`, `ASM-07` (OPT) |
| `QAS-006` | Thông lượng RDS gộp (ghi checkout + đọc catalog) | Đồng thời ~15.000 đơn/giờ (ghi) + ~150.000 truy vấn catalog/giờ (đọc, ×10 tải ghi) trên 1 cụm RDS chính (P2, schema-per-module, không tính Payment); staging `db.r6g.xlarge` Multi-AZ, dataset ~50GB/300k SKU (kịch bản A) | **p95 write (checkout) ≤ 300ms**, **p95 read (catalog) ≤ 200ms**, **CPU RDS < 75%**, connection pool không exhaust | **`POC-02`** (đã lập ở `ARISK §6`) — load test staging cấu hình instance thật, tối đa 5 ngày, **chưa chạy** | Tech Lead/DBA | Must | `DRV-04`, `ARISK-02`, `ASM-08` (OPT) |
🔴 Cả hai `QAS` này **không tạo bài đo mới** — chúng chính là `POC-01`/`POC-02` đã có kế hoạch ở
`ARISK_e-commerce_v1.0.md §6` (theo đúng ghi chú người duyệt: "ARISK-01/02 chính là bài đo").
Việc còn lại là **chạy POC**, không phải thiết kế lại tiêu chí.
### Sẵn sàng
| ID | Mục tiêu | Ngân sách lỗi | Phạm vi tính | Không tính vào | Đo bằng cách nào | Mức |
|---|---|---|---|---|---|---|
| `QAS-007` | 99.9%/tháng cho dịch vụ giao dịch lõi (Catalog, Checkout, Payment, Identity — `SAD §3.1`) | **43 phút/tháng** | API công khai của 4 service trên | Bảo trì có báo trước **≤ 2 giờ/tháng** *(🔴 đề xuất của SA — chưa PO xác nhận, xem `OQ-020`, `ASM-17` mới)* | Uptime/health-check monitor (CloudWatch Synthetics hoặc tương đương), tính theo tháng, báo cáo hàng tháng cho SRE | Must |
| ID | Nhóm service | RPO | RTO | Đo bằng cách nào | Mức |
|---|---|---|---|---|---|
| `QAS-008` | Payment, Cart & Order, Identity & Access (giao dịch cốt lõi) | **≤ 15 phút** | **≤ 1 giờ** | Diễn tập DR (failover drill) — **CHƯA TỪNG DIỄN TẬP**; con số kế thừa nguyên trạng từ `SAD §5.3.2`/`§9.5.2`, chưa thiết kế lại (thuộc hoạt động `inf`, chưa chạy). Theo `SKILL.md` mục 7: "RTO/RPO chưa diễn tập là RTO/RPO trên giấy" ⇒ `Confidence` 🔴, cần lịch diễn tập trước AG2 (xem `OQ-022`) | Must |
🔴 **`QAS-008` không phải RTO/RPO mới** — SA **không thiết kế lại** HA/DR ở lượt chạy này (đó là
hoạt động `inf`, chưa chạy); ghi lại đây để `QAS` nhóm Sẵn sàng đầy đủ theo yêu cầu template,
nhưng con số vẫn là **đề xuất kế thừa từ SAD**, chưa qua diễn tập thật — thấp hơn cả mức "ước
lượng có cơ sở".
### Mở rộng
| ID | Tải hôm nay | Tải mục tiêu | Trong bao lâu | Scale bằng cách nào | Giới hạn trên | Mức |
|---|---|---|---|---|---|---|
| `QAS-009` | 0 (chưa go-live, greenfield) | Kịch bản A (Năm 1): **2.000 concurrent user**, ~400 đơn/giờ đỉnh · Kịch bản B (đỉnh flash sale): **10.000 concurrent user**, ~15.000 đơn/giờ đỉnh (≈4,2 đơn/giây) — `TCO §2`, `ASM-10` | Từ go-live tới đợt flash sale đầu tiên — **thời điểm cụ thể chưa xác nhận** (🔴 mới, xem `OQ-018`… không, xem ghi chú dưới) | ECS Fargate auto-scaling theo CPU/request count cho nhóm "giao dịch" (Cart/Order/Catalog) — **ngưỡng kích hoạt cụ thể chưa chốt**, thuộc hoạt động `inf` (chưa chạy) | Chưa xác định — đề xuất xét lại kiến trúc nếu tải thật vượt kịch bản B ×2 (~20.000 concurrent) mà chưa kiểm chứng lại (xem "Ngoài phạm vi" §D) | Must |
*Bài đo cho `QAS-009` tái sử dụng chính `QAS-005`/`QAS-006` (`POC-01`/`POC-02`) chạy lần lượt ở
kịch bản A rồi kịch bản B — không tạo bài đo trùng lặp.*
### Bảo mật
| ID | Mối đe doạ | Yêu cầu | Kiểm chứng bằng cách nào | `THR-nn` liên quan | Mức |
|---|---|---|---|---|---|
| `QAS-010` | IDOR — request giả mạo `cartItemId`/`session` không phải chủ sở hữu lên `PATCH`/`DELETE /v1/cart/items` | 100% request phải qua kiểm tra quyền sở hữu (đối chiếu `customerId`/`sellerId` JWT hoặc `session_id` Guest); 0 lượt IDOR thành công | Security test tự động (integration test gọi thẳng API với token/session không phải chủ sở hữu — tương ứng `AC-US003-12/13` của BA) trên staging trước mỗi release | *(chưa có — `THR` thuộc hoạt động `sec`, chưa chạy)* | Must |
| `QAS-011` | Rò rỉ/chia sẻ thừa PII (địa chỉ, SĐT người nhận) cho seller khi tách đơn — vi phạm NĐ13/2023 | 100% trường PII chia sẻ cho seller đã qua rà soát Pháp chế/Security trước go-live (data minimization: chỉ trường cần thiết để giao hàng); 0 trường dư thừa bị lộ qua audit | Review thủ công bởi đại diện Pháp chế/Security (**chưa có người — kế thừa `OQ-007` của `CTX`/`ARISK-06`**) đối chiếu danh sách field SA chuẩn bị, cộng kiểm thử so khớp field thực tế truyền cho seller vs danh sách đã duyệt | *(chưa có — `THR` thuộc hoạt động `sec`)* | Must |
| `QAS-012` | Bypass MFA khi đăng nhập Admin | 100% đăng nhập Admin bắt buộc bước MFA thứ hai, 0 lượt bypass; Seller: khuyến khích (không bắt buộc) | Test tự động: đăng nhập Admin không qua MFA phải bị từ chối; audit log đăng nhập admin rà soát hàng tháng | *(chưa có — `THR` thuộc hoạt động `sec`)* | Must (Admin) / Should (Seller) |
*Không ghi "bảo mật" như một mục — mỗi dòng trên nêu đúng một mối đe doạ cụ thể. Threat model
STRIDE đầy đủ (`THR-nn`) là hoạt động `sec`, **chưa chạy** ở lượt này; ba `QAS` trên là input đầu
vào cho hoạt động đó, không thay thế nó.*
### Bảo trì
*Xem "Nhóm không áp dụng" ở A1 — không có `QAS` nào trong nhóm này ở lượt chạy này.*
### Quan sát được
| ID | Kịch bản | Đo lường | Đo bằng cách nào | Mức |
|---|---|---|---|---|
| `QAS-013` | Sự cố tăng đột biến lỗi 5xx ở service giao dịch cốt lõi (Cart & Order, Payment, Identity) | Cảnh báo tự động trong **≤ 1 phút** (health check fail liên tục > 1 phút — kế thừa `SAD §9.4.1`); on-call acknowledge trong **≤ 15 phút** (`NFR-08`), quá hạn thì escalate | Diễn tập inject lỗi (chaos/fault injection thủ công — dừng task ECS) trên staging trước go-live, đo thời gian từ inject tới cảnh báo xuất hiện trên kênh (PagerDuty/OpsGenie) — **chưa từng diễn tập** | Must |
| `QAS-014` | Webhook xác nhận thanh toán VNPay/Momo trễ/lỗi khiến đơn kẹt "chờ thanh toán" dù tiền đã thu (`DRV-08`) | Job đối soát phát hiện lệch trạng thái trong **≤ 15 phút** kể từ khi giao dịch được xác nhận phía cổng thanh toán *(🔴 đề xuất của SA — `SAD §3.4` chưa chốt tần suất job cụ thể, xem `OQ-021`, `ASM-18` mới)* | Test giả lập webhook trễ/mất trên staging — **cần sandbox VNPay/Momo thật, hiện CHƯA có (`ARISK-03`)**; đo thời gian phát hiện qua log job đối soát | Must |
---
## A4. `QAS` xung đột nhau
| `QAS` A | `QAS` B | Xung đột ở đâu | Phương án cân bằng | Ai quyết | `ADR` |
|---|---|---|---|---|---|
| `QAS-010` (kiểm tra ownership mọi request `PATCH`/`DELETE /v1/cart/items`) | `QAS-003`/`QAS-004` (latency ≤500ms/≤300ms) | Mỗi lần kiểm tra ownership cần đối chiếu JWT/session với chủ sở hữu `CartItem` — nếu tra DB mỗi lần sẽ ăn vào ngân sách latency vốn đã eo hẹp (đề xuất) | Cache thông tin ownership/session trong Redis thay vì query DB mỗi request; đo lại `QAS-003`/`004` sau khi có thiết kế cụ thể | Tech Lead (quyết định thi công, không phải trade-off nghiệp vụ) | *(chưa có — sẽ chốt ở hoạt động `asr`/`adr` kế tiếp nếu cần)* |
| `QAS-005` (SQS FIFO per-seller message group, sustained ≥100 msg/s) | `QAS-009` (mở rộng tới kịch bản B, ~4,2 đơn/giây × ~5 event/đơn) | AWS giới hạn cứng throughput cho **một message group** SQS FIFO (không phải toàn hàng đợi) — nếu một seller có volume rất cao, event của riêng seller đó có thể chạm trần group dù tổng hệ thống chưa chạm 100 msg/s; đảm bảo **thứ tự xử lý đúng theo seller** (liên quan `DRV-06` — tính nhất quán dữ liệu tài chính) buộc serialize trong group đó | Cần quyết định ở `ADR` message backbone: chấp nhận rủi ro cho seller lớn (theo dõi + cảnh báo riêng), hay thiết kế sharding/batching cho seller volume cao | Tech Lead + PO (ảnh hưởng kiến trúc + rủi ro vận hành cho seller lớn) | *(chưa có — `ADR` message backbone thuộc hoạt động `asr`/`adr` kế tiếp, `POC-01` phải chạy trước khi chốt)* |
---
# PHẦN B — Architecturally Significant Requirements
## Ghi chú phạm vi — KHÔNG thực hiện ở lượt chạy này
Theo yêu cầu điều phối ("Không tạo ASR/SAD/ADR ở lượt này"), Phần B **để trống có chủ đích**.
`sa-2-architecture` yêu cầu thứ tự bắt buộc 1 (`QAS`) → 2 (`ASR`) → 3 (`SAD`) — tài liệu này đã
hoàn thành đúng bước 1. Hoạt động `--focus asr` kế tiếp phải:
- Rà toàn bộ 9 `DRV` ở `CTX §2` (chưa `DRV` nào có `ASR`/`QAS` phục vụ, theo `DTM §2` — 0/9,
"kỳ vọng đúng lúc này").
- Rà 14 `QAS` Must ở Phần A trên — mọi `QAS` Must là ứng viên trực tiếp cho `ASR` (theo tiêu chí
B1 của template: *"có `QAS` mức Must đứng sau"*).
- Ứng viên `ASR` quan sát được trong lúc làm `QAS` (ghi lại để hoạt động `asr` không phải dò lại
từ đầu, **không phải `ASR` chính thức**):
- Ép hàng đợi bền + cơ chế đối soát bù cho xác nhận thanh toán bên thứ ba (`DRV-08`, `QAS-014`).
- Ép biên cô lập Payment Service (network/IAM riêng) cho PCI-DSS SAQ A (`CON-06`, đã có trong
`OPT` P2, chưa phải `ASR` chính thức).
- Ép ranh giới message group theo seller cho thông lượng/thứ tự sự kiện (`DRV-06`, `QAS-005`,
xung đột A4 dòng 2) — cần `ADR` message backbone.
- Ép rà soát PII trước khi chia sẻ cho seller (`DRV-07`, `QAS-011`) — cần người phụ trách
(`OQ-007` còn mở) trước khi có thể "Đã thiết kế".
- `DEC-06` (chọn P2) phải được nâng thành `ADR` chính thức ngay khi hoạt động `asr`/`adr` bắt đầu
(đã cảnh báo ở `DTM §11` "🟠 Nợ #1", radar ước lượng ~7 — **chưa đủ ngưỡng ≥8 bắt buộc POC**
nhưng `POC-01` vẫn cần chạy trước khi `Accepted` vì bản thân `ASM-07` chưa xác minh).
---
## C. Đối chiếu với `NFR` của bộ BA
| `NFR` của BA/SAD | Nội dung gốc | `QAS` tương ứng | Đã lượng hoá | Hành động |
|---|---|---|---|---|
| `NFR-01` (SAD) | Catalog/search <2s, checkout <3s | `QAS-001`, `QAS-002` | ✅ (số giữ nguyên, `Confidence` 🔴 vì chưa SLA) | Không đổi số — QAS tham chiếu đúng NFR-01, không có lệch |
| `NFR-02` (SAD) | Scale-out ngang, cache/CDN/MQ, hàng nghìn–chục nghìn concurrent | `QAS-005`, `QAS-006`, `QAS-009` | ✅ (cụ thể hoá thành 2 kịch bản A/B với số concurrent/throughput rõ) | Không lệch — là làm rõ thêm, không đổi ý nghĩa |
| `NFR-03` (SAD) | Uptime 99.9% dịch vụ giao dịch lõi | `QAS-007`, `QAS-008` | ✅ (thêm ngân sách lỗi 43 phút/tháng + RTO/RPO kế thừa) | Không lệch |
| `NFR-04` (SAD) | Bảo mật PII, MFA | `QAS-011`, `QAS-012` | ✅ (một phần — `THR` STRIDE đầy đủ chờ hoạt động `sec`) | Hoạt động `sec` kế tiếp bổ sung `THR-nn` |
| `NFR-05` (SAD) | PCI-DSS, NĐ52/85, NĐ13/2023 | `QAS-011` (một phần) | 🟡 Một phần | Phần PCI-DSS (biên cô lập Payment) chưa có `QAS` riêng — thuộc `SEC`/`ADR` hoạt động sau |
| `NFR-06` (SAD) | Đa ngôn ngữ 5 thứ tiếng | *(không có `QAS`)* | ❌ Không lượng hoá thành `QAS` | Đây là yêu cầu chức năng/UI (chiến lược i18n), không phải thuộc tính chất lượng đo bằng con số kiểu latency/throughput — sẽ thành `ASR` (ép chiến lược tách chuỗi hiển thị khỏi code) ở hoạt động `asr`, không phải `QAS` |
| `NFR-07` (SAD) | Bảo trì — kiến trúc module hoá | *(không có `QAS`, xem A1)* | ❌ N/A có lý do | Xem "Nhóm không áp dụng" A1 — chờ đội thi công thật (`OQ-010`) |
| `NFR-08` (SAD) | Vận hành — 3 môi trường, on-call 24/7 sự cố nghiêm trọng | `QAS-013` | ✅ | Không lệch |
| `NFR-PERF-01` (BA, `OQ-033`) | Ngưỡng `GET /v1/cart` — chưa chốt | `QAS-003` | 🟡 SA đề xuất 500ms | **`QAS` thắng `NFR`** — BA nên cập nhật `NFR_US002-003` §1 tham chiếu `QAS-003`, giữ `OQ-033` mở cho tới khi PO/Tech Lead xác nhận qua `OQ-018` |
| `NFR-PERF-02` (BA, `OQ-033`) | Ngưỡng `PATCH`/`DELETE /v1/cart/items` — chưa chốt | `QAS-004` | 🟡 SA đề xuất 300ms | Tương tự — BA cập nhật tham chiếu `QAS-004`, `OQ-019` |
| `NFR-SEC-01` (BA) | IDOR ownership check | `QAS-010` | ✅ Khớp hoàn toàn | Không lệch |
| `NFR-SEC-02` (BA) | Cookie Guest `HttpOnly/Secure/SameSite` | *(không có `QAS` — thuộc mô hình xác thực)* | — | Thuộc hoạt động `sec` (mô hình authn), không phải `QAS` số |
| `NFR-SEC-03` (BA) | Rate limit `PATCH`/`DELETE` Guest — "SAD định nghĩa" nhưng SAD cũng chưa có số cụ thể | *(chưa có `QAS`)* | ❌ Khoảng trống thật | Cần Tech Lead/Security chốt số cụ thể ở hoạt động `sec`/`icd` — ghi `OQ-023` |
| `NFR-AVL-01/02` (BA) | Banner lỗi khi Cart & Order Service lỗi/chậm | *(không có `QAS` — thuộc `FAIL`)* | — | Thuộc hoạt động `fail` (failure mode), không phải `QAS` |
| `NFR-AUD` (BA) | N/A cho `CartItem` | *(không áp dụng)* | ✅ Nhất quán | Không cần `QAS` |
---
## D. Giả định & Ngoài phạm vi
**Giả định** *(tiếp số toàn dự án — `ASM-01…15` đã dùng ở `CTX`/`OPT`/`TCO`, bắt đầu `ASM-16`)*:
| ID | Giả định | Cách xác minh | Nếu sai thì `QAS` nào đổi |
|---|---|---|---|
| `ASM-16` | Giỏ hàng có tối đa ~50 dòng/giỏ (đề xuất BA `NFR-PERF-01`) đủ làm baseline đo `GET /v1/cart` | Đo phân phối số dòng/giỏ thật trong 4–6 tuần đầu soft-launch (cùng đợt với `DRV-02` `GOAL-01`) | `QAS-003` — giỏ lớn hơn nhiều lần có thể cần phân trang/lazy-load, đổi cả ngưỡng latency lẫn thiết kế API |
| `ASM-17` | Cửa sổ bảo trì có báo trước ≤ 2 giờ/tháng được loại khỏi ngân sách lỗi 99.9% | PO xác nhận chính sách bảo trì (`OQ-020`) | `QAS-007` — nếu PO không chấp nhận loại trừ, ngân sách lỗi thực tế hẹp hơn 43 phút/tháng |
| `ASM-18` | Job đối soát thanh toán chạy đủ nhanh (đề xuất ≤15 phút) để phát hiện lệch trạng thái trước khi ảnh hưởng đáng kể tới CSKH | Tech Lead xác nhận tần suất job thật (`OQ-021`), đo lại sau khi có sandbox VNPay/Momo | `QAS-014` — tần suất chậm hơn thực tế cần thiết kế lại (webhook + polling kết hợp, hoặc rút ngắn chu kỳ) |
*`ASM-01…15` của `CTX`/`OPT`/`TCO` (đặc biệt `ASM-07` → `QAS-005`, `ASM-08` → `QAS-006`,
`ASM-10` → `QAS-009`, `ASM-04` → residency liên quan `QAS-011`) vẫn áp dụng nguyên trạng — không
lặp lại nội dung, chỉ tham chiếu theo `artifact-map.md §7`.*
**Ngoài phạm vi:**
- `ASR`/`SAD`/`ADR`/`ICD`/`DAT`/`SEC`/`INF`/`FAIL` — chưa thực hiện ở lượt chạy này (chỉ hoạt
động `qas`), theo đúng yêu cầu điều phối. Xem Phần B để biết ứng viên `ASR` đã quan sát được.
- Kiến trúc này (P2, chưa `Accepted` bằng `ADR`) không nhắm tới tải vượt kịch bản B (10.000
concurrent) **×2** (~20.000 concurrent) mà chưa kiểm chứng lại bằng `POC`/bài đo thật — ngưỡng
phải xét lại nếu traffic thật sau go-live tiệm cận mức này.
- `NFR-06` (i18n)/`NFR-07` (bảo trì qua module hoá) không được lượng hoá thành `QAS` số — xử lý
qua `ASR` (chiến lược i18n) và bằng cách đánh dấu N/A có lý do (bảo trì), không phải bỏ sót.
- `QAS-008` (RTO/RPO) và ngưỡng cảnh báo ở `QAS-013` **kế thừa nguyên trạng** từ `SAD §5.3.2/
§9.4.1/§9.5.2` — SA **không** thiết kế lại HA/DR/observability ở lượt này (đó là hoạt động
`inf`, chưa chạy); chỉ ghi lại để nhóm Sẵn sàng/Quan sát được của `QAS` đầy đủ theo template.
## E. Open Questions
*Tiếp số sổ SA (`00-index/OQ_e-commerce.md` đang ở `OQ-017`) — bắt đầu `OQ-018`.*
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | Hệ quả nếu trả lời ngược |
|---|---|---|---|---|---|
| `OQ-018` | Ngưỡng p95 cho `GET /v1/cart` là bao nhiêu? SA đề xuất ≤500ms (nối `OQ-033` của BA). | PO + Tech Lead | 2026-09-14 | `QAS-003` baseline; bài đo `FIT` ở GĐ3 | Nếu PO/Tech Lead muốn ngưỡng chặt hơn (VD ≤200ms): có thể cần thiết kế cache Redis mạnh hơn hoặc bỏ bớt dữ liệu trả về (VD ảnh sản phẩm rút gọn); nếu lỏng hơn (VD ≤1s): giảm áp lực thiết kế cache, nhưng tăng rủi ro trải nghiệm kém ở `DRV-02` (bỏ giỏ) |
| `OQ-019` | Ngưỡng p95 cho `PATCH`/`DELETE /v1/cart/items` là bao nhiêu? SA đề xuất ≤300ms (nối `OQ-033` của BA). | PO + Tech Lead | 2026-09-14 | `QAS-004` baseline; bài đo `FIT` ở GĐ3 | Tương tự `OQ-018` — ngưỡng chặt hơn cần tối ưu ghi (VD giảm số lần round-trip DB); ngưỡng lỏng hơn giảm áp lực thiết kế |
| `OQ-020` | Cửa sổ bảo trì có báo trước (nếu có) được loại trừ khỏi ngân sách lỗi 99.9%/tháng là bao nhiêu giờ? SA đề xuất ≤2 giờ/tháng. | PO | 2026-09-14 | `QAS-007` (ngân sách lỗi thật); chính sách release ở `INF` (chưa chạy) | Nếu PO không chấp nhận loại trừ nào: ngân sách lỗi thực tế thu hẹp còn đúng 43 phút/tháng kể cả bảo trì có kế hoạch — cần chiến lược blue-green/zero-downtime deploy nghiêm ngặt hơn, tăng chi phí vận hành |
| `OQ-021` | Tần suất chạy job đối soát thanh toán (reconciliation) là bao nhiêu? SA đề xuất ≤15 phút/lần. | Tech Lead | 2026-09-14 | `QAS-014`; thiết kế job đối soát ở `DAT`/`INF` (chưa chạy) | Nếu tần suất thật thưa hơn (VD hàng giờ): thời gian phát hiện đơn kẹt "chờ thanh toán" lâu hơn, tăng rủi ro khiếu nại CSKH (`DRV-08`, `RISK-02` của BA) |
| `OQ-022` | Lịch diễn tập DR (failover drill) đầu tiên cho nhóm service giao dịch cốt lõi là khi nào? **Đã chốt điều kiện (sign 2026-09-14, `DEC-12`): phải thực hiện TRƯỚC khi ký AG2** — ngày/lịch cụ thể vẫn chờ Ops/SRE. | Ops/SRE | 2026-09-14 | `QAS-008` (nâng `Confidence` từ 🔴); điều kiện tiên quyết ký AG2 (đã ghi vào điều kiện AG2, xem header) | Nếu không diễn tập trước AG2: Ops/SRE từ chối ký AG2 (theo `workflow.md §2` AG2 — "Chặn: RTO/RPO chưa diễn tập"), phải lùi gate — điều kiện này nay là bắt buộc, không còn là lựa chọn "ký có điều kiện kèm ARISK mới" |
| `OQ-023` | Ngưỡng rate limit cụ thể (số request/phút theo IP) cho `PATCH`/`DELETE /v1/cart/items` của Guest là bao nhiêu? `NFR-SEC-03` của BA ghi "SAD định nghĩa" nhưng SAD cũng chưa có số. | Tech Lead + Security | 2026-09-14 | Hoạt động `sec`/`icd` kế tiếp; `NFR-SEC-03` của BA | Không có ngưỡng ⇒ rủi ro lạm dụng API (spam thêm/xoá giỏ hàng) không bị chặn — cần Security chấp nhận rủi ro tạm thời nếu chưa chốt được số trước go-live |
**Nhắc:** cộng với `OQ-010` (kinh nghiệm team thật — ảnh hưởng gián tiếp `QAS-005`/`ASM-05` mới
tương tự `ARISK-05`) và `OQ-012` (thời điểm chạy `POC-01`, đã đóng có điều kiện — POC phải chạy
trước `ADR` message backbone) còn mở từ GĐ1, xem sổ đầy đủ `00-index/OQ_e-commerce.md`.