PRD: Danh mục tài chính
| Module | Tài chính (CORE-12) | PRD ID | PRD-CAT-001 |
| Status | Shipped | Owner | Finance squad |
| Date | 2026-05-25 | Version | v1.0 |
| Packages | @nx/finance · apps/client | URD | CAT |
TL;DR
Cho phép merchant đọc sổ sách theo thu vs chi và theo lý do (Bán hàng, Mua hàng, Thuê mặt bằng, Lương…). Một danh mục cố định các category hệ thống thuộc sở hữu nền tảng được áp dụng tự động cho mọi voucher sinh tự động, đồng thời merchant có thể thêm category riêng lồng dưới một category cha qua một màn hình quản lý. Kết quả: mọi dòng tiền đều mang một phân loại nhất quán, có thể báo cáo được - không còn voucher thiếu nhãn, không còn gắn nhãn tùy tiện.
1. Context & Problem
Mọi dòng tiền trong Finance cần một phân loại để chủ tiệm đọc sổ sách theo thu vs chi và theo lý do (Bán hàng, Mua hàng, Thuê mặt bằng, Lương…). Nếu không có danh mục category, các voucher sinh tự động - phiếu thu khi đơn hàng được thanh toán, phiếu chi khi nhận purchase order - sẽ không có nhãn nhất quán, và merchant không thể nhóm hay báo cáo dòng tiền của mình. Điều này chặn nhu cầu đọc sổ sách cơ bản mà các chủ HKD/SME mong đợi.
Hạng mục này cung cấp trục category của mô hình voucher ghi sổ kép: một tập category cố định mà nền tảng sở hữu và áp dụng tự động, cùng khả năng cho merchant thêm category riêng lồng dưới một category cha, hiển thị qua một màn hình quản lý trong client.
2. Goals & Non-Goals
Goals
- Cung cấp một danh mục cố định các category hệ thống bao trùm thu và chi, thuộc sở hữu nền tảng (không scope theo merchant).
- Phân loại mỗi category là thu hoặc chi.
- Áp dụng category hệ thống tự động cho voucher sinh tự động (Bán hàng, Mua hàng, v.v.) qua các định danh cố định ổn định.
- Cho phép merchant thêm category tùy chỉnh lồng dưới một category cha, quản lý qua một màn hình client với xem trước trực tiếp, bộ chọn category cha, và hiển thị icon/badge.
Non-Goals
- Theo dõi ngân sách và chênh lệch (Non-Goal của URD).
- Tự động hóa chi phí định kỳ / theo lịch (Non-Goal của URD).
- Báo cáo lãi/lỗ và dự báo dòng tiền (Non-Goal của URD).
- Bản thân cơ chế hạch toán voucher và ledger line - thuộc các area
VCHvàTXN.
3. Success Metrics
| Metric | Mục tiêu / tín hiệu |
|---|---|
| Độ phủ phân loại | 100% voucher sinh tự động mang một category hệ thống |
| Tính ổn định của danh mục | Chạy lại seeder không bao giờ tạo trùng category hệ thống (idempotent theo định danh) |
| Mức độ dùng category tùy chỉnh | Số merchant thêm ít nhất một category tùy chỉnh tăng dần |
| Sẵn sàng báo cáo | Dòng tiền nhóm gọn theo thu/chi và theo category trong báo cáo |
4. Personas & Use Cases
| Persona | Mục tiêu trong tính năng này |
|---|---|
| Chủ tiệm | Đọc sổ sách theo thu vs chi và theo lý do; tùy biến category cho doanh nghiệp |
| Kế toán / Quản lý | Phân loại dòng tiền nhất quán để báo cáo |
| Nền tảng | Áp dụng một category ổn định, đã biết, cho mọi bút toán tự động |
Core scenarios: nền tảng seed danh mục cố định lúc khởi động → voucher sinh tự động phân giải một category hệ thống ổn định theo định danh cố định → chủ tiệm thêm category tùy chỉnh lồng dưới một category cha qua màn hình quản lý → mọi dòng tiền báo cáo theo thu/chi và theo category.
5. User Stories
- Là chủ tiệm, tôi muốn dòng tiền được phân loại thu hoặc chi, để tôi đọc sổ sách trong nháy mắt.
- Là chủ tiệm, tôi muốn voucher sinh tự động mang category hệ thống nhất quán, để bán hàng và mua hàng nhóm đúng mà không phải gắn nhãn thủ công.
- Là chủ tiệm, tôi muốn thêm category riêng lồng dưới một category cha, để phân loại khớp với cách doanh nghiệp tôi nghĩ về dòng tiền.
- Là chủ tiệm, tôi muốn một màn hình quản lý có xem trước trực tiếp và bộ chọn icon, để tạo và sửa category rõ ràng.
- Là nền tảng, tôi muốn một tập category hệ thống cố định mà seeder chạy lại an toàn, để bút toán tự động luôn phân giải được một category ổn định.
6. Functional Requirements
| # | Requirement | URD ref |
|---|---|---|
| FR-1 | Cung cấp danh mục cố định các category hệ thống được seed, bao trùm thu và chi, thuộc sở hữu nền tảng (merchantId: null); seeder idempotent (tạo-hoặc-cập-nhật theo định danh/loại) | URD-CAT-001 |
| FR-2 | Mỗi category được phân loại INCOME hoặc EXPENSE | URD-CAT-002 |
| FR-3 | Category hệ thống được khóa bằng định danh cố định ổn định (SALE, PURCHASE, REFUND_*, …) để voucher sinh tự động phân giải một category hệ thống tự động | URD-CAT-003 |
| FR-4 | Merchant có thể thêm category tùy chỉnh lồng dưới một category cha, kèm metadata icon | URD-CAT-004 |
| FR-5 | CRUD category scope theo merchant (x-merchant-id), được authorize qua finance category permission | URD-CAT-004 |
| FR-6 | Một màn hình quản lý client cho tạo / sửa / liệt kê, với ô nhập tên, bộ chọn category cha, xem trước trực tiếp, badge + bộ icon, và nhãn song ngữ | URD-CAT-004 |
Toàn văn requirement và tiêu chí nghiệm thu nằm trong URD Tài chính. PRD này tham chiếu chúng thay vì lặp lại.
7. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Data integrity | Category hệ thống mang định danh cố định ổn định; bút toán tự động phân giải theo định danh, không bao giờ theo tên |
| Idempotency | Seeder tạo-hoặc-cập-nhật theo định danh/loại - chạy lại không bao giờ tạo trùng category hệ thống |
| Tenancy & authz | Category hệ thống thuộc sở hữu nền tảng (merchantId: null); category tùy chỉnh scope theo merchant (x-merchant-id) và được gác bằng permission |
| Performance / scale | Danh mục category nhỏ và có thể cache; phân giải theo định danh cố định là tra cứu thời gian hằng số |
| i18n | Tên category và nhãn màn hình là song ngữ ({ en, vi }) |
8. UX & Flows
Các màn hình chính (trong apps/client): danh sách category, tạo, và sửa - với ô nhập tên, bộ chọn category cha, xem trước trực tiếp, và badge category + bộ icon.
9. Data & Domain
| Entity | Vai trò |
|---|---|
FinanceCategory | Bản ghi category - type (thu/chi), parentId (lồng phân cấp), metadata icon, merchantId (null = thuộc sở hữu nền tảng) |
FixedFinanceCategories | Định danh cố định ổn định (SALE, PURCHASE, REFUND_*, …) dùng bởi bút toán tự động để phân giải một category hệ thống |
FinanceCategoryTypes | Enum loại thu / chi |
| Category seeder | Process khởi động idempotent seed danh mục hệ thống cố định (finance-0001-seed-categories.ts) |
Chỉ ở mức khái niệm - schema và bất biến đầy đủ trong finance domain model.
10. Dependencies & Assumptions
Phụ thuộc vào
- Vouchers & Posting (URD-VCH) - voucher sinh tự động tiêu thụ category.
- Ledger Lines (URD-TXN) - một ledger line mang category tùy chọn.
@nx/finance- seeder, schema, và controller scope theo merchant nằm ở đây.
Giả định
- Các category hệ thống cố định bao trùm các lý do thu/chi mà bút toán tự động phát ra (Bán hàng, Mua hàng, hoàn tiền, v.v.).
- Một merchant tồn tại trước khi tạo category tùy chỉnh scope theo merchant.
11. Risks & Open Questions
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Bút toán tự động có thể không phân giải được category | Phân giải theo định danh cố định ổn định, được seed idempotent lúc khởi động |
| Chạy lại seeder có thể tạo trùng category | Seeder tạo-hoặc-cập-nhật theo định danh/loại - không bao giờ tạo trùng |
| Lồng category tùy chỉnh quá sâu có thể làm phức tạp báo cáo | Một cấp category cha là mô hình được tài liệu hóa; xem lại nếu xuất hiện nhu cầu nhiều cấp |
| Đổi tên category hệ thống thủ công | Category hệ thống thuộc sở hữu nền tảng, merchant không sửa được |
12. Release Plan & Launch Criteria
| Aspect | Kế hoạch |
|---|---|
| Phase | P1 (nền tảng) - xem danh mục tính năng URD |
| Rollout | Tất cả merchant; không feature flag |
| Migration | Không có cho merchant; danh mục hệ thống cố định được seed lúc khởi động (idempotent) |
| Launch criteria | 14 category hệ thống được seed với phân loại thu/chi đúng; voucher sinh tự động phân giải một category hệ thống theo định danh cố định; tạo/sửa/liệt kê category tùy chỉnh hoạt động scope theo merchant |
| Monitoring | Lỗi phân giải category của bút toán tự động; tốc độ tạo category tùy chỉnh; tính idempotent của seeder khi khởi động lại |
13. FAQ
Merchant có sửa được category hệ thống không? Không - các category hệ thống cố định thuộc sở hữu nền tảng (merchantId: null) và được áp dụng tự động; thay vào đó merchant thêm category tùy chỉnh của riêng mình.
Voucher sinh tự động chọn category bằng cách nào? Bằng một định danh cố định ổn định (SALE, PURCHASE, REFUND_*, …), nên cùng một sự kiện luôn phân giải về cùng một category hệ thống.
Category tùy chỉnh có lồng được không? Có - một category tùy chỉnh lồng dưới một category cha, kèm metadata icon để hiển thị.
Chạy seeder hai lần có tạo bản trùng không? Không - seeder là idempotent (tạo-hoặc-cập-nhật theo định danh/loại).
Cái gì tính là thu vs chi? Mỗi category được phân loại thu hoặc chi; danh mục được seed bao trùm cả hai (ví dụ Doanh thu bán hàng, Hoàn tiền nhận về là thu; Mua hàng, Thuê & tiện ích, Lương là chi).
References
- URD: Tài chính - Categories
- Related PRDs: Vouchers & Posting · Accounts & Ledger
- Module: Tài chính - tổng quan + truy vết
- Developer: @nx/finance · domain model