Skip to content

Architecture

1. System Context (C4 L1)

2. Container View (C4 L2)

3. Component View (C4 L3) — Phân lớp nội bộ

LayerTrách nhiệm
ComponentsKafka producer/consumer, WebSocket emitter, asset ngân hàng VN
ControllersAuth + cổng Casbin + map DTO; action tùy chỉnh phiếu; scope tài khoản theo merchant
WorkerFinanceWorkerService — map sự kiện inbound thành lời gọi issueDirect
Core servicesFinanceVoucherService (động cơ hạch toán), FinanceAccountService, PaymentIntegrationService
RepositoriesTruy vấn Drizzle, soft-delete, lưu balance/posting-sequence (tất cả từ @nx/core)

4. Chỉ mục State Machine

EntityTrạng tháiSơ đồ
FinanceVoucherDRAFT, ISSUED, VOIDED→ jump
FinanceTransactionPENDING, COMPLETED, CANCELLED→ jump
FinanceAccountACTIVATED, DEACTIVATED, ARCHIVED→ jump

FinanceVoucher

TừSự kiệnĐếnGuards
createDraftDRAFTnguồn manual; dòng đệm trong metadata.draftLines
issueDirectISSUEDdòng post ngay; replay idempotent trên dedup key
DRAFTapprove (issueDraft)ISSUEDdraft phải có ≥1 dòng; nâng draft, gán số
DRAFTdeleteDraftremovedchỉ khi đang DRAFT
ISSUEDvoidVOIDEDkhông phải COGS/INVENTORY_ADJUSTMENT; opening-balance chỉ khi không có hoạt động sau; phát phiếu đối ứng

FinanceTransaction (dòng ledger)

Trên thực tế các dòng phiếu được tạo trực tiếp COMPLETED. PENDING/CANCELLED tồn tại trong enum cho các luồng tương lai.

FinanceAccount

5. Kịch bản Runtime

5.1 Thanh toán bán hàng → phiếu RECEIPT

BướcChi tiết
1-2Idempotency qua sourceEventUid = attempt.uid (dedup theo từng sự kiện SALE_ORDER)
3RECEIPT ⇒ hướng dòng suy ra DEBIT; balance tăng
4Toàn bộ hạch toán là một DB transaction với SELECT … FOR UPDATE trên tài khoản

5.2 Đơn mua đã nhận → phiếu PAYMENT (với leg tài sản)

5.3 Tồn kho xuất bán → hạch toán COGS

5.4 Merchant CDC → đối soát tài khoản + onboarding

6. Mối quan tâm xuyên suốt

Mối quan tâmCách service này xử lý
AuthNJWT (Issuer = identity), JWKS verify mỗi request (VerifierApplication)
AuthZCasbin; list/count tài khoản lọc theo GROUP policy từng merchant (assertMerchantAccess trên route single-entity)
i18nCột jsonb, dạng { default, en, vi } (tên account/category, party/reason phiếu)
LoggingKey-value có cấu trúc (key: %s); @logged() trên handler worker
IdempotencyDedup phiếu: partial unique index theo từng-source (merchantId, type, sourceType, sourceId) và theo từng-event (sourceType, sourceEventUid); issueDirect replay phiếu hiện có khi trúng
Toàn vẹn hạch toánpostingSequenceLastValue tăng nghiêm ngặt theo tài khoản; balance tính trong-tx với float(_, 4); dòng tài khoản khóa FOR UPDATE
Soft-deleteSoftDeletableRepository (deletedAt)
IDsSnowflake qua IdGenerator, worker 4

7. Trang liên quan

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.