Bối cảnh
Chi tiêu cá nhân, khoản vay thế chấp, thấu chi và các khoản cho đối tác vay lại nằm rải rác ở sao kê nhiều ngân hàng và vài bảng tính. Mỗi tháng phải đối chiếu tay: tiền nào đã trả, lãi bao nhiêu, đối tác còn nợ bao nhiêu. SPARK Finance gom tất cả về một chỗ — rồi được tách thành SaaS đa tenant để người khác cũng dùng được trên cùng hệ thống.
Tính năng chính
- Nhập sao kê bằng AI: nhận PDF, ảnh, CSV, XLSX. Trình duyệt tách trang PDF (pdf.js) / chuyển XLSX sang CSV, tải file thẳng lên Cloudflare R2 bằng presigned URL; LLM đọc từng trang (~6 giây/trang) và tạo bản nháp — không ghi gì vào sổ cho tới khi người dùng bấm Nhập. Chống nhập trùng bằng sha256, kiểm tra số dư liên tục giữa các kỳ, nhập theo lô.
- Giao dịch & phân loại: danh mục, quy tắc tự phân loại (xem trước rồi áp dụng), xu hướng theo danh mục, dòng tiền theo tháng, nguồn thu và chi phí cố định.
- Khoản vay & thấu chi: dư nợ, lãi ước tính, theo dõi rút/trả thấu chi và đối chiếu dòng tiền.
- Cho vay đối tác: lãi tính theo ngày
dư nợ × lãi suất/365 × số ngày, nhiều giai đoạn lãi suất, điều chỉnh tay, dựng lại từ giao dịch. Đối tác đăng nhập bằng mã 6 số, tự báo đã trả qua VietQR; chủ khoản vay xác nhận qua Telegram bot. - Liên kết tenant: bên cho vay mời bên vay; bên vay xem được khoản vay của mình, hai bên đối chiếu khoản vay và chuyển khoản tự động (lệch ±3 ngày).
- Dashboard kéo thả: 9 loại widget, cộng widget biểu đồ do trợ lý AI dựng từ một câu lệnh.
- Trợ lý AI: chat SSE qua SPARK AI Gateway tới agent OpenClaw riêng; agent chỉ được gọi tool đọc, mọi thao tác ghi đi qua thẻ xác nhận.
SaaS đa tenant
- Mỗi tenant một subdomain
<tenant>.finance.devbyspark.com; tenant chỉ được xác định từ subdomain, khoá API đã xác thực hoặc session do server ký — không bao giờ từ header, query hay body. - Cô lập 4 lớp: kiểu
tenant.IDriêng, pool kết nối từ chối truy vấn thiếu tenant, giá trị mặc định +WITH CHECKcủa PostgreSQL Row-Level Security, và điều kiệnUSINGcủa RLS. Tenant đi theocontext.Contextnên ~55 hàm repository không phải đổi chữ ký; 14 khoá ngoại chuyển sang khoá ghép(tenant_id, …). - Cấp tenant tự động: superadmin tạo tenant, backend commit Ingress của subdomain vào repo GitOps qua GitHub API, ArgoCD đồng bộ và cert-manager cấp TLS.
- Phân quyền: superadmin, quản trị tenant (mã 6 số) và đối tác (mã truy cập riêng); bật/tắt AI và hạn mức tin nhắn AI theo từng tenant.
MCP cho agent bên ngoài
- Endpoint
https://<tenant>.finance.devbyspark.com/api/mcp— Streamable HTTP, JSON-RPC 2.0, có session. - 28 tool (24 đọc, 5 ghi; một tool tìm kiếm ngữ nghĩa ẩn khi tắt embedding): tra giao dịch, dòng tiền, danh mục, khoản vay, thấu chi, đối tác, bản nháp import… — cùng một registry dùng cho REST, MCP và trợ lý AI.
- Khoá API
spk_live_…chỉ lưu SHA-256, chọn quyền theo từng tool và hạn dùng, chỉ chạy trên đúng subdomain của tenant, 120 lời gọi/phút. - Thao tác nhạy cảm (sửa dư nợ, ghi kỳ cho vay) bắt buộc
confirm=true; ghi cóidempotency_key; mọi phiên và lời gọi lưu log 90 ngày. Màn hình "Kết nối MCP" sinh sẵn lệnh/prompt kết nối cho Claude Code, Claude Desktop, Cursor, OpenClaw.
Kỹ thuật
- Backend: Go 1.22 chỉ với 3 thư viện trực tiếp (pgx, minio-go cho R2, x/crypto); router là
http.ServeMuxcủa thư viện chuẩn (~126 route); trình migrate tự viết có checksum và dry-run (37 migration); image distroless. - Cơ sở dữ liệu: PostgreSQL với Row-Level Security,
pg_trgmcho tìm kiếm,pgvectorcho bộ nhớ ngữ nghĩa của trợ lý. - Frontend: React 18, Vite, TypeScript, MUI + MUI X, ApexCharts, react-grid-layout, pdf.js, SheetJS.
- Vận hành: GitHub Actions → Docker Hub → repo GitOps → ArgoCD trên Kubernetes (K3s), cert-manager + Let's Encrypt, rolling update không gián đoạn.
- Kiểm thử: hơn 300 test Go, mỗi test chạy trong schema Postgres riêng; test "khoá" logic tiền (tái hiện đủ 12 kỳ cho vay thật); 31 kịch bản end-to-end đa tenant qua HTTP với Host header từng tenant.
Kết quả
- Thay bảng tính bằng một sổ tài chính tự đối chiếu: số liệu cho vay khớp 12/12 kỳ với bảng tính gốc.
- Đang chạy cho 3 tenant trên
finance.devbyspark.comvà các subdomain riêng. - Agent AI (Claude, OpenClaw…) đọc và ghi dữ liệu tài chính qua MCP với quyền theo từng tool và bước xác nhận an toàn.
Điểm nổi bật
Chuyển từ app một chủ sở hữu sang SaaS đa tenant mà không đổi chữ ký ~55 hàm repository: tenant đi theo context, cô lập 4 lớp với PostgreSQL Row-Level Security (22 ca kiểm tra RLS).
Nhập sao kê bằng LLM: PDF/ảnh/CSV/XLSX tải thẳng lên R2 bằng presigned URL, OCR từng trang (~6 s/trang), chống trùng sha256, kiểm tra liên tục số dư, không ghi gì trước khi người dùng bấm Nhập.
MCP server Streamable HTTP cho từng tenant: khoá spk_live chọn quyền theo từng tool và hạn dùng, xác nhận bắt buộc trước khi sửa dư nợ, log 90 ngày; cùng một registry tool dùng chung cho REST, MCP và trợ lý AI.
Cho vay đối tác: lãi theo ngày, nhiều giai đoạn, đối tác tự báo trả qua VietQR, chủ xác nhận qua Telegram bot; khớp đúng 12/12 kỳ với bảng tính thật.
Liên kết tenant bên cho vay – bên vay với đối chiếu hai chiều khoản vay và chuyển khoản.
Thêm tenant mới tự sinh Ingress vào repo GitOps qua GitHub API, ArgoCD đồng bộ và cấp TLS cho subdomain.
