ADR-0004. Bảng WebhookConfig thay cho cấu hình routing tĩnh
| Trường | Giá trị |
|---|---|
| Trạng thái | Accepted |
| Ngày | 2026-03-08 |
| Người quyết định | Phat Nguyen |
| Thay thế | - |
Bối cảnh
- Payment phát webhook khi trạng thái transaction/attempt thay đổi. Các subscriber (sale, finance, tích hợp tuỳ chỉnh) cần endpoint của họ nhận được các sự kiện này.
- Có hai cách cấu hình routing:
- Cấu hình tĩnh (env var / yaml) - endpoint nhúng cứng vào bản triển khai.
- Registry động - các hàng
WebhookConfiglưu trong DB; admin có thể đăng ký subscriber mới khi đang chạy.
Quyết định
Dùng bảng WebhookConfig với các endpoint CRUD (POST /webhook-configs). Mỗi hàng có url, eventTypes[], status, tuỳ chọn signingMethod + secret, và metadata riêng từng hàng (timeout, số lần retry tối đa).
WebhookEventHandlerHelper.handle() truy vấn các config đang hoạt động đã lọc theo loại sự kiện và gửi tới từng cái.
Hệ quả
| Ưu điểm | Nhược điểm |
|---|---|
| Thêm subscriber mới mà không cần triển khai lại | Lệch cấu hình giữa các môi trường (do DB quản lý) |
| Retry/timeout/HMAC riêng từng subscriber | Cần phân quyền để quản lý webhook config (bảo mật) |
Bật/tắt subscriber qua status | Truy vấn DB trên mỗi sự kiện - cần index (status, eventTypes GIN) để đạt hiệu năng |
| Vết audit qua lịch sử Configuration (nếu có triển khai) | Endpoint thử nghiệm có thể lọt vào prod nếu không dọn dẹp |
Quyết định về schema
eventTypes: text[](mảng Postgres) - hỗ trợ lọc quaeventTypes @> ARRAY[event].metadata: jsonbvới mặc định{ timeoutMs: 30000, maxRetries: 3 }- tinh chỉnh được theo từng hàng.- Hỗ trợ soft-delete (ưu tiên vô hiệu hoá qua
statusđể giữ vết audit).
Phương án đã cân nhắc
| Lựa chọn | Ưu điểm | Nhược điểm | Lý do từ chối |
|---|---|---|---|
| URL hardcode trong env | Đơn giản | Không đổi được khi đang chạy; không mở rộng cho nhiều subscriber | Thiếu linh hoạt |
| Routing bằng service mesh (ví dụ Istio) | Tách ứng dụng khỏi URL | Hạ tầng nặng nề | Quá mức cần thiết |
| Pub/sub bên ngoài (Kafka topic) | Tách rời; subscriber tự tiêu thụ | Không cân xứng - sale vốn đã dùng kiểu HTTP webhook | Chi phí migration không xứng đáng |
Tham chiếu
core/src/models/schemas/public/webhook-config/schema.tscontrollers/webhook-config/controller.tshelpers/webhook-event-handler/helper.ts