TLAHuỳnh Văn Giỏi Em

Chili by TLA

Ứng dụng quản lý tài chính cá nhân đang beta với 10 người dùng: ví, ngân sách, sao kê thẻ tín dụng, trả góp và khoản vay, kèm trợ lý AI chuyển câu mô tả hoặc ảnh chụp màn hình thành giao dịch.

Vai trò
Phát triển độc lập · sản phẩm, kỹ thuật và vận hành
Thời gian
06/2026 – Hiện tại
Công nghệ
React 19Express 5Prisma 7PostgreSQLTanStack QueryReact Router 7ZodVitePlaywrightDocker
Liên kết
chili.tlait.online ↗

Điểm chính

  • 3tháng từ repo trống đến production
  • 31phiên bản phát hành trong ba tuần đầu
  • ~3,300test tự động, gồm unit và end-to-end
  • Đưa sản phẩm từ repo trống lên production trong khoảng ba tháng, sau đó phát hành 31 phiên bản trong ba tuần đầu, theo roadmap chia thành các phần nhỏ, mỗi phần hoàn chỉnh từ đầu đến cuối.
  • Thiết kế xoay quanh một nguyên tắc: mọi thao tác làm thay đổi số tiền đều phải đi qua service layer. Web, trợ lý AI và các tác vụ định kỳ chỉ là bên gọi, nên không thành phần nào có thể bỏ qua quy tắc nghiệp vụ hay truy cập dữ liệu của người dùng khác.
  • Bảo đảm trợ lý AI đủ an toàn để xử lý nghiệp vụ tiền tệ: AI chỉ gọi được các service sẵn có, không tự quyết định thao tác trên tài khoản của ai, mỗi hành động chỉ thực thi một lần kể cả khi request bị gửi lại; model được lựa chọn qua chấm điểm trên bộ 76 tình huống thay vì đánh giá cảm tính.
  • Xử lý những nghiệp vụ tài chính cá nhân mà nhiều ứng dụng bỏ qua: chu kỳ sao kê thẻ tín dụng, trả góp, khoản vay có lịch trả nợ và dự báo dòng tiền theo tháng; số tiền được tính chính xác bằng kiểu thập phân, các quyết định sản phẩm đều được ghi lại kèm lý do.
  • Vận hành theo chuẩn của một sản phẩm có team: khoảng 3.300 test tự động, bao gồm các luồng end-to-end chạy trên database thật; release có đánh số phiên bản, triển khai lên server riêng có backup; Claude Code làm việc trong khuôn khổ kiến trúc do tôi đặt ra, mọi thay đổi đều được tôi review.

Bài toán

Phần lớn ứng dụng quản lý chi tiêu chỉ dừng ở mức "thu trừ chi". Thực tế tài chính cá nhân ở Việt Nam phức tạp hơn nhiều: lương nhận qua ngân hàng, chi tiêu hằng ngày bằng tiền mặt và ví điện tử, thẻ tín dụng có kỳ sao kê riêng, điện thoại mua trả góp 0%, khoản vay trả hằng tháng. Chili quản lý tất cả trong một nơi, với số dư chính xác đến từng đồng.

Chili đang trong giai đoạn beta tại chili.tlait.online với giao diện tiếng Việt, hiện có 10 người dùng đang sử dụng để quản lý tài chính của chính họ. Tôi phát triển sản phẩm một mình: từ repo trống đến production trong khoảng ba tháng, sau đó phát hành 31 phiên bản trong ba tuần đầu.

Màn hình tổng quan của Chili: tổng số dư của bốn ví, thu chi trong tháng, dự báo dòng tiền tháng này và tiến độ ngân sách
Tổng quan: số dư các ví, dự báo dòng tiền trong tháng và tiến độ ngân sách.

Phạm vi

  • Đủ loại ví, kể cả thẻ tín dụng có kỳ sao kê và trả góp.
  • Giao dịch, ngân sách theo tháng, mục tiêu tiết kiệm, các khoản nợ và khoản vay kèm lịch trả.
  • Dự báo dòng tiền trong tháng, báo cáo theo tháng và theo năm.
  • Trợ lý AI chuyển câu mô tả hoặc ảnh chụp màn hình thành giao dịch.

Kiến trúc

Monorepo dùng pnpm + Turborepo. web và api đều import shared, nhưng không import lẫn nhau.

packages/shared   Zod schemas · types · enums · error codes   (không phụ thuộc gói nào)
       ▲                         ▲
apps/web                    apps/api
React 19 + Vite             Express 5
React Router 7              Controller → Service → Repository
TanStack Query              Prisma 7 → PostgreSQL

