417 lines
55 KiB
Markdown
417 lines
55 KiB
Markdown
# ASR — Architecturally Significant Requirements — e-commerce
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Version** | 1.0 |
|
||
| **Date** | 2026-09-14 |
|
||
| **Author** | SA (skill sa-2-architecture, chế độ `go`, hoạt động `asr`) |
|
||
| **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-15: chấp nhận 15 `ASR-001…015` (14 `Must` + 1 `Should`) đủ nguồn/"vì sao định hình kiến trúc"/cấu trúc bị ép, và chấp nhận danh sách 12 `ADR` ứng viên (`ADR-001…012`, §B2) với radar ước lượng đã ghi kèm; xác nhận `ADR-005`/`ADR-006`/`ADR-009` (radar ước lượng ≥8) **chỉ được chuyển `Accepted`** sau khi `POC-01`/`POC-02`/diễn tập DR (Ops/SRE) chạy xong, đúng `decision-radar.md §2`/§6 — không ký tắt qua bước đo. Chốt **TẠM** `OQ-024` (phương thức MFA Admin = TOTP app, theo `ASM-20`) và `OQ-025` (không dịch nội dung seller tự nhập ở MVP, chỉ i18n UI hệ thống, theo `ASM-21`) làm hướng đi tạm để `sad`/`sec` kế tiếp không nghẽn — **`OQ-024`/`OQ-025` giữ nguyên MỞ**, chờ Security/PO thật xác nhận, không coi là đã đóng. Ký thay Tech Lead theo ngoại lệ `DEC-01` (SA) — **không phải chữ ký Tech Lead thật**. · Security: — *(chưa ký)* · Ops/SRE: — *(chưa ký)* — AG2 cần cả ba cùng ký; tài liệu này **vẫn chưa qua AG2**. `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ệ. Ghi thêm `DEC-14`. |
|
||
| **Source** | `01-context/CTX_e-commerce_v1.0.md` (v1.2) §2 (`DRV-01…09`), §3 (`CON-01…09`) · `01-context/OPT_e-commerce_v1.0.md` §1, §3 (P2), §5 (P3/P4 loại), §8 (`ASM-07…09`) · `01-context/ARISK_e-commerce_v1.0.md` §3 (`ARISK-01…10`), §6 (`POC-01`/`POC-02`) · `02-architecture/QAS_e-commerce_v1.0.md` v1.0 (toàn bộ `QAS-001…014`, đặc biệt Phần B "Ghi chú phạm vi") · `00-index/OQ_e-commerce.md` v1.9 · `00-index/DEC_e-commerce.md` v1.10 · `00-index/DTM_e-commerce.md` §11 ("🟠 Nợ #1" — `ADR-001`) · `00-index/ADL_e-commerce.md` §8 (việc phải làm #1) · `ba-output/e-commerce/02-analysis/BR_CartCheckout_v1.0.md` (`BR-CART-01…09`) · `ba-output/e-commerce/02-analysis/RBAC_CartCheckout_v1.0.md` (`ROLE-01/02`, ma trận §2, §4, §6) · `ba-output/e-commerce/02-analysis/IMPACT_CartCheckout_v1.0.md` · `ba-output/e-commerce/03-specification/API_US002-003_v1.0.md` · `e-commerce/docs/sections/02-phan-tich-yeu-cau.md` (`NFR-01…08`) · `e-commerce/docs/sections/03-kien-truc.md` §3.1–§3.4 (tham khảo, kế thừa nguyên trạng — không thiết kế lại ở lượt này) |
|
||
| **Scope** | Toàn sàn e-commerce theo phương án **P2** (modular monolith + managed AWS, tách riêng Payment Service — `DEC-06`, chưa phải `ADR` chính thức). Chi tiết nhất: module **Giỏ hàng & Checkout** (US-002/003, `BR-CART-01…09`, `RBAC` `ROLE-01/02`). Chỉ hoạt động 2/9 của `sa-2-architecture` (**ASR**) — không tạo `SAD`/`ADR`/`ICD`/`DAT`/`SEC`/`INF`/`FAIL` ở lượt này; `QAS` (hoạt động 1) đã có ở `QAS_e-commerce_v1.0.md`, duyệt từng phần theo `DEC-12`. |
|
||
| **Confidence** | 🔴 Giả định chưa xác minh — theo yêu cầu điều phối. AG1 chưa có chữ ký PO/Tech Lead thật (`OQ-004` mở); `POC-01`/`POC-02` chưa chạy; BA chưa ký G1 cho `BRIEF_CartCheckout`; `QAS` nguồn của phần lớn `ASR` dưới đây cũng đang giữ `Confidence` 🔴 (xem `QAS_e-commerce_v1.0.md` header). Mọi `ASR` giữ mức thấp nhất cho tới khi: (a) AG1 ký thật, (b) `POC-01`/`POC-02` chạy xong, (c) các `OQ` nguồn (`OQ-002/007/010/012/018…025`) được trả lời. |
|
||
|
||
## 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 `asr`) | Bản đầu — chưng cất 15 `ASR-nnn` từ `DRV`/`CON`/`QAS` (GĐ1–2 SA) và `BR-CART`/`ROLE` (BA), bao phủ đủ 14 nhóm bắt buộc theo ghi chú người duyệt (tách đơn theo seller, Payment cô lập, webhook idempotent + đối soát, message backbone + giới hạn FIFO group, RDS gộp, ownership check, PII/residency, MFA Admin, HA/DR + drill, observability, AWS bắt buộc, đối tác thanh toán/vận chuyển, ranh giới module Conway, đa ngôn ngữ) cộng 1 `ASR` tổng thể (kiểu kiến trúc P2, gắn `ADR-001` đang nợ theo `DTM`/`ADL`). Mỗi `ASR` có nguồn, "vì sao định hình kiến trúc", cấu trúc bị ép, đánh giá radar ước lượng và `ADR` ứng viên (số dự kiến — hoạt động `adr` kế tiếp xác nhận lại thứ tự thật). Không viết `ADR` ở lượt này. Thêm `OQ-024`/`OQ-025` (phương thức MFA Admin, chủ sở hữu chiến lược i18n) và `ASM-19…21`. Ghi `DEC-13` (tiếp nối `DEC-01…12`, ngoại lệ gate tiếp tục GĐ2 hoạt động `asr`). Không sửa `QAS`/`CTX`/`OPT` đã duyệt từng phần. `Confidence` 🔴 toàn bộ. | `DEC-13` |
|
||
| 1.0 | 2026-09-15 | Đ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 15 `ASR-001…015` (14 `Must` + 1 `Should`) và danh sách 12 `ADR` ứng viên (`ADR-001…012`, §B2) với radar ước lượng; xác nhận `ADR-005`/`ADR-006`/`ADR-009` (radar ≥8) chỉ được `Accepted` sau khi `POC-01`/`POC-02`/diễn tập DR chạy xong. Chốt **TẠM** `OQ-024` (MFA Admin = TOTP app, `ASM-20`) và `OQ-025` (không dịch nội dung seller tự nhập ở MVP, chỉ i18n UI hệ thống, `ASM-21`) làm hướng đi tạm — cả hai **giữ nguyên mở**, chờ Security/PO thật xác nhận. 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-14`. | `DEC-14` |
|
||
|
||
> Sơ đồ thắng về **quan hệ và luồng** — tài liệu này không có sơ đồ mới (chỉ bảng chưng cất yêu
|
||
> cầu). 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) vẫn chưa được ký chính thức**, và **AG2 (gate của chính GĐ2) càng chưa tới
|
||
hạn** — tài liệu này mới là hoạt động 2/9 của GĐ2. Tình trạng kế thừa nguyên vẹn từ
|
||
`QAS_e-commerce_v1.0.md` §0 và `ARISK`/`OPT` §Tự chấm: AG1 4/4 artifact đủ cấu trúc nhưng nội
|
||
dung còn `OQ-004` (tính hợp lệ ký thay), `OQ-005/006/007/008/010/012` (số/người thật) mở,
|
||
`POC-01`/`POC-02` chưa chạy.
|
||
|
||
Người dùng (vai điều phối dự án chạy thử) đã được cảnh báo lại và **khẳng định muốn tiếp tục**
|
||
sang hoạt động 2 (`ASR`) của `sa-2-architecture`, sau khi hoạt động 1 (`QAS`) đã được duyệt từng
|
||
phần (`DEC-12`). Quyết định ngoại lệ này được ghi tại `DEC-13` dưới đây và tại sổ
|
||
`00-index/DEC_e-commerce.md`.
|
||
|
||
> **DEC-13 (SA)** — Tiếp tục `sa-2-architecture` (hoạt động 2 — `ASR`) cho e-commerce trong khi
|
||
> AG1 chưa có chữ ký PO/Tech Lead thật và AG2 (gate của chính GĐ2) chưa tới hạn — tiếp nối
|
||
> `DEC-01…12`.
|
||
> **Quyết định:** Chưng cất 15 `ASR` từ `DRV`/`CON`/`QAS`/`BR-CART`/`ROLE` đã có, giữ
|
||
> `Confidence 🔴` cho tới khi nguồn tương ứng được xác nhận thật (đặc biệt: AG1 ký thật,
|
||
> `POC-01`/`POC-02` chạy xong, `OQ-002/007/010/012/018…025` được trả lời).
|
||
> **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 (chưng cất `ASR` từ tài liệu đã có, sửa lại
|
||
> không tốn nhiều nếu nguồn đổi) · bán kính ảnh hưởng: toàn bộ hoạt động `sad`/`adr` kế tiếp phụ
|
||
> thuộc danh sách 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 chưng cất từ chính các `QAS` Must) nhưng chưa phải quyết định kiến trúc đã
|
||
> cam kết thi công · không ràng buộc dài hạn (danh sách `ASR` có thể sửa khi nguồn đổi, chưa phải
|
||
> `ADR` bất biến) · không tranh cãi mới, tiếp nối tiền lệ `DEC-11/12` → **ghi `DEC-nn`, không cần
|
||
> `ADR` cho việc chạy dưới ngoại lệ** (`decision-radar.md §1–§2`) — khác với các `ADR` ứng viên
|
||
> liệt kê ở §B2 dưới đây, việc đó vẫn để hoạt động `sad`/`adr` kế tiếp.
|
||
> **Hệ quả nếu không chấp nhận ngoại lệ:** dừng GĐ2 ở hoạt động `qas`, không có `ASR` để hoạt
|
||
> động `sad` (bắt buộc có trước theo thứ tự 1→2→3 của `SKILL.md`) dùng làm đầu vào — chậm tiến độ
|
||
> chạy thử tương ứng thời gian xử lý các `OQ` đang mở.
|
||
|
||
🔴 **Nhắc quan trọng:** đây là hoạt động 2/9. `SAD` (hoạt động 3), `ADR`, `ICD`, `DAT`, `SEC`,
|
||
`INF`, `FAIL` **chưa được tạo**. Theo `SKILL.md`: "1→2→3 bắt buộc trước; 4–8 chạy song song
|
||
được" — `ASR` này là điều kiện đầu vào bắt buộc cho `SAD` (hoạt động 3) kế tiếp.
|
||
|
||
---
|
||
|
||
# PHẦN B — Architecturally Significant Requirements
|
||
|
||
## B0. Tóm tắt
|
||
|
||
| Nhóm | Số `ASR` | Must | Should | Có ứng viên `ADR` | Chỉ cần `DEC` |
|
||
|---|---|---|---|---|---|
|
||
| Cấu trúc hệ thống (kiểu kiến trúc, ranh giới, tách đơn) | 3 (`ASR-001,003,014`) | 3/3 | — | 3/3 | 0 |
|
||
| Bảo mật & tuân thủ | 4 (`ASR-002,007,008,009`) | 3/4 | 1/4 *(MFA Admin Must, phần Seller Should)* | 3/4 | 1 (`ASR-009`, borderline) |
|
||
| Tích hợp & dữ liệu | 3 (`ASR-004,005,006`) | 3/3 | — | 3/3 | 0 |
|
||
| Hạ tầng & vận hành | 2 (`ASR-010,011`) | 2/2 | — | 2/2 | 0 |
|
||
| Ràng buộc nền tảng (đầu vào, không phải quyết định SA) | 1 (`ASR-012`) | 1/1 | — | 0/1 *(đã phản ánh trong `ADR-001`)* | — |
|
||
| Phụ thuộc bên ngoài | 1 (`ASR-013`) | 1/1 | — | 1/1 | 0 |
|
||
| Frontend / i18n | 1 (`ASR-015`) | — | 1/1 | 0/1 *(borderline)* | 1 |
|
||
| **Tổng** | **15** | **13/15** | **2/15** | **12/15** | **2/15** (+1 N/A) |
|
||
|
||
**Đọc bảng:** 15 nằm trong khoảng "8–15 mục" khuyến nghị của `SKILL.md` §2 — không phải danh
|
||
sách 200 mục. Ba `ASR` không bắt buộc `ADR` (`ASR-009`, `ASR-012`, `ASR-015`) vẫn được giữ trong
|
||
sổ vì đều có `QAS` Must hoặc Should đứng sau (tiêu chí B1), chỉ khác ở việc quyết định cụ thể có
|
||
thể chốt bằng `DEC-nn`/`AGD` thay vì `ADR` bất biến.
|
||
|
||
## B1. Tiêu chí một yêu cầu là `ASR` *(tham chiếu — xem đầy đủ ở `templates/quality-scenarios.md` §B1)*
|
||
|
||
Có ≥ 1 điều: ép một **cấu trúc** · ép một **ràng buộc không đảo ngược** · ép một **đánh đổi** ·
|
||
có `QAS` mức **Must** đứng sau. Mỗi `ASR` dưới đây ghi rõ đang thoả điều nào.
|
||
|
||
## B2. Danh sách `ASR` — chi tiết
|
||
|
||
### ASR-001 — Kiểu kiến trúc tổng thể phải là Modular Monolith + managed AWS, Payment tách riêng (P2) `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Toàn sàn phải được tổ chức thành 2–3 nhóm triển khai ECS Fargate (modular monolith theo domain), **không** phải ~10 microservices độc lập database-per-service (P1); duy nhất Payment Service tách hoàn toàn khỏi phần còn lại. |
|
||
| **Nguồn** | `DEC-06` (chọn P2, chưa phải `ADR`) · `OPT_e-commerce_v1.0.md` §1, §3, §4 (điểm 4.05 vs 2.95) · `CON-05` (năng lực team, Conway) · `CON-01`/`CON-02` (chi phí/thời gian) |
|
||
| **Vì sao định hình kiến trúc** | **Chi phí đổi sau cao** (đảo từ monolith sang microservices hay ngược lại tốn tái cấu trúc network/DB/CI-CD, không phải một buổi chiều) **+ cắt ngang mọi component** (mọi module — Catalog, Cart&Order, Seller, Commission, Promo, Review, Notify, Shipping — đều nằm trong ranh giới triển khai này) |
|
||
| **Ép ra cấu trúc gì** | Ranh giới triển khai (deployment boundary): tối đa 2–3 đơn vị ECS Fargate cho phần monolith + 1 đơn vị Payment riêng biệt mạng/IAM; 1 RDS chính schema-per-module (xem `ASR-006`); SQS/EventBridge thay Kafka/MSK (xem `ASR-005`) |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-001`** (số đã "nợ" theo `DTM §11`/`ADL §8`) — *"Kiểu kiến trúc tổng thể GĐ2 — Modular Monolith P2, không phải Microservices P1"*. Radar ước lượng **~7** (chi phí đảo ngược cao=2 · bán kính toàn hệ thống=2 · chạm `QAS` Must gián tiếp qua `QAS-005/006/009`=1 · ràng buộc ≥1 năm=2 · chưa tranh cãi mới=0). **Dưới ngưỡng 8 cứng nhưng vẫn cần `POC-01`/`POC-02` trước khi `Accepted`** vì bản thân `ASM-07`/`ASM-08` (SQS đủ throughput, RDS đủ tải gộp) chưa xác minh — nếu một trong hai `POC` fail, quyết định này phải viết lại một phần (kiến trúc lai), không phải toàn bộ. |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-001` chưa viết (hoạt động `sad`/`adr` kế tiếp phải viết ngay khi bắt đầu, theo cảnh báo đã có ở `DTM`/`ADL`) |
|
||
|
||
---
|
||
|
||
### ASR-002 — Payment Service là biên cô lập PCI-DSS SAQ A, không lưu thông tin thẻ `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Payment Service phải là ranh giới mạng + IAM + dữ liệu (RDS riêng) hoàn toàn tách biệt khỏi phần monolith còn lại; hệ thống sàn không được lưu số thẻ/CVV ở bất kỳ đâu — mọi xử lý thẻ do VNPay/Momo thực hiện, sàn chỉ lưu `gateway_transaction_ref` + kết quả. |
|
||
| **Nguồn** | `DRV-03` (giảm phạm vi PCI-DSS) · `CON-06` (PCI-DSS SAQ A + NĐ13/2023, cứng) · `BR-CART-05` (BA, "Không lưu trữ thông tin thẻ thanh toán" — không thể đổi trong 1 năm) |
|
||
| **Vì sao định hình kiến trúc** | **Ràng buộc công nghệ/pháp lý không đảo ngược** (vi phạm PCI-DSS/hợp đồng với VNPay/Momo, không phải quyết định kỹ thuật có thể đổi ý sau) **+ cắt ngang** (mọi luồng chạm dữ liệu thanh toán trong toàn hệ thống phải đi qua đúng một biên này) |
|
||
| **Ép ra cấu trúc gì** | Payment Service = container riêng, network/IAM riêng, RDS riêng nhỏ (đã phản ánh sơ bộ ở `OPT §3` P2); mọi module khác chỉ nhận `gateway_transaction_ref`/`status`, không bao giờ nhận/lưu dữ liệu thẻ |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-002`** (dự kiến) — *"Payment Service là biên cô lập PCI-DSS SAQ A"*. Radar ước lượng **~7** (đảo ngược tốn — tách lại sau khi đã gộp nhầm sẽ phải audit lại toàn bộ luồng thẻ=2 · bán kính: mọi module chạm thanh toán=1 · chạm `QAS-011` Must (PII) gián tiếp=1 · ràng buộc pháp lý ≥1 năm, không thương lượng=2 · chưa tranh cãi=1). Không cần POC bắt buộc (không phải con số hiệu năng chưa đo — đây là ràng buộc pháp lý đã có sẵn), nhưng cần Security ký (theo `decision-radar.md §5`: bảo mật/quyền riêng tư do Security chốt). |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-002` chưa viết; input trực tiếp cho hoạt động `sec` (threat model) và `dat` (ownership dữ liệu Payment) kế tiếp |
|
||
|
||
---
|
||
|
||
### ASR-003 — Tách đơn hàng theo seller khi checkout (Order cha / OrderSeller con) `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Khi checkout, hệ thống phải nhóm `CartItem` theo `seller_id` và tạo một `OrderSeller` (đơn con) riêng cho mỗi nhóm; `Order` (đơn cha) là tập hợp các `OrderSeller`, mỗi `OrderSeller` có vòng đời trạng thái độc lập. |
|
||
| **Nguồn** | `BR-CART-01` (BA) · `DRV-01` (blocker MVP) · `DRV-02` (bỏ giỏ đa seller) · `DRV-06` (minh bạch dòng tiền 3 bên) |
|
||
| **Vì sao định hình kiến trúc** | **Chi phí đổi sau cao** (đổi mô hình dữ liệu Order/OrderSeller sau go-live cần migrate toàn bộ đơn hàng lịch sử + sửa mọi module đọc `Order`) **+ cắt ngang nhiều component** (Cart&Order, Commission&Payout, Shipping&Fulfillment, Review đều phụ thuộc cấu trúc cha-con này) |
|
||
| **Ép ra cấu trúc gì** | Mô hình dữ liệu 1 `Order` — N `OrderSeller` — N `OrderItem`; mỗi `OrderSeller` là đơn vị hạch toán/vận chuyển/đối soát độc lập; ranh giới sở hữu dữ liệu giữa Cart&Order (tạo `Order`/`OrderSeller`) và Commission&Payout/Shipping (tiêu thụ) |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-003`** (dự kiến) — *"Mô hình Order/OrderSeller — tách đơn theo seller"*. Radar ước lượng **~6** (đảo ngược cao=2 · bán kính nhiều module=2 · chạm `QAS` Must gián tiếp (không có `QAS` số riêng nhưng là nền cho toàn luồng checkout `QAS-002`)=1 · ràng buộc ≥1 năm (mô hình dữ liệu lõi)=1 · ít tranh cãi, đã là mô hình kinh doanh đã chốt=0). *Lưu ý: cơ chế tách chi tiết "luôn đúng N đơn cho N seller, không gộp" vẫn phụ thuộc `OQ-011` (BA) chưa đóng — `ADR-003` phải chờ hoặc ghi rõ giả định.* |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-003` chưa viết; phụ thuộc `OQ-011` (BA) trước khi có thể coi là "Đã kiểm chứng" |
|
||
|
||
---
|
||
|
||
### ASR-004 — Webhook xác nhận thanh toán phải idempotent + có job đối soát bù `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Cập nhật `Payment.status = success` chỉ được thực hiện khi webhook VNPay/Momo có chữ ký hợp lệ và xử lý **idempotent** (webhook gọi lại nhiều lần không tạo hiệu ứng phụ); đồng thời phải có job đối soát bù chạy định kỳ để phát hiện lệch trạng thái khi webhook trễ/mất. |
|
||
| **Nguồn** | `QAS-014` (đối soát ≤15 phút, đề xuất SA, `OQ-021`) · `DRV-08` (webhook chưa xác minh khả thi gần thời gian thực) · `BR-CART-06` (BA) · `ARISK-03` |
|
||
| **Vì sao định hình kiến trúc** | **Ép một đánh đổi** (không thể đảm bảo consistency mạnh cho trạng thái thanh toán vì phụ thuộc bên thứ ba — phải chấp nhận eventual consistency có giới hạn thời gian, đây là quyết định kiến trúc không phải chi tiết code) **+ cắt ngang** (chạm Payment Service, Cart&Order — cập nhật `OrderSeller.status`, và tầng quan sát được — job đối soát cần alerting riêng) |
|
||
| **Ép ra cấu trúc gì** | Idempotency key (theo `gateway_transaction_ref`) cho endpoint nhận webhook; job đối soát bù (reconciliation) chạy định kỳ, độc lập với luồng webhook chính; cần bảng log webhook đã nhận để so khớp |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-004`** (dự kiến) — *"Cơ chế idempotency & đối soát cho webhook thanh toán bên thứ ba"*. Radar ước lượng **~6** (đảo ngược trung bình-cao (đổi cơ chế đối soát sau khi có dữ liệu thật tốn công viết lại job + backfill)=1 · bán kính: Payment + Cart&Order + Observability=1 · chạm `QAS-014` Must trực tiếp=2 · ràng buộc trong khoảng GĐ2, có thể đổi khi có sandbox thật=1 · chưa tranh cãi=1). |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-004` chưa viết; phụ thuộc sandbox VNPay/Momo thật (`ARISK-03`, chưa có) để kiểm chứng |
|
||
|
||
---
|
||
|
||
### ASR-005 — Message backbone SQS FIFO (per-seller group) + EventBridge cho luồng đặt hàng, có giới hạn thông lượng theo group `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Luồng sự kiện `OrderPlaced`/`PaymentConfirmed` phải dùng SQS FIFO (message group theo `seller_id`, đảm bảo thứ tự xử lý trong cùng seller) + EventBridge fan-out cho các consumer chuỗi sau đặt hàng (hoa hồng, payout, notify, loyalty); phải có phương án cho seller có volume cao chạm trần throughput của một message group. |
|
||
| **Nguồn** | `QAS-005` (≥100 msg/s sustained, p99 ≤2s, 0 mất message) · `ARISK-01` · `DEC-06` (P2 chọn SQS/EventBridge thay Kafka/MSK) · `ASM-07` (chưa xác minh) |
|
||
| **Vì sao định hình kiến trúc** | **Ràng buộc công nghệ không đảo ngược trong ngắn hạn** (đổi từ SQS/EventBridge sang Kafka/MSK sau khi đã có producer/consumer thật là viết lại toàn bộ tầng tích hợp bất đồng bộ, không phải cấu hình) **+ cắt ngang** (mọi module tiêu thụ event `OrderPlaced` — Commission, Payout, Notification, Loyalty — đều phụ thuộc cơ chế này) |
|
||
| **Ép ra cấu trúc gì** | SQS FIFO queue với message group key = `seller_id`; EventBridge rule cho fan-out ≥5 consumer; cơ chế giám sát riêng cho seller có volume cao (theo dõi/cảnh báo riêng theo `QAS` A4 xung đột dòng 2); **KHÔNG** dùng Kafka/MSK trừ khi `POC-01` fail |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-005`** (dự kiến) — *"Message backbone cho luồng đặt hàng — SQS FIFO + EventBridge"*. Radar ước lượng **~8** (đảo ngược cao=2 · bán kính nhiều module=2 · chạm `QAS-005` Must trực tiếp=2 · ràng buộc ≥1 năm (chọn message broker là quyết định dài hạn)=1 · chưa tranh cãi mới=1). **≥8 ⇒ theo `decision-radar.md §2`, `ADR` này không được chuyển `Accepted` khi chưa có `POC`/bài đo — `POC-01` (`ARISK §6`) chính là bài đo bắt buộc, hiện CHƯA CHẠY.** |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-005` chưa viết; **chặn `Accepted` cho tới khi `POC-01` chạy xong** (đã ghi ở `OQ-012`, `ARISK §6`) |
|
||
|
||
---
|
||
|
||
### ASR-006 — Một cụm RDS PostgreSQL chính, schema-per-module, chịu tải ghi/đọc gộp (trừ Payment) `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Toàn bộ module ngoại trừ Payment phải dùng chung 1 cụm RDS PostgreSQL Multi-AZ, phân tách theo schema-per-module (ranh giới logic rõ ràng dù chung instance); cụm này phải chịu được tải ghi (checkout) + đọc (catalog) gộp ở tải đỉnh. |
|
||
| **Nguồn** | `QAS-006` (p95 write ≤300ms, p95 read ≤200ms, CPU <75%) · `ARISK-02` · `DEC-06` (P2) · `ASM-08` (chưa xác minh) |
|
||
| **Vì sao định hình kiến trúc** | **Chi phí đổi sau cao** (tách read replica/DB riêng cho từng module sau khi đã gộp là một dự án migration riêng, không phải config) **+ cắt ngang** (mọi module ngoài Payment — Catalog, Cart&Order, Seller, Commission, Promo, Review, Notify, Shipping — đều chia sẻ cùng một instance, một module quá tải ảnh hưởng tất cả) |
|
||
| **Ép ra cấu trúc gì** | 1 RDS instance chính (`db.r6g.xlarge` Multi-AZ theo `TCO`/`ARISK`, tham khảo — số thật thuộc hoạt động `inf`), schema riêng cho từng module, connection pool chia sẻ có giới hạn theo module để tránh một module chiếm hết pool |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-006`** (dự kiến) — *"Chiến lược dữ liệu — RDS gộp schema-per-module cho P2"*. Radar ước lượng **~8** (đảo ngược cao=2 · bán kính toàn bộ module ngoài Payment=2 · chạm `QAS-006` Must trực tiếp=2 · ràng buộc ≥1 năm=1 · chưa tranh cãi=1). **≥8 ⇒ bắt buộc `POC`/bài đo trước `Accepted` — `POC-02` (`ARISK §6`) là bài đo bắt buộc, hiện CHƯA CHẠY.** |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-006` chưa viết; **chặn `Accepted` cho tới khi `POC-02` chạy xong** |
|
||
|
||
---
|
||
|
||
### ASR-007 — Mọi thao tác Cart/Order phải qua kiểm tra quyền sở hữu (ownership check) `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Mọi request đọc/sửa/xoá `Cart`/`CartItem`/`Order` phải được đối chiếu quyền sở hữu: Guest theo `session_id` của chính phiên, Customer theo `customer_id` của chính họ — 0% truy cập chéo (IDOR) thành công. |
|
||
| **Nguồn** | `QAS-010` (100% request qua kiểm tra, 0 IDOR thành công) · `RBAC_CartCheckout_v1.0.md` §2 (ma trận: "Xem giỏ hàng/đơn hàng của người khác" = ❌ cho cả `ROLE-01` Guest và `ROLE-02` Customer) |
|
||
| **Vì sao định hình kiến trúc** | **Ép một đánh đổi** (kiểm tra ownership mỗi request cạnh tranh trực tiếp với ngân sách latency `QAS-003`/`QAS-004` — đã ghi nhận ở `QAS` A4 xung đột dòng 1, cần quyết định cache ownership hay query DB mỗi lần) **+ cắt ngang** (mọi endpoint `GET`/`PATCH`/`DELETE` của `/v1/cart*` đều cần cùng một cơ chế) |
|
||
| **Ép ra cấu trúc gì** | Chỗ ra quyết định authz (API gateway hay từng service) phải nhất quán cho toàn bộ nhóm "giao dịch"; cần cơ chế cache session/ownership (VD Redis) nếu chọn tối ưu latency thay vì query DB mỗi request |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-007`** (dự kiến) — *"Chỗ ra quyết định ownership/authz cho Cart & Order — gateway hay service, có cache không"*. Radar ước lượng **~6** (đảo ngược trung bình=1 · bán kính: toàn bộ endpoint Cart&Order=1 · chạm `QAS-010` Must trực tiếp + xung đột trực tiếp với `QAS-003/004`=2 · ràng buộc trong khoảng GĐ2=1 · đã có xung đột ghi nhận ở `QAS` A4, cần Tech Lead quyết=1). |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-007` chưa viết; input trực tiếp cho hoạt động `sec` (mô hình phân quyền) và `sad` (nơi đặt logic authz) |
|
||
|
||
---
|
||
|
||
### ASR-008 — Dữ liệu PII chia sẻ cho seller phải qua data-minimization + xác nhận residency NĐ13/2023 `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Khi tách đơn theo seller, chỉ những trường PII (địa chỉ, SĐT người nhận) thực sự cần thiết để giao hàng mới được chia sẻ cho seller tương ứng; toàn bộ dữ liệu này (và mọi PII khách hàng/seller khác) phải được xác nhận nơi lưu trữ (residency) đáp ứng NĐ13/2023 trước go-live. |
|
||
| **Nguồn** | `QAS-011` (100% trường PII đã rà soát, 0 trường dư thừa) · `CON-06` (NĐ13/2023, cứng) · `DRV-07` (chưa rà soát) · `ARISK-06` · `ASM-04` (`ap-southeast-1` chưa xác nhận đủ) |
|
||
| **Vì sao định hình kiến trúc** | **Ràng buộc pháp lý không đảo ngược** (vi phạm NĐ13/2023 là vi phạm pháp luật, không phải lựa chọn kỹ thuật) **+ cắt ngang** (mọi module có PII — Identity, Cart&Order khi tách đơn, Seller Management với KYC — đều chịu ràng buộc vùng lưu trữ và chính sách chia sẻ này) |
|
||
| **Ép ra cấu trúc gì** | Danh sách trường PII được phép truyền cho seller (whitelist, không phải blacklist); vùng lưu trữ dữ liệu (region AWS) phải được Legal/Security xác nhận; cơ chế che/ẩn field khi hiển thị cho seller (mức che — theo `RBAC` §4, chưa chốt) |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-008`** (dự kiến) — *"Vùng lưu trữ dữ liệu cá nhân & chính sách chia sẻ PII cho seller"*. Radar ước lượng **~7** (đảo ngược cao — đổi region sau go-live là migration dữ liệu thật=2 · bán kính nhiều module có PII=1 · chạm `QAS-011` Must trực tiếp=2 · ràng buộc pháp lý ≥1 năm, không thương lượng=2 · chưa tranh cãi (chờ người rà soát)=0). **Phủ quyết thuộc Security/Legal** (`decision-radar.md §5`), không phải SA — SA chỉ chuẩn bị danh sách trường để người đó rà soát (đã ghi ở `ARISK-06`). |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-008` chưa viết; **chặn hoàn toàn cho tới khi có đại diện Pháp chế/Bảo mật** (`OQ-007`, vẫn chưa có người sau cả GĐ1 lẫn hoạt động `qas`) |
|
||
|
||
---
|
||
|
||
### ASR-009 — Đăng nhập Admin bắt buộc MFA (Seller khuyến khích, không bắt buộc) `[Must cho Admin / Should cho Seller]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | 100% đăng nhập tài khoản Admin phải qua bước xác thực thứ hai (MFA); 0 lượt bypass được chấp nhận. Seller được khuyến khích bật MFA nhưng không bắt buộc ở MVP. |
|
||
| **Nguồn** | `QAS-012` (100% Admin qua MFA, Must; Seller Should) |
|
||
| **Vì sao định hình kiến trúc** | Chủ yếu **chạm `QAS` Must** (tiêu chí thứ tư của B1) — bán kính hẹp hơn các `ASR` khác (chỉ Identity/Admin module), chi phí đổi sau ở mức trung bình (thêm MFA sau go-live không tốn quá nhiều nếu thiết kế đúng ngay từ đầu, nhưng đổi phương thức MFA sau khi user đã đăng ký thì tốn UX) |
|
||
| **Ép ra cấu trúc gì** | Identity/Access module cần bước xác thực thứ hai (TOTP app / SMS OTP / khác — **chưa chốt phương thức cụ thể**, xem `OQ-024` mới) trong luồng đăng nhập Admin; cần lưu trạng thái MFA đã bật/thu hồi được |
|
||
| **Quyết định cần `ADR`** | **Không bắt buộc `ADR`** — radar ước lượng **~4** (đảo ngược trung bình=1 · bán kính hẹp, 1 module=0 · chạm `QAS-012` Must trực tiếp=2 · ràng buộc trong 1 release, có thể đổi nhà cung cấp MFA sau=1 · chưa tranh cãi=0). Theo `decision-radar.md §2` (3–4 điểm) ⇒ **`DEC-nn` là đủ** khi Tech Lead chốt phương thức cụ thể ở hoạt động `sec`. *Ngoại lệ: nếu chọn nhà cung cấp MFA bên thứ ba ràng buộc hợp đồng dài hạn, nâng lên `ADR` theo `decision-radar.md §4` "ngoại lệ tiền lệ".* |
|
||
| **Trạng thái** | Đã ghi nhận — quyết định cụ thể (phương thức MFA) để hoạt động `sec` chốt bằng `DEC-nn`, không nhất thiết `ADR` |
|
||
|
||
---
|
||
|
||
### ASR-010 — HA/DR cho nhóm dịch vụ giao dịch lõi: RPO ≤15 phút, RTO ≤1 giờ, bắt buộc diễn tập trước AG2 `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Payment, Cart & Order, Identity & Access phải có khả năng khôi phục sau sự cố với RPO ≤15 phút và RTO ≤1 giờ; **con số này phải được chứng minh bằng diễn tập (failover drill) thật trước khi AG2 được ký** — không chấp nhận RTO/RPO chỉ tồn tại trên giấy. |
|
||
| **Nguồn** | `QAS-008` · `OQ-022` (đã chốt điều kiện qua `DEC-12`: diễn tập là điều kiện tiên quyết AG2) |
|
||
| **Vì sao định hình kiến trúc** | **Chi phí đổi sau cao** (thiết kế lại chiến lược backup/failover sau khi đã go-live là một dự án riêng, có rủi ro downtime khi thực hiện) **+ cắt ngang** (ảnh hưởng chiến lược backup, network, và runbook vận hành của cả 3 service lõi) **+ chạm `QAS` Must trực tiếp** |
|
||
| **Ép ra cấu trúc gì** | Chiến lược backup point-in-time (RPO ≤15 phút ⇒ tần suất backup/WAL archiving tương ứng); kiến trúc Multi-AZ + quy trình failover có runbook; **lịch diễn tập cụ thể — vẫn chưa có, `OQ-022` giữ mở chờ Ops/SRE** |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-009`** (dự kiến) — *"Chiến lược HA/DR cho nhóm dịch vụ giao dịch lõi"*. Radar ước lượng **~9** (đảo ngược cao=2 · bán kính 3 service lõi + toàn bộ vận hành=2 · chạm `QAS-008` Must trực tiếp=2 · ràng buộc hạ tầng ≥1 năm=2 · chưa tranh cãi nhưng con số kế thừa từ `SAD.md` chưa được SA thiết kế lại=1). **≥8 ⇒ bắt buộc bài đo (diễn tập DR) trước `Accepted`** — đây chính là điều kiện đã chốt ở `DEC-12`/`OQ-022`, nhất quán với `decision-radar.md §6`. |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-009` chưa viết; input bắt buộc cho hoạt động `inf` kế tiếp; **chặn `Accepted` cho tới khi diễn tập DR chạy** (đã là điều kiện ký AG2, không chỉ điều kiện `Accepted` của riêng ADR này) |
|
||
|
||
---
|
||
|
||
### ASR-011 — Observability phải cảnh báo lỗi 5xx tăng đột biến trong ≤1 phút cho nhóm giao dịch lõi `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Sự cố lỗi 5xx tăng đột biến ở Cart & Order, Payment, Identity phải được cảnh báo tự động trong ≤1 phút; on-call phải acknowledge trong ≤15 phút. |
|
||
| **Nguồn** | `QAS-013` |
|
||
| **Vì sao định hình kiến trúc** | **Cắt ngang** (mọi service lõi cần cùng chuẩn logging/metric để pipeline cảnh báo hoạt động nhất quán) **+ chạm `QAS` Must trực tiếp**; chi phí đổi sau ở mức trung bình (đổi công cụ observability sau này khả thi nhưng tốn công di chuyển dashboard/alert đã cấu hình) |
|
||
| **Ép ra cấu trúc gì** | Chuẩn log/metric/trace thống nhất cho 3 service lõi; pipeline cảnh báo (CloudWatch Synthetics/Alarms hoặc tương đương) kết nối kênh on-call (PagerDuty/OpsGenie); ngưỡng cấu hình cảnh báo phải khớp ≤1 phút |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-010`** (dự kiến) — *"Kiến trúc observability & alerting cho dịch vụ giao dịch lõi"*. Radar ước lượng **~6** (đảo ngược trung bình=1 · bán kính 3 service lõi=1 · chạm `QAS-013` Must trực tiếp=2 · ràng buộc trong khoảng GĐ2/GĐ3, có thể đổi công cụ=1 · chưa tranh cãi=1). |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-010` chưa viết; input cho hoạt động `inf` (observability) kế tiếp |
|
||
|
||
---
|
||
|
||
### ASR-012 — Toàn bộ hạ tầng phải chạy trên AWS `[Must — ràng buộc đầu vào]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Không dùng cloud khác hoặc on-premise cho bất kỳ thành phần nào của hệ thống. |
|
||
| **Nguồn** | `CON-03` (cứng, đã xác nhận vòng 3 Q&A brief — không phải sở thích SA) |
|
||
| **Vì sao định hình kiến trúc** | **Ràng buộc công nghệ không đảo ngược** — nhưng đây là **ràng buộc đầu vào** (khách hàng đã chốt), không phải một quyết định do SA cân nhắc và chọn giữa nhiều phương án |
|
||
| **Ép ra cấu trúc gì** | Loại toàn bộ phương án dùng cloud khác/on-prem ngay từ `OPT` (đã thực hiện ở GĐ1); mọi dịch vụ managed trong `ASR-001…011` (ECS Fargate, RDS, SQS/EventBridge, CloudWatch) đều phải là dịch vụ AWS |
|
||
| **Quyết định cần `ADR`** | **Không cần `ADR` riêng** — đây là input, không phải quyết định SA; đã được phản ánh làm điều kiện tiên quyết trong `ADR-001` (kiểu kiến trúc tổng thể). Ghi lại ở đây để đầy đủ theo yêu cầu bao phủ, không phải vì cần quyết định thêm. |
|
||
| **Trạng thái** | Đã ghi nhận — không cần thiết kế thêm, chỉ cần tuân thủ xuyên suốt `SAD`/`INF` |
|
||
|
||
---
|
||
|
||
### ASR-013 — Tích hợp bắt buộc VNPay/Momo (thanh toán) + GHN/GHTK (vận chuyển, có fallback chéo) `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Hệ thống phải tích hợp đúng 4 đối tác đã chốt (không phải "chờ chọn tuỳ ý"); GHN/GHTK phải có cơ chế fallback chéo khi một bên lỗi. Mỗi đối tác cần chính sách timeout/retry/idempotent nhất quán. |
|
||
| **Nguồn** | `CON-04` (cứng về danh tính đối tác) · `ARISK-03` (VNPay/Momo) · `ARISK-04` (GHN/GHTK fallback chưa kiểm chứng) |
|
||
| **Vì sao định hình kiến trúc** | **Ràng buộc hợp đồng/công nghệ không đảo ngược** (đổi đối tác thanh toán/vận chuyển là quyết định kinh doanh + hợp đồng, không phải cấu hình) **+ cắt ngang** (Payment Service phụ thuộc VNPay/Momo; Shipping & Fulfillment phụ thuộc GHN/GHTK; cùng một chính sách resilience nên áp dụng nhất quán) |
|
||
| **Ép ra cấu trúc gì** | Adapter/anti-corruption layer riêng cho từng đối tác; chính sách timeout/retry/idempotent chung (kế thừa đề xuất từ `SAD.md §3.4`: VNPay/Momo 10s, GHN/GHTK 8s — **chưa kiểm chứng sandbox thật**); cơ chế fallback GHN↔GHTK cần test riêng |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-011`** (dự kiến) — *"Chính sách resilience khi đối tác thanh toán/vận chuyển bên ngoài lỗi (timeout/retry/fallback chung)"*. Radar ước lượng **~6** (đảo ngược trung bình=1 · bán kính Payment + Shipping=1 · chạm gián tiếp `QAS-002`/`QAS-014`=1 · ràng buộc hợp đồng đối tác, khó đổi giữa chừng=2 · chưa tranh cãi=1). Đây cũng là input trực tiếp cho hoạt động `fail` (đường lỗi) — không trùng lặp, `ADR` chốt chính sách chung, `FAIL` áp dụng chi tiết từng phụ thuộc. |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-011` chưa viết; phụ thuộc sandbox thật của cả 4 đối tác (chưa có, `CON-04`/`ARISK-03/04`) để kiểm chứng đầy đủ |
|
||
|
||
---
|
||
|
||
### ASR-014 — Ranh giới nhóm triển khai (deployment grouping) phải khớp năng lực đội thi công thật (Conway) `[Must]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Việc gom module vào 2–3 nhóm ECS Fargate (thay vì ~10 service độc lập như P1) phải phản ánh đúng số người/kỹ năng đội thi công thật, không chỉ theo giả định "team MVP chuẩn" (`DEC-02`, 🔴 chưa xác nhận) hay đội hình đề xuất của hồ sơ thầu (9 vị trí TB, đỉnh 10). |
|
||
| **Nguồn** | `DEC-02` (giả định tạm, chưa xác nhận) · `CON-05` (con người, chưa xác nhận số thật) · `OQ-002`/`OQ-010` (còn mở) · `OPT §1`/§4 (tiêu chí 5 "Năng lực team & vận hành") |
|
||
| **Vì sao định hình kiến trúc** | **Chi phí đổi sau cao** (vẽ lại ranh giới triển khai sau khi team đã quen vận hành theo ranh giới cũ tốn công tái tổ chức CI/CD + on-call) **+ cắt ngang** (ảnh hưởng toàn bộ cách tổ chức code, quyền truy cập, và trách nhiệm vận hành của mọi module) |
|
||
| **Ép ra cấu trúc gì** | Nhóm "giao dịch" (Cart/Order/Catalog, scale nhanh) tách khỏi nhóm "hỗ trợ" (Seller/Promo/Review/Notify/Shipping) — theo đề xuất `OPT §3` P2; **ranh giới cụ thể này chưa được xác nhận lại ở mức chi tiết ASR khi có số team thật** (xem `ASM-19` mới) |
|
||
| **Quyết định cần `ADR`** | **Có — `ADR-012`** (dự kiến) — *"Ranh giới nhóm triển khai (deployment boundary) theo domain và năng lực đội"* — khác `ADR-001` (kiểu kiến trúc tổng thể: monolith hay không) ở chỗ đây là quyết định **cụ thể module nào nằm nhóm nào**. Radar ước lượng **~7** (đảo ngược cao=2 · bán kính toàn bộ tổ chức code/vận hành=2 · chạm gián tiếp mọi `QAS` (mở rộng, quan sát được)=1 · ràng buộc ≥1 năm=1 · chưa tranh cãi, nhưng phụ thuộc số liệu chưa xác nhận=1). |
|
||
| **Trạng thái** | Đã ghi nhận — `ADR-012` chưa viết; **phụ thuộc `OQ-010` (Tech Lead xác nhận đội thật)** trước khi có thể coi ranh giới này là vững |
|
||
|
||
---
|
||
|
||
### ASR-015 — Chiến lược đa ngôn ngữ (5 thứ tiếng) phải tách chuỗi hiển thị khỏi code ngay từ đầu `[Should]`
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Phát biểu** | Nội dung hiển thị (VI mặc định/EN/ZH/KO/JA) phải được quản lý tách biệt khỏi logic code (resource file/bảng dịch theo locale), để bổ sung ngôn ngữ mới không cần sửa code nghiệp vụ. |
|
||
| **Nguồn** | `DRV-09` (Should, không chặn MVP) |
|
||
| **Vì sao định hình kiến trúc** | Chủ yếu **ràng buộc kiến trúc bảo trì dài hạn** — nếu không tách ngay từ đầu, retrofit i18n sau khi đã có hàng trăm màn hình là công việc tốn kém hơn nhiều lần so với làm đúng từ đầu; bán kính rộng (toàn bộ tầng hiển thị FE) nhưng không chạm `QAS` Must nào (chỉ Should) |
|
||
| **Ép ra cấu trúc gì** | Framework i18n ở tầng FE (tách string ra resource file theo locale); chiến lược lưu trữ nội dung động (VD tên sản phẩm do seller nhập — có cần dịch không, ai dịch — **chưa chốt**, xem `OQ-025` mới) |
|
||
| **Quyết định cần `ADR`** | **Borderline, không bắt buộc** — radar ước lượng **~5** (đảo ngược trung bình=1 · bán kính rộng nhưng chỉ FE=1 · không chạm `QAS` Must (chỉ Should)=0 · ràng buộc trong khoảng dự án=1 · chưa tranh cãi=0, +2 vì đây là danh mục "Chiến lược đa ngôn ngữ" được `decision-radar.md §3` liệt kê rõ trong nhóm Frontend). Khuyến nghị: nếu Tech Lead không thấy tranh cãi, ghi `DEC-nn` + đưa framework cụ thể vào `AGD` (GĐ3) thay vì mở một `ADR` riêng; nâng lên `ADR-013` nếu phát sinh tranh luận về công nghệ i18n cụ thể. |
|
||
| **Trạng thái** | Đã ghi nhận — quyết định công cụ cụ thể để hoạt động `sad`/GĐ3 (`AGD`) chốt |
|
||
|
||
---
|
||
|
||
## B3. Ma trận `ASR` × `CMP`
|
||
|
||
*Chưa điền — `SAD` (hoạt động 3, kế tiếp) chưa tồn tại nên chưa có `CMP-nn` để đối chiếu. Khung
|
||
để hoạt động `sad` điền khi có bảng component:*
|
||
|
||
| | `CMP-nn` (điền ở hoạt động `sad`) |
|
||
|---|---|
|
||
| `ASR-001…015` | *(chờ `SAD`)* |
|
||
|
||
🔴 Nhắc cho hoạt động `sad` kế tiếp: mỗi `CMP` phải phục vụ được ít nhất một `ASR` ở trên (cột
|
||
"cái nó KHÔNG làm" của `SAD` giúp kiểm tra ngược); `ASR-012` (AWS) không sinh ra `CMP` riêng, chỉ
|
||
là ràng buộc nền cho mọi `CMP`.
|
||
|
||
---
|
||
|
||
## C. Đối chiếu với `BR`/`ROLE` của bộ BA
|
||
|
||
| `BR`/`ROLE` (BA) | Nội dung gốc | `ASR` tương ứng | Khớp? | Hành động |
|
||
|---|---|---|---|---|
|
||
| `BR-CART-01` | Tách đơn theo seller | `ASR-003` | ✅ | Không lệch — `BR-CART-01` chính là nguồn của `ASR-003`; cơ chế chi tiết vẫn chờ `OQ-011` (BA) |
|
||
| `BR-CART-02` | Giữ tồn kho khi checkout (chống oversell) | *(không có `ASR` riêng)* | ➖ N/A | Đây là quy tắc nghiệp vụ thuần (điều kiện hành động), không ép cấu trúc kiến trúc riêng — thuộc `SAD`/logic thi công, không phải `ASR` |
|
||
| `BR-CART-03` | Giới hạn giá trị đơn COD (chưa chốt) | *(không có `ASR`)* | ➖ N/A | Đây là quyết định nghiệp vụ/rủi ro tài chính (PO chọn phương án), không ép cấu trúc kiến trúc — nếu PO chọn phương án (b) "xác thực bổ sung" (OTP), có thể phát sinh `ASR` mới (tích hợp OTP) — chưa xảy ra |
|
||
| `BR-CART-04` | Điều kiện chọn phương thức thanh toán | Gián tiếp qua `ASR-002`/`ASR-013` | 🟡 Một phần | Không có `ASR` riêng vì bản thân việc "cho chọn 1 trong 3 phương thức" không ép cấu trúc — cấu trúc bị ép là do *mỗi* phương thức cần tích hợp riêng (`ASR-002` Payment, `ASR-013` đối tác ngoài) |
|
||
| `BR-CART-05` | Không lưu thông tin thẻ | `ASR-002` | ✅ | Khớp hoàn toàn |
|
||
| `BR-CART-06` | Xác thực webhook thanh toán | `ASR-004` | ✅ | Khớp hoàn toàn |
|
||
| `BR-CART-07` | Điều kiện tối thiểu Guest checkout | *(không có `ASR`)* | ➖ N/A | Danh sách field bắt buộc là chi tiết UI/validation, không ép cấu trúc kiến trúc |
|
||
| `ROLE-01` Guest / `ROLE-02` Customer (`RBAC` §1, §2) | 2 vai trò, phạm vi dữ liệu theo `session_id`/`customer_id` | `ASR-007` | ✅ | Khớp — `ASR-007` chính là hoá kỹ thuật của ranh giới "không xem được giỏ/đơn người khác" trong ma trận `RBAC` §2 |
|
||
| `RBAC` §4 (PII địa chỉ/SĐT chia sẻ cho seller) | Mức che khi hiển thị cho seller — chưa chốt | `ASR-008` | 🟡 Một phần | `ASR-008` bao phủ phần "vùng lưu trữ + data minimization"; phần "mức che hiển thị cụ thể" vẫn chờ Pháp chế/Bảo mật — ghi nhận là chưa tách rời được cho tới khi có người đó |
|
||
| `RBAC` §8 `OQ-012` (RISK-01 phương án OTP cho Guest giá trị cao) | Guest cần giới hạn/OTP cho đơn giá trị cao? | *(chưa có `ASR` — phụ thuộc `BR-CART-03`)* | ➖ Chờ PO | Nếu PO chọn phương án OTP ở `BR-CART-03`, sẽ phát sinh `ASR` mới (tích hợp OTP) ở lần cập nhật `ASR` tiếp theo |
|
||
|
||
*`BR-nnn` ép ràng buộc kiến trúc ⇒ `ADR` (theo `artifact-map.md §7`) — bảng trên xác nhận 4/7
|
||
`BR-CART` có `ASR` tương ứng trực tiếp; 3 còn lại (`BR-CART-02/03/07`) là quy tắc nghiệp vụ thuần
|
||
không ép cấu trúc, đúng theo tiêu chí B1 (không phải mọi `BR` đều thành `ASR`).*
|
||
|
||
---
|
||
|
||
## D. Giả định & Ngoài phạm vi
|
||
|
||
**Giả định** *(tiếp số toàn dự án — `ASM-01…18` đã dùng ở `CTX`/`OPT`/`TCO`/`QAS`, bắt đầu `ASM-19`)*:
|
||
|
||
| ID | Giả định | Cách xác minh | Nếu sai thì `ASR`/`ADR` nào đổi |
|
||
|---|---|---|---|
|
||
| `ASM-19` | Ranh giới "nhóm giao dịch" (Cart/Order/Catalog) vs "nhóm hỗ trợ" (Seller/Promo/Review/Notify/Shipping) theo `OPT §3` P2 vẫn là ranh giới đúng ở mức chi tiết `ASR-014`/`ADR-012` | Tech Lead xác nhận lại tại hoạt động `sad`, sau khi có số đội thi công thật (`OQ-010`) | `ASR-014`/`ADR-012` (dự kiến) — nếu team thật nhỏ hơn/khác cơ cấu, phải vẽ lại nhóm (VD gộp thêm module vào 1 nhóm duy nhất) |
|
||
| `ASM-20` | MFA cho Admin dùng TOTP app (không phụ thuộc thêm nhà cung cấp SMS gateway) làm mặc định đề xuất cho `ASR-009` | Security xác nhận phương thức tại hoạt động `sec` (`OQ-024` mới) | `ASR-009` — nếu cần SMS OTP, phát sinh phụ thuộc nhà cung cấp SMS mới (chi phí + `ASR` phụ thuộc bên ngoài mới) |
|
||
| `ASM-21` | Nội dung do seller tự nhập (tên sản phẩm, mô tả) **không** cần dịch tự động sang 5 ngôn ngữ ở MVP — chỉ UI hệ thống (nhãn, thông báo) cần i18n theo `ASR-015` | PO xác nhận phạm vi i18n tại hoạt động `sad`/GĐ3 (`OQ-025` mới) | `ASR-015` — nếu seller content cũng cần dịch, cần thêm chiến lược dịch thuật (thủ công/máy) và ảnh hưởng `DAT` (lưu bản dịch) |
|
||
|
||
*`ASM-01…18` của `CTX`/`OPT`/`TCO`/`QAS` vẫn áp dụng nguyên trạng — không lặp lại nội dung, chỉ
|
||
tham chiếu (đặc biệt `ASM-04`→`ASR-008`, `ASM-07`→`ASR-005`, `ASM-08`→`ASR-006`).*
|
||
|
||
**Ngoài phạm vi:**
|
||
|
||
- `SAD`/`ADR`/`ICD`/`DAT`/`SEC`/`INF`/`FAIL` — chưa thực hiện ở lượt chạy này (chỉ hoạt động
|
||
`asr`). Mọi "`ADR` ứng viên" ở §B2 là **đề xuất số thứ tự**, chưa phải file `ADR` thật — hoạt
|
||
động `adr` kế tiếp xác nhận lại số thật theo thứ tự viết, không nhất thiết khớp số đề xuất ở đây.
|
||
- Ma trận `ASR` × `CMP` (§B3) — để trống, chờ `SAD`.
|
||
- `BR-CART-02/03/07` không có `ASR` tương ứng (xem §C) — đây là quyết định nghiệp vụ thuần, đúng
|
||
theo tiêu chí B1, không phải bỏ sót.
|
||
- `ASR` mới có thể phát sinh nếu PO chọn phương án OTP cho `BR-CART-03` (xem §C, dòng cuối) —
|
||
chưa xảy ra ở lượt này.
|
||
|
||
## E. Open Questions
|
||
|
||
*Tiếp số sổ SA (`00-index/OQ_e-commerce.md` đang ở `OQ-023`) — bắt đầu `OQ-024`.*
|
||
|
||
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | Hệ quả nếu trả lời ngược |
|
||
|---|---|---|---|---|---|
|
||
| `OQ-024` | Phương thức MFA cho Admin là gì — TOTP app (Google Authenticator/Authy), SMS OTP, hay khoá bảo mật cứng? | Tech Lead + Security | 2026-09-14 | `ASR-009`; thiết kế `SEC` (mô hình xác thực) | Nếu chọn SMS OTP: phát sinh phụ thuộc nhà cung cấp SMS gateway mới (chi phí + `ARISK` phụ thuộc ngoài mới, tương tự `ARISK-10`); nếu chọn TOTP app: không phát sinh chi phí vận hành thêm nhưng cần hướng dẫn user cài app |
|
||
| `OQ-025` | Nội dung do seller tự nhập (tên/mô tả sản phẩm) có cần dịch sang 5 ngôn ngữ ở MVP không, hay chỉ UI hệ thống cần i18n? Nếu cần dịch, ai cung cấp bản dịch (dịch máy tự động hay seller tự nhập đa ngôn ngữ)? | PO + Tech Lead | 2026-09-14 | `ASR-015`; `DAT` (có cần lưu bản dịch theo locale không) | Nếu cần dịch nội dung seller: `DAT` phải thêm mô hình lưu trữ đa ngôn ngữ cho `Product`/`ProductVariant` (ngoài phạm vi module Giỏ hàng & Checkout hiện tại), tăng effort đáng kể so với chỉ dịch UI tĩnh |
|
||
|
||
**Nhắc:** cộng với các `OQ` còn mở ảnh hưởng trực tiếp `ASR` ở tài liệu này — `OQ-002`/`OQ-010`
|
||
(team thật, chặn `ASR-001`/`ASR-014`), `OQ-007` (đại diện Pháp chế, chặn `ASR-008`), `OQ-011` (BA,
|
||
cơ chế tách đơn, chặn `ASR-003`), `OQ-012` (thời điểm `POC-01`, chặn `ASR-001`/`ASR-005`),
|
||
`OQ-018…023` (số `QAS` nguồn của nhiều `ASR`) — xem sổ đầy đủ `00-index/OQ_e-commerce.md`.
|
||
|
||
---
|
||
|
||
## Tự chấm
|
||
|
||
### ① Bảng tự chấm Gate AG2 *(`workflow.md §2` — chỉ dòng liên quan tới `ASR`, tự chấm sớm)*
|
||
|
||
| # | Tiêu chí | ☐/✅ | Ghi chú |
|
||
|---|---|---|---|
|
||
| 1 | `ASR` liệt kê yêu cầu thực sự định hình kiến trúc, mỗi cái truy về `DRV` hoặc `QAS` | ✅ | 15 `ASR`, mỗi cái có cột "Nguồn" trỏ về `DRV`/`CON`/`QAS`/`BR`/`ROLE` cụ thể, không có `ASR` "mồ côi" nguồn |
|
||
| — | `QAS` — mọi NFR đã lượng hoá | ✅ *(đã đạt ở hoạt động `qas` trước)* | Xem `QAS_e-commerce_v1.0.md`, không lặp lại ở đây |
|
||
| — | `SAD` có sơ đồ C4 | ☐ | **Chưa tới** — hoạt động 3, kế tiếp |
|
||
| 2 | `ADR-nnn` tồn tại cho mọi quyết định đạt ngưỡng radar | ☐ | **Chưa viết `ADR` nào** — đúng theo yêu cầu điều phối "không viết ADR ở lượt này"; §B2 đã liệt kê đủ 12/15 ứng viên `ADR` (radar 6–9) để hoạt động `adr` kế tiếp không phải dò lại từ đầu |
|
||
| — | `ICD`/`DAT`/`SEC`/`INF`/`FAIL` | ☐ | Chưa tới — hoạt động 4–8 |
|
||
| — | `sa-conformance` báo coverage `ASR → ADR/CMP` ≥ 100% | ☐ | **0/15** — kỳ vọng đúng lúc này (đã ghi nhận là "🟠 Nợ" trong `DTM`/`ADL` từ trước khi file này tồn tại), sẽ chặn AG2 thật nếu vẫn 0/15 khi hoạt động `adr`/`sad` đã chạy xong |
|
||
|
||
**Kết luận tự chấm (riêng phần `ASR`):** Hoạt động `asr` hoàn tất đúng phạm vi được giao — 15
|
||
`ASR` có nguồn, có "vì sao định hình kiến trúc", có `ADR` ứng viên (hoặc lý do không cần). AG2
|
||
**còn xa** vì 7/9 hoạt động khác của GĐ2 chưa chạy — đây là tiến độ kỳ vọng, không phải lỗi.
|
||
|
||
### ② Checklist D1–D12 *(`design-rules.md`)*
|
||
|
||
| # | Mục | ☐/✅ | Ghi chú |
|
||
|---|---|---|---|
|
||
| D1 | Một ADR một quyết định | N/A | Tài liệu này không viết `ADR` — chỉ liệt kê ứng viên; mỗi ứng viên đã được tách theo đúng nguyên tắc một quyết định (VD `ADR-001` kiểu kiến trúc tổng thể tách khỏi `ADR-012` ranh giới nhóm triển khai cụ thể, dù liên quan) |
|
||
| D2 | Không NFR định tính; đủ 4 câu | N/A | `ASR` không phải `QAS` — không áp dụng trực tiếp; mọi `ASR` tham chiếu đúng `QAS` đã lượng hoá ở hoạt động trước, không tự đặt số mới |
|
||
| D3 | Nêu phương án bị loại + lý do gắn `CON`/`QAS` | ✅ *(kế thừa)* | `ASR-001` tham chiếu `OPT §5` (P1/P3/P4 đã loại) làm nền; không lặp lại nội dung, chỉ dẫn |
|
||
| D4 | Sơ đồ khai báo mức + legend | N/A | Không có sơ đồ mới trong tài liệu này |
|
||
| D5 | Interface có chủ/contract | N/A | Chưa tới `ICD` |
|
||
| D6 | Phụ thuộc ngoài process có timeout/retry | 🟡 Một phần | `ASR-004`/`ASR-013` đã nêu yêu cầu (idempotent, timeout/retry) nhưng chi tiết đầy đủ 4 câu hỏi D6 thuộc hoạt động `fail` kế tiếp |
|
||
| D7 | Một chủ sở hữu dữ liệu | 🟡 Một phần | `ASR-006` xác nhận 1 RDS chính là chủ cho các module ngoài Payment, `ASR-002` xác nhận Payment có DB riêng — chi tiết từng thực thể để `DAT` |
|
||
| D8 | Ràng buộc có FIT hoặc nhãn khuyến nghị | N/A | Chưa tới `AGD`/`FIT` (GĐ3) |
|
||
| D9 | Con số hạ tầng quy ra tiền + nguồn | N/A | `ASR` không thêm con số hạ tầng mới — kế thừa `TCO`/`ARISK` |
|
||
| D10 | Không quyết định thay người có thẩm quyền | ✅ | `ASR-008` ghi rõ phủ quyết thuộc Security/Legal; `ASR-002` ghi Security cần ký; mọi chỗ chưa rõ đều có `OQ` kèm hệ quả phương án ngược (§E, và trong từng khối ASR) |
|
||
| D11 | Có mục "Ngoài phạm vi" + `ASM-nn` | ✅ | §D đầy đủ — `ASM-19…21` mới, có cách xác minh/hệ quả; mục "Ngoài phạm vi" liệt kê rõ những gì chưa làm |
|
||
| D12 | Câu quy định thẩm quyền sơ đồ vs văn bản | ✅ | Có ngay sau Change Log |
|
||
|
||
### ③ Bảng đối chiếu với bộ BA
|
||
|
||
Xem Phần C ở trên (`BR`/`ROLE` × `ASR`) — 4/7 `BR-CART` có `ASR` tương ứng trực tiếp; 3 còn lại
|
||
xác nhận đúng là không ép cấu trúc (không phải bỏ sót). Không có hành động "BA cập nhật SRS" nào
|
||
cần thiết ở lượt này vì không phát hiện lệch nội dung, chỉ có 1 dòng chờ quyết định PO
|
||
(`BR-CART-03`) có thể sinh `ASR` mới sau.
|
||
|
||
### ④ Danh sách `OQ` mở kèm người phải trả lời, chặn gì
|
||
|
||
Xem §E (mới: `OQ-024`, `OQ-025`) cộng các `OQ` còn mở từ `CTX`/`OPT`/`ARISK`/`QAS`
|
||
(`OQ-002/004/005/006/007/008/010/012/013…023`) — sổ đầy đủ tại `00-index/OQ_e-commerce.md`. Ba
|
||
câu quan trọng nhất cho tiến độ `ASR`→`ADR`/`SAD` kế tiếp: **`OQ-010`** (team thật — chặn
|
||
`ASR-001`/`ASR-014`), **`OQ-012`** (thời điểm `POC-01` — chặn `ASR-001`/`ASR-005`), **`OQ-007`**
|
||
(đại diện Pháp chế — chặn `ASR-008`).
|
||
|
||
**Nhắc:** AG2 cần **Tech Lead + Security + Ops/SRE ký** — còn xa vì `SAD`/`ADR`/`ICD`/`DAT`/`SEC`/
|
||
`INF`/`FAIL` chưa chạy. Hoạt động kế tiếp bắt buộc là **`sad`** (hoạt động 3, theo đúng thứ tự
|
||
1→2→3 của `SKILL.md`), dùng chính 15 `ASR` ở tài liệu này làm đầu vào để phân rã component và vẽ
|
||
C4; `ADR-001` (kiểu kiến trúc tổng thể) nên được viết ngay khi `sad`/`adr` bắt đầu, theo đúng cảnh
|
||
báo đã có từ `DTM §11`/`ADL §8`.
|