Files
sys-analysis-design/sa-output/e-commerce/02-architecture/adr/ADR-011_chinh-sach-resilience-doi-tac-ngoai.md
Canhchimlac 343ad8bbbc save
2026-09-15 16:02:30 +07:00

160 lines
9.7 KiB
Markdown

# ADR-011 — Chính sách resilience chung khi đối tác thanh toán/vận chuyển bên ngoài lỗi (timeout/retry/fallback)
*Tên file: `adr/ADR-011_chinh-sach-resilience-doi-tac-ngoai.md`*
| | |
|---|---|
| **Status** | `Proposed` |
| **Date** | 2026-09-15 |
| **Người quyết** | SA + Tech Lead (tích hợp — `decision-radar.md §5`) |
| **Người đề xuất** | SA (qua skill `sa-2-architecture`, hoạt động `adr`) |
| **Điểm radar** | **~6/10** |
| **Supersedes** | — |
| **Superseded by** | — |
| **Liên quan** | `ASR-013` · `CON-04` · `ARISK-03` · `ARISK-04` · `CMP-10`, `CMP-11` |
> ⚠️ **ADR bất biến sau khi `Accepted`.** Muốn đổi quyết định thì viết ADR mới có
> `Supersedes: ADR-011` và đổi trạng thái bản cũ thành `Superseded by`.
---
## 1. Bối cảnh
Hệ thống phải tích hợp đúng 4 đối tác đã chốt: VNPay, Momo (thanh toán), GHN, GHTK (vận chuyển,
có fallback chéo) — `CON-04`. Không đối tác nào có sandbox/hợp đồng thật tại thời điểm này
(`CTX §4.2`). `ASR-013` yêu cầu một chính sách resilience **chung** cho cả 4 đối tác (timeout,
retry, idempotent) thay vì mỗi đội tự chọn một kiểu khác nhau — đây là quyết định "thiết lập tiền
lệ" theo `decision-radar.md §4` (ngoại lệ để nhỏ thành ADR): áp dụng cho mọi tích hợp đối tác
ngoài tương lai, không chỉ 4 đối tác hiện tại.
**Ràng buộc đang chi phối:**
| Nguồn | Nội dung |
|---|---|
| `ASR-013` | Chính sách timeout/retry/idempotent nhất quán cho VNPay/Momo/GHN/GHTK; GHN/GHTK cần fallback chéo |
| `CON-04` | 4 đối tác đã chốt danh tính, chưa có sandbox/hợp đồng thật |
| `ARISK-03` | VNPay/Momo — webhook chưa xác minh khả thi gần thời gian thực |
| `ARISK-04` | GHN/GHTK — cơ chế fallback chéo chưa kiểm chứng hoạt động đúng giữa 2 API khác nhau |
**Cái đã biết chắc / cái còn là giả định:**
| Điều | 🟢 Đã kiểm chứng / 🔴 Giả định | Bằng chứng |
|---|---|---|
| Danh tính 4 đối tác đã chốt (không phải chờ chọn) | 🟢 Đã kiểm chứng | `CON-04` |
| Timeout đề xuất VNPay/Momo 10s, GHN/GHTK 8s | 🔴 Giả định — kế thừa từ `SAD.md §3.4`, chưa kiểm chứng sandbox thật | `CTX §4.2` |
| Fallback GHN↔GHTK hoạt động đúng khi chuyển đổi API giữa chừng | 🔴 Giả định | `ARISK-04`, chưa có tài liệu API/sandbox thật |
## 2. Phương án đã cân nhắc
### PA-1 — Mỗi đội tự thiết kế timeout/retry riêng cho từng đối tác (không có chính sách chung)
| | |
|---|---|
| **Mô tả** | Không có ADR/chuẩn chung — mỗi dev tích hợp VNPay/Momo/GHN/GHTK tự quyết định timeout/retry theo kinh nghiệm cá nhân |
| **Ưu** | Linh hoạt tối đa cho từng đối tác cụ thể |
| **Nhược** | Không nhất quán — dev khác nhau chọn số khác nhau, khó audit/thay đổi hàng loạt khi cần; đúng bẫy đã cảnh báo ở `GUIDE.md` ("Bỏ qua đường lỗi vì sẽ xử lý lúc code") |
| **Chi phí đảo ngược** | Cao — chuẩn hoá lại sau khi đã có nhiều cách làm khác nhau tốn công rà soát từng điểm tích hợp |
### PA-2 — Chính sách chung: timeout theo loại đối tác + retry có backoff + idempotency key bắt buộc, adapter riêng mỗi đối tác *(chọn)*
| | |
|---|---|
| **Mô tả** | Một chuẩn chung áp dụng cho mọi đối tác ngoài: timeout cụ thể theo loại (thanh toán 10s, vận chuyển 8s — đề xuất, chờ kiểm chứng sandbox), retry ≤3 lần với exponential backoff + jitter, idempotency key bắt buộc cho mọi lời gọi ghi; mỗi đối tác có một adapter/anti-corruption layer riêng để cô lập thay đổi API của họ |
| **Ưu** | Nhất quán, dễ audit và thay đổi hàng loạt; adapter riêng giúp thay đổi API một đối tác không ảnh hưởng đối tác khác; đặt tiền lệ cho đối tác tương lai (khớp `decision-radar.md §4`) |
| **Nhược** | Cần thời gian thiết kế chuẩn chung trước khi bắt tay code từng đối tác; timeout cụ thể vẫn là đề xuất chưa kiểm chứng sandbox thật |
| **Chi phí đảo ngược** | Thấp — điều chỉnh số cụ thể (timeout, số lần retry) sau khi có sandbox thật là thay đổi cấu hình, không phải viết lại kiến trúc |
### Bảng so sánh
| Tiêu chí | PA-1 (Tự do từng đội) | PA-2 (Chuẩn chung + adapter) |
|---|---|---|
| Nhất quán, dễ audit | ❌ | ✅ |
| Đặt tiền lệ cho đối tác tương lai | ❌ | ✅ |
| Cô lập thay đổi API một đối tác | 🔶 Tuỳ đội | ✅ (adapter riêng) |
| Effort thiết kế trước khi code | Thấp | Trung bình |
## 3. Quyết định
> **Chọn PA-2 — Chính sách resilience chung (timeout theo loại đối tác, retry backoff+jitter,
> idempotency key bắt buộc) + adapter riêng cho mỗi đối tác.**
**Vì sao:** Đây là quyết định thiết lập tiền lệ cho mọi tích hợp đối tác ngoài hiện tại và tương
lai (`decision-radar.md §4`) — không nhất quán ngay từ đầu sẽ tốn công chuẩn hoá lại sau, đúng
bẫy đã cảnh báo ở `GUIDE.md`.
**Phạm vi áp dụng:** VNPay, Momo, GHN, GHTK, Email/SMS Provider, và mọi đối tác ngoài tương lai.
### Điều kiện chuyển `Proposed → Accepted`
| Điều kiện | Ai xác nhận | Trạng thái hiện tại |
|---|---|---|
| Có sandbox thật của cả 4 đối tác để kiểm chứng timeout cụ thể | Tech Lead | Chưa có (`CON-04`, `ARISK-03`/`04`) |
| Kiểm chứng fallback GHN↔GHTK hoạt động đúng | Tech Lead | Chưa kiểm chứng |
| Không bắt buộc POC theo `decision-radar.md §6` (không phải con số hiệu năng lớn) nhưng cần sandbox thật | — | Chờ sandbox |
## 4. Phương án bị loại và lý do
| Phương án | Loại vì | Gắn với | Điều kiện nào thì xét lại |
|---|---|---|---|
| PA-1 — Mỗi đội tự thiết kế riêng | Không nhất quán, khó audit/thay đổi hàng loạt; vi phạm nguyên tắc "đường lỗi không thể xử lý lúc code" | `GUIDE.md` "Bẫy thường gặp" | Không xét lại — đây là anti-pattern đã có cảnh báo rõ trong bộ SA |
## 5. Hệ quả
**Hệ quả tích cực**
- Nhất quán, dễ audit và thay đổi hàng loạt khi cần đổi chính sách retry/timeout
- Adapter riêng cô lập thay đổi API một đối tác, không lan sang đối tác khác
**Hệ quả tiêu cực phải sống chung**
- Cần thời gian thiết kế chuẩn chung trước khi từng đội bắt tay code — có thể chậm hơn PA-1 ở
giai đoạn đầu
- Timeout cụ thể (10s/8s) vẫn là đề xuất chưa kiểm chứng, có thể cần điều chỉnh khi có sandbox
**Cái quyết định này khoá lại**
| Muốn đổi về sau thì | Tốn |
|---|---|
| Bỏ chuẩn chung, để từng đối tác tự do sau khi đã có nhiều adapter theo chuẩn | Không tốn nhiều nếu chỉ đổi số cụ thể; tốn nhiều nếu đổi cấu trúc adapter |
**Việc phát sinh**
| Việc | Chủ | Hạn | Ghi ở đâu |
|---|---|---|---|
| Đàm phán sandbox 4 đối tác | Tech Lead + PM | Trước GĐ2 `ICD` hoàn tất | `ARISK-03`, `ARISK-04` |
| Thiết kế chi tiết từng phụ thuộc (4 câu hỏi D6) | SA (hoạt động `fail`) | GĐ2 tiếp theo | `FAIL_e-commerce` |
| Viết integration test cho fallback GHN↔GHTK | Tech Lead | GĐ2/GĐ3 | `FIT` (ứng viên) |
## 6. Cách kiểm chứng quyết định này được tuân thủ
| Cách kiểm | Công cụ | Chạy ở đâu | `FIT` |
|---|---|---|---|
| Mọi lời gọi ghi tới đối tác ngoài có idempotency key | Code review/lint + integration test | CI | `FIT-14` (ứng viên) |
| Retry có backoff+jitter, không retry storm khi đối tác hồi phục | Integration test giả lập đối tác chậm/hỏng | CI + staging | `FIT-15` (ứng viên) |
| Fallback GHN→GHTK kích hoạt đúng khi GHN lỗi | Integration test riêng cho luồng fallback | Staging, cần sandbox thật | — |
## 7. Điều kiện xét lại
| Dấu hiệu | Ngưỡng | Ai theo dõi |
|---|---|---|
| Sandbox thật cho thấy timeout đề xuất sai lệch nhiều | Timeout thật khác đề xuất > 50% | Tech Lead |
| Fallback GHN↔GHTK thất bại trong kiểm thử/production | Bất kỳ lần nào | Tech Lead/SRE |
## 8. Tham chiếu
- POC: Không bắt buộc — cần sandbox thật để kiểm chứng đầy đủ
- Bài đo: `FIT-14`, `FIT-15` (ứng viên GĐ3)
- Tài liệu ngoài: `CTX_e-commerce_v1.0.md §4.2` (trạng thái đối tác), `ARISK_e-commerce_v1.0.md §3 ARISK-03/04`
- Thảo luận: `ASR_e-commerce_v1.0.md §B2 ASR-013`
## 9. Review log (không đổi Status)
| Ngày | Người review | Vai trò | Quyết định | Lý do chưa chuyển `Accepted` |
|---|---|---|---|---|
| 2026-09-15 | Điều phối dự án (thay mặt Tech Lead, chế độ chạy thử) | Tech Lead (ký thay, ngoại lệ `DEC-01`) | `Reviewed (Proposed giữ nguyên)` — nội dung đủ làm cơ sở thiết kế tiếp (`icd`/`dat`/`sec`/`inf`/`fail`) | Chưa có chữ ký thật Tech Lead; cần chạy thử trên sandbox đối tác ngoài trước khi chốt |
> Đây là ghi nhận **review nội dung**, không phải "sign" theo nghĩa gate: `Status` giữ nguyên
> `Proposed`. Xem `00-index/ADL_e-commerce.md` (Change Log — Review 2026-09-15) và `ADL §8`
> "Việc phải làm" cho điều kiện chuyển `Accepted`. Confidence tổng thể của lượt review: 🔴 —
> `AG2` chưa ký.