PRD: Tài khoản tài chính & sổ cái
| Module | Tài chính (CORE-12) | PRD ID | PRD-WAL-001 |
| Status | In-progress | Owner | Nhóm Tài chính |
| Date | 2026-06-04 | Version | v0.1 |
| Packages | @nx/finance · @nx/ledger | URD | WAL · TXN |
TL;DR
Cho merchant một nơi chính thức để chứa tiền: các tài khoản có kiểu (tiền mặt, ngân hàng, QR, mobile-POS) mang số dư lũy kế, cùng các tài khoản kiểm soát nội bộ (Inventory, Cost of Goods Sold) mà hệ thống tự duy trì. Mỗi voucher post các dòng sổ cái ghi nợ/ghi có cân bằng vào các tài khoản đó, mỗi dòng mang một snapshot số dư trước/sau - để chủ cửa hàng có thể truy ra tiền nằm ở đâu và mỗi lần post đã dịch chuyển nó ra sao.
1. Bối cảnh & Vấn đề
Module Tài chính (URD §1) theo dõi tiền trên các tài khoản, ghi nhận mọi dòng tiền dưới dạng một voucher ghi sổ kép cân bằng, và post phần lớn các dòng tiền một cách tự động. Không có gì trong số đó có chỗ để tồn tại cho đến khi các tài khoản và dòng sổ cái xuất hiện. Không có tài khoản có kiểu thì không có số dư lũy kế để định tuyến các lần post tự động, và không có dòng sổ cái thì không có một dấu vết kiểm toán cân bằng, theo từng tài khoản, về việc mỗi voucher đã dịch chuyển tiền như thế nào.
Phần việc này đặt nền móng: các tài khoản (WAL) chứa tiền và mang số dư lũy kế, và các dòng sổ cái (TXN) mà mọi voucher post vào chúng. Nó cũng giới thiệu các tài khoản kiểm soát nội bộ phi tiền mặt (Inventory, Cost of Goods Sold) mà hệ thống tự duy trì, để các lần post giá vốn hàng bán và điều chỉnh tồn kho có chỗ để rơi vào.
2. Mục tiêu & Không phải mục tiêu
Mục tiêu
- Chứa các tài khoản có kiểu (Cash, Bank, QR, Mobile-POS), mỗi tài khoản thuộc về một merchant, mỗi tài khoản có một số dư lũy kế.
- Duy trì đúng một tài khoản mặc định cho mỗi loại trên mỗi merchant để định tuyến các lần post tự động.
- Seed các tài khoản mặc định của mỗi merchant cùng các tài khoản kiểm soát nội bộ Inventory / Cost of Goods Sold khi merchant được tạo.
- Post các dòng sổ cái ghi nợ/ghi có vào các tài khoản, mỗi dòng mang tài khoản của nó, số tiền, và một snapshot số dư trước/sau, theo đơn vị tiền của voucher.
- Liên kết các tài khoản với các payment integration (tham chiếu, không tự động kèm vào).
Không phải mục tiêu
- Xử lý payment-gateway - thuộc module Payment; tài chính chỉ liên kết tới các integration.
- Toàn bộ vòng đời voucher và các quy tắc post tự động (
VCH) cùng phân loại danh mục (CAT) - do các feature riêng của chúng theo dõi. - Theo dõi ngân sách, lãi lỗ, và dự báo dòng tiền.
- Quy đổi đa tiền tệ trong cùng một voucher (một đơn vị tiền cho mỗi voucher, mặc định VND).
3. Success Metrics
| Metric | Mục tiêu / tín hiệu |
|---|---|
| Độ phủ tài khoản | Mọi merchant đều có các tài khoản mặc định và kiểm soát nội bộ sau khi được tạo |
| Tính duy nhất của mặc định | Đúng một tài khoản mặc định cho mỗi loại trên mỗi merchant; không có bản trùng |
| Toàn vẹn số dư | Số dư lũy kế của tài khoản bằng tổng các dòng sổ cái đã post của nó |
| Đầy đủ snapshot | Mọi dòng sổ cái đều mang một snapshot số dư trước/sau theo đơn vị tiền của voucher |
4. Personas & Use Cases
| Persona | Mục tiêu |
|---|---|
| Owner | Thấy tiền nằm ở đâu trên các tài khoản tiền mặt, ngân hàng, QR, mobile-POS và đối chiếu số dư |
| Kế toán / Quản lý | Đọc sổ cái theo từng tài khoản và truy mỗi dòng tiền về chứng từ nguồn của nó |
| Hệ thống (worker) | Tự seed các tài khoản khi có merchant mới và post các dòng sổ cái cân bằng cho mọi voucher |
Kịch bản cốt lõi: một merchant được tạo → các tài khoản mặc định và kiểm soát nội bộ được seed → các voucher post các dòng sổ cái ghi nợ/ghi có vào các tài khoản đó → số dư lũy kế của mỗi tài khoản cập nhật và mỗi dòng ghi lại một snapshot số dư trước/sau.
5. User Stories
- Là một owner, tôi muốn có các tài khoản có kiểu cho tiền mặt, ngân hàng, QR, và mobile-POS, để tôi thấy tiền của mình nằm ở đâu và số dư lũy kế của nó.
- Là một owner, tôi muốn một tài khoản mặc định cho mỗi loại, để các lần post tự động định tuyến tới một tài khoản dự đoán được.
- Là hệ thống, tôi muốn các tài khoản mặc định và kiểm soát nội bộ của một merchant mới được seed tự động, để các lần post giá vốn và tồn kho có chỗ rơi vào ngay từ ngày đầu.
- Là một kế toán, tôi muốn mỗi voucher post các dòng sổ cái cân bằng vào các tài khoản kèm một snapshot số dư, để tôi có thể kiểm toán mỗi dòng tiền đã thay đổi một tài khoản như thế nào.
- Là một owner, tôi muốn một tài khoản tham chiếu tới payment integration của nó, để một tài khoản QR / mobile-POS gắn ngược về gateway của nó mà không tự động kéo dữ liệu integration vào.
6. Functional Requirements
| # | Yêu cầu | URD ref |
|---|---|---|
| FR-1 | Chứa các tài khoản loại Cash, Bank, QR, và Mobile-POS, mỗi tài khoản thuộc về một merchant | URD-WAL-001 |
| FR-2 | Duy trì một tài khoản mặc định cho mỗi loại trên mỗi merchant để định tuyến các lần post tự động | URD-WAL-002 |
| FR-3 | Tự tạo các tài khoản mặc định và kiểm soát nội bộ (Inventory, Cost of Goods Sold) của mỗi merchant khi merchant được tạo | URD-WAL-003 |
| FR-4 | Theo dõi số dư hiện tại lũy kế của mỗi tài khoản khi các voucher post | URD-WAL-004 |
| FR-5 | Cho phép đơn vị tiền của tài khoản (mặc định VND) | URD-WAL-005 |
| FR-6 | Giới hạn khả năng thấy tài khoản theo các merchant mà người dùng được grant; admin thấy tất cả | URD-WAL-006 |
| FR-7 | Mỗi voucher post các dòng sổ cái ghi nợ/ghi có vào các tài khoản | URD-TXN-001 |
| FR-8 | Một dòng mang tài khoản nó tác động, một category tùy chọn, một số tiền, và một snapshot số dư trước/sau | URD-TXN-002 |
| FR-9 | Các dòng sổ cái dùng chung đơn vị tiền của voucher | URD-TXN-003 |
| FR-10 | Một dòng có thể tham chiếu chứng từ nguồn của nó để truy vết | URD-TXN-004 |
Toàn văn yêu cầu và tiêu chí chấp nhận nằm trong URD Tài chính. PRD này tham chiếu tới chúng thay vì lặp lại.
7. Non-Functional Requirements
| Lĩnh vực | Yêu cầu |
|---|---|
| Toàn vẹn dữ liệu | Số dư lũy kế của một tài khoản và các dòng sổ cái dịch chuyển nó được ghi cùng nhau; số dư bằng tổng các dòng đã post |
| Tính duy nhất của mặc định | Đúng một tài khoản mặc định cho mỗi loại trên mỗi merchant, ràng buộc ở cấp model |
| Tenancy & authz | Các tài khoản được scope theo merchant (x-merchant-id); non-admin chỉ thấy các merchant được grant, admin thấy tất cả |
| Độ chính xác | Toán tiền tệ dùng float(value, 4); số dư lưu cùng độ chính xác |
| Nhất quán | Việc seed tài khoản và post sổ cái là idempotent và một thao tác duy nhất; một sự kiện merchant lặp lại không bao giờ seed trùng |
| i18n | Nhãn/loại hiển thị cho người dùng là song ngữ ({ en, vi }) |
8. UX & Flows
Các màn hình chính (trong apps/client): danh sách / lọc / form tài khoản (gồm loại bank), voucher chọn-tài-khoản-theo-tiền-tệ, và bảng / lọc / trang xem sổ cái kèm chế độ xem PDF.
9. Data & Domain
| Entity | Vai trò |
|---|---|
Account (finance-account) | Một tài khoản tiền - loại (Cash/Bank/QR/Mobile-POS), merchant sở hữu, số dư lũy kế, đơn vị tiền, isDefault theo loại, relation tùy chọn tới payment integration |
| Tài khoản kiểm soát nội bộ | Một tài khoản phi tiền mặt (Inventory, Cost of Goods Sold) mà hệ thống duy trì cho các lần post giá vốn/tồn kho |
LedgerLine | Một dòng ghi nợ/ghi có - tài khoản tác động, category tùy chọn, số tiền, snapshot số dư trước/sau, đơn vị tiền của voucher, tham chiếu chứng từ nguồn |
| Ledger config / job | Cấu hình sổ cái theo từng merchant và ledger job dạng draft (với tiến độ qua websocket) |
Chỉ ở mức khái niệm - schema và bất biến đầy đủ nằm trong finance domain model.
10. Dependencies & Assumptions
Phụ thuộc vào
- Commerce (Merchant) - các tài khoản của một merchant mới được đối chiếu tự động khi tạo.
- Voucher & posting (URD-VCH) - voucher là thứ post các dòng sổ cái vào các tài khoản.
- Payment (
@nx/payment) - các tài khoản tham chiếu tới các payment integration (liên kết, không tự động kèm vào).
Giả định
- Một sự kiện merchant-được-tạo được chuyển tới finance worker để các tài khoản có thể được seed.
- Các tài khoản kiểm soát nội bộ tồn tại trước khi bất kỳ lần post giá vốn hàng bán nào được thực hiện.
11. Risks & Open Questions
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Số dư tài khoản và các dòng sổ cái có thể lệch nhau | Ghi theo một thao tác duy nhất; số dư bằng tổng các dòng đã post, snapshot theo từng dòng |
| Sự kiện merchant lặp lại có thể seed trùng tài khoản | Việc seed là idempotent - một sự kiện lặp lại không bao giờ tạo tài khoản mặc định thứ hai |
Tính duy nhất của isDefault theo loại | Ràng buộc ở cấp model sau các sửa lỗi template/model ban đầu |
| Không hỗ trợ đa tiền tệ trong một voucher | Ngoài phạm vi; một đơn vị tiền cho mỗi voucher (mặc định VND) |
12. Release Plan & Launch Criteria
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P1 (nền móng) - xem catalog tính năng URD |
| Rollout | Tất cả merchant; không feature flag |
| Migration | Migration seed cho các tài khoản tài chính mặc định; các tài khoản kiểm soát nội bộ được seed theo từng merchant |
| Tiêu chí ra mắt | Merchant mới nhận được các tài khoản mặc định + kiểm soát; các dòng sổ cái post cân bằng kèm snapshot số dư; số dư tài khoản bằng tổng các dòng của nó |
| Giám sát | Số lượng tài khoản theo từng merchant, kiểm tra tính duy nhất của mặc định, nhất quán số-dư-so-với-tổng-sổ-cái |
13. FAQ
Có những loại tài khoản nào? Cash, Bank, QR, và Mobile-POS - cùng các tài khoản kiểm soát nội bộ phi tiền mặt (Inventory, Cost of Goods Sold) mà hệ thống tự duy trì.
Tài khoản kiểm soát nội bộ là gì? Một tài khoản ghi sổ phi tiền mặt - không phải tiền của merchant - cho các lần post giá vốn hàng bán và điều chỉnh tồn kho có một chỗ để rơi vào.
Tài khoản mặc định được chọn ra sao? Đúng một tài khoản cho mỗi loại trên mỗi merchant được đánh dấu mặc định; các lần post tự động định tuyến tới nó.
Một dòng sổ cái ghi lại những gì? Tài khoản tác động, một category tùy chọn, một số tiền, đơn vị tiền của voucher, một snapshot số dư trước/sau, và một tham chiếu chứng từ nguồn tùy chọn.
Liên kết một tài khoản với payment integration có kéo dữ liệu integration vào không? Không - relation là một tham chiếu; các integration không được tự động kèm vào tài khoản.
References
- URD: Tài chính - Accounts (
WAL) · Ledger Lines (TXN) - Liên quan: Vouchers & Posting (
VCH) · Categories (CAT) - Module: Tài chính - tổng quan + truy vết
- Developer: @nx/finance · domain model