Mỗi nhóm chức năng của API (wallets, transactions, budgets, …) gồm controller xử lý HTTP, service chứa quy tắc nghiệp vụ, và repository là lớp duy nhất làm việc với Prisma. Production gồm ba container Docker trên một VPS: Caddy, API và PostgreSQL.

Danh sách giao dịch của Chili: bộ lọc theo loại, ví, danh mục và tháng, kèm tổng số tiền của kết quả lọc
Giao dịch: lọc theo loại, ví, danh mục và thời gian, kèm tổng tiền của kết quả lọc.

Các quyết định kỹ thuật chính

Mọi thứ đều đi qua service layer

Web, trợ lý AI và các tác vụ định kỳ đều gọi chung một bộ method của service, và mọi method đều kiểm tra quyền sở hữu dữ liệu của người dùng. Vì vậy AI không có đường truy cập riêng vào database: nó chỉ là một bên gọi service như các bên khác.

AI chỉ làm phiên dịch, không có cửa sau

Tool của AI được sinh từ chính các Zod schema dùng chung, nên dữ liệu do AI gửi vào được kiểm tra như dữ liệu nhập từ form. userId luôn lấy từ session, không bao giờ do model truyền vào, và mỗi thao tác chỉ thực thi một lần kể cả khi request bị gửi lại. Ảnh chụp màn hình chỉ được chuyển thành bản nháp; dữ liệu chỉ được lưu sau khi người dùng xác nhận.

Hệ thống dùng một model mã nguồn mở do tôi tự host bằng Ollama, nên dữ liệu tài chính của người dùng không đi qua bất kỳ dịch vụ AI bên thứ ba nào. Model được lựa chọn dựa trên điểm số với bộ 76 câu nhập tiếng Việt, chẳng hạn "ăn trưa 50k tiền mặt", thay vì cảm nhận qua vài lần thử.

Một schema, kiểm tra ở cả hai đầu

Cùng một bộ Zod schema kiểm tra dữ liệu ở client và kiểm tra lại ở server, nên form, API và tool của AI không thể lệch nhau. Lỗi trả về cũng theo một định dạng thống nhất, nhờ đó giao diện chỉ ra chính xác quy tắc nào bị vi phạm.

Tiền và thời gian: không chấp nhận sai số

Số tiền được lưu bằng Decimal(19, 4) và truyền đi dưới dạng chuỗi, không bao giờ dùng float của JavaScript. Ngày tháng tính theo múi giờ Asia/Ho_Chi_Minh, nên kỳ sao kê hay tháng ngân sách không bị lệch chỉ vì server chạy giờ UTC.

Trang ngân sách tháng 10/2026 của Chili: ba ngân sách, số đã chi, số còn lại và thanh tiến độ
Ngân sách: xem theo từng tháng, mỗi ngân sách gồm nhiều danh mục.

Mỗi quy tắc được test một lần, ở tầng thấp nhất đủ để chứng minh

Unit test bao phủ quy tắc nghiệp vụ và component. Integration test chạy service trên PostgreSQL thật để kiểm tra rollback, race condition và lock. Playwright chỉ dùng cho những gì cần cả trình duyệt, API và database cùng chạy, như số dư, chuyển tiền giữa các ví và trọn một tháng sử dụng.

Trang báo cáo của Chili: so sánh thu chi theo tháng và biểu đồ tròn về chi tiêu theo danh mục
Báo cáo: thu chi theo tháng, so với kỳ trước, và cơ cấu chi tiêu theo danh mục.

Làm một mình nhưng vận hành như một team

Khi làm một mình, không có ai khác phát hiện những gì tôi bỏ sót, vì vậy quy trình được văn bản hóa:

  • Lát cắt nhỏ, làm trọn vẹn. Mỗi tính năng chỉ phát hành khi đã hoàn chỉnh, kèm ghi chú trong changelog.
  • Quyết định có văn bản. Những lựa chọn quan trọng đều được ghi lại kèm lý do.
  • Release được kiểm tra. CI chạy type check, lint, hơn 3.000 unit test, build và test end-to-end trên database thật. Database được backup mỗi đêm.
  • AI làm việc có khuôn khổ. Tôi sử dụng Claude Code trong khuôn khổ các quy tắc kiến trúc và kiểm thử do tôi xây dựng, và trực tiếp review mọi thay đổi.

Từ Pocketly đến Chili

Chili là bản viết lại. Bản đầu tiên, Pocketly (Next.js, Server Actions, Prisma, đầu năm 2026), đã kiểm chứng được logic tài chính, nhưng quy tắc nghiệp vụ nằm lẫn trong phần xử lý request, nên ngoài giao diện không có cách nào khác để thay đổi số tiền một cách an toàn. Chili tách quy tắc nghiệp vụ thành một API riêng xoay quanh service layer, và tính đến trợ lý AI ngay từ khâu thiết kế.

← Tất cả dự án