Tất cả dự án
Đang chạy

Spendly

Web app thu chi cá nhân cho freelancer và người thu nhập không đều — ghi một khoản chỉ trong vài giây kiểu Locket, và trả lời câu hỏi “số tiền đang có trụ được mấy ngày?” thay vì ép lập ngân sách tháng. Dùng tốt trên cả điện thoại lẫn máy tính.

Thời gian05/2026 - nowCông nghệ
  • React 19
  • Vite
  • TanStack Router
  • TanStack Query
  • Tailwind CSS 4
  • PWA
  • Astro
  • NestJS
  • Prisma
  • PostgreSQL
  • Redis
  • BullMQ
  • Zod
  • AWS S3
  • Web Push
  • payOS
Spendly

Điểm nổi bật

  • Ghi một khoản thu/chi trong vài giây: chụp ảnh, nhập số tiền là xong — nhanh như đăng một tấm Locket.
  • Tiền vào là tiêu được ngay, không phải “chuyển ví” hay lập kế hoạch trước.
  • Quên ghi vài hôm cũng không sao — ghi bù nhiều khoản một lúc, chọn đúng ngày và giờ đã tiêu.
  • Biết số tiền đang có còn trụ được bao nhiêu ngày, tính từ chính thói quen chi tiêu của bạn.
  • Đặt mục tiêu nếu muốn: mục tiêu thu nhập (đã kiếm được bao nhiêu, bao giờ chạm đích) hoặc mục tiêu sinh tồn (mỗi ngày nên tiêu bao nhiêu). Không đặt cũng không sao.
  • Không phán xét: tiêu vượt chỉ đổi màu nhắc nhẹ, không bao giờ chặn bạn ghi.
  • Nhật ký ảnh theo từng ngày và thống kê chi tiêu theo danh mục.
  • Nhắc nhẹ qua thông báo, hộp thư trong app và email khi lâu chưa ghi hoặc khi tiền sắp cạn.
  • Dùng mượt trên cả điện thoại lẫn máy tính, cài lên màn hình chính như một app.

Về dự án

Spendly là dự án cá nhân tôi làm từ tháng 5/2026 và vẫn đang phát triển tiếp; trang giới thiệu chạy tại spendly.liqwy.com, app tại spendly-app.liqwy.com.

Bài toán đến từ người thu nhập không đều: tháng cao, tháng gần như bằng 0 — với họ câu hỏi “tháng này tiêu bao nhiêu?” vô nghĩa. Câu hỏi đúng là: “số tiền đang có trụ được mấy ngày?”. Spendly trả lời bằng chính những gì người dùng ghi lại hằng ngày.

Phiên bản đầu từng chia tiền vào 3 ví: tiền mới vào phải nằm im ở ví tiết kiệm, muốn tiêu phải chủ động chuyển sang ví khác, kèm chuỗi ngày giữ kỷ luật. Làm kỹ hơn, tôi nhận ra Spendly là app ghi chép chứ không phải app ép kế hoạch — nên khi kế hoạch trở thành tuỳ chọn, các rào cản đó cũng mất lý do tồn tại. Giờ chỉ còn một ví tiền thật, thu vào là tiêu được ngay.

Mục tiêu cũng không bắt đặt từ ngày đầu, vì người mới chưa có dữ liệu để biết mình nên tiêu bao nhiêu. App chỉ mời khi đã có thể nói điều cụ thể, kiểu: “Hai tuần qua bạn tiêu trung bình 180.000đ mỗi ngày. Với số tiền đang có, bạn trụ được khoảng 47 ngày.”

Ban đầu Spendly chỉ nhắm tới điện thoại; giờ giao diện đã chạy tốt trên cả máy tính, có gói Free và PRO.

Góc kỹ thuật

  • Frontend là monorepo gồm app Vite + React 19 + TanStack Router/Query (PWA, responsive) và landing Astro tĩnh. Backend NestJS + Prisma + PostgreSQL.
  • Tiền lưu bằng decimal thay vì float, truyền qua API dạng chuỗi, mọi mốc ngày nghiệp vụ tính theo giờ Việt Nam — vì sai tiền không báo lỗi mà chỉ âm thầm lệch.
  • Mọi thay đổi số dư nằm trong một DB transaction và ghi vào ledger bất biến — trigger PostgreSQL chặn sửa/xoá dòng ledger.
  • Job chạy mỗi đêm tự kiểm bất biến “số dư = tổng thu − tổng chi”, lệch là báo động thay vì đợi người dùng phát hiện.
  • Ảnh upload thẳng lên storage tương thích S3 qua presigned URL, không đi qua server; bucket private, đọc qua presigned GET có hạn.
  • Worker BullMQ chạy riêng: nhắc ghi chép, cảnh báo runway, nhắc target và dọn dẹp định kỳ; thông báo đi 3 kênh Web Push, inbox trong app và email.
  • Auth bằng access token ngắn hạn + refresh token lưu DB để thu hồi được; phân quyền Role–Permission khớp theo path + method, mặc định cấm.
  • Redis cho cache và rate limit dùng chung giữa nhiều instance; Redis sập thì API vẫn phục vụ thay vì trả lỗi 500.
  • Zod schema là nguồn sự thật của API contract — FE parse response bằng zod để bắt lệch shape giữa BE và FE.
  • Thanh toán gói PRO qua payOS.

Bạn có câu hỏi?

Tôi luôn sẵn sàng hợp tác với những dự án thú vị và sáng tạo!

Điện thoại0834 564 869