ADR-0001. Hai lớp provider-adapter: @nx/iiapi và @nx/t-van
| Trường | Giá trị |
|---|---|
| Status | Accepted |
| Date | 2026-04-01 |
| Deciders | invoice-team |
| Supersedes | — |
Bối cảnh
- Hoá đơn điện tử Việt Nam đến cơ quan thuế qua các kênh khác nhau: provider HĐĐT trực tiếp (VNIS, VNPAY) và gateway transaction-VAN (T-VAN).
- Hai kênh có hình dạng SDK, mô hình auth và lưu trữ credential khác nhau (theo từng merchant vs một kết nối platform duy nhất).
- DB mã hoá enum provider riêng (
InvoiceProviders), không được để enum iiapi (IIAPIProviders) lọt vào tầng lưu trữ. - Credential khác nhau theo từng kênh: VNIS dùng một hàng
Configurationplatform; VNPAY dùng các hàngInvoiceProvidertheo từng merchant; T-VAN dùng một hàngConfigurationplatform.
Quyết định
Chúng ta sẽ bọc mỗi kênh trong package adapter riêng và đăng ký chúng bằng các component riêng:
@nx/iiapi(VNIS + VNPAY) đăng ký bởiInvoiceProviderConnectionComponent.@nx/t-van(gateway T-VAN, provider VNPAY) đăng ký bởiTVanConnectionComponent.
Enum provider DB↔iiapi được bắc cầu bởi InvoiceProviderMapper (src/common/providers.ts), vốn ném lỗi với provider lạ. Tầng lưu trữ chỉ bao giờ lưu giá trị InvoiceProviders.
Hệ quả
| Ưu | Nhược |
|---|---|
| Mỗi kênh tiến hoá độc lập | Hai component đăng ký + đường boot phải bảo trì |
| Tầng lưu trữ tách khỏi enum vendor | Mapper phải cập nhật khi thêm provider mới |
| Mô hình credential theo merchant vs platform tách bạch sạch sẽ | Hiện chỉ map VNPAY — các provider khác ném lỗi cho tới khi thêm |
| Thêm provider = mở rộng mapper + adapter, không đổi schema | Hai đường nạp credential (hàng Configuration vs hàng provider) |
Phương án đã cân nhắc
| Phương án | Ưu | Nhược | Vì sao loại |
|---|---|---|---|
| Một adapter cho mọi kênh | Ít component hơn | Ép một hình dạng SDK lên các API không tương thích | Các kênh quá khác nhau (trực tiếp vs VAN) |
| Lưu enum iiapi trực tiếp trong DB | Không cần mapper | Enum vendor lọt vào lưu trữ; biến động migration | Ràng schema vào package bên thứ ba |
| Config T-VAN theo từng merchant | Đối xứng với VNPAY | T-VAN hiện là một gateway platform duy nhất | Quá kỹ so với nhu cầu hiện tại |
Tham chiếu
src/common/providers.ts(InvoiceProviderMapper)src/components/invoice-provider-connection/component.tssrc/components/tvan-connection/component.tssrc/migrations/data/configuration.ts(VNIS_DEFAULT_CONNECTION,TVAN_DEFAULT_CONNECTION)