Weave your money story โ ใ้ใฎ็ฉ่ชใ็ถดใใ
Tsuzuru (็ถดใ) is a Zen-inspired, minimalist personal finance manager modeled after the traditional Japanese Kakeibo (ๅฎถ่จ็ฐฟ) budgeting method. Built with Next.js, Prisma, and Framer Motion, it offers a seamless, offline-first, and highly aesthetic interface to record, analyze, and master your monthly cash flows.
- ๐ Zen-inspired Minimalist Design: Premium aesthetics featuring clean layouts, smooth micro-animations, custom dark mode, and card structures that bring peace of mind to expense tracking.
- ๐ Offline-First PWA Capabilities: Fully installable as a Progressive Web App (PWA) on Mobile and Desktop. Log transactions on-the-go offline, which are automatically synced to the server once your connection is restored.
- ๐ต Smart Multi-Currency Ledger: Native support for JPY (ยฅ) and IDR (Rp) tracking. View individual account balances (Cash, Banks, E-Wallets, Investments) and total assets separated clearly.
- ๐ Kakeibo Budget Limits: Define a monthly expected budget and custom spending categories (e.g. Pocket Money, Shopping). Instantly view remaining limits on the dashboard. Categories are fully customizable.
- ๐ Micro-animated Interactivity: Fluid number transitions using physics-based spring animations (
Framer Motion) that roll up/down dynamically as account balances adjust. - ๐๏ธ One-Click Recurring Bills: Create monthly template schedules (Rent, Utilities, SIM Cards) and record payments with a single tap.
- โก Advanced Analytics: Interactive bar charts and category donut charts powered by
Recharts, complete with custom tooltips and pocket-money meal stats. - ๐ค AI Receipt Parsing: Scan or paste receipt text/images and have Gemini AI automatically extract items and prices โ with per-user rate limiting.
- ๐ Split Bill Tracker: Track shared expenses with friends (who owes whom), and settle bills with automatic account balance adjustments.
- ๐ Fixed Bill Reminders: Flag a recurring bill as fixed-amount with a known due day, and get a real Web Push browser notification the day before it's due (driven by a Vercel Cron job).
- ๐ฆ Budget Threshold Alerts: Proactive toast warnings when a spending category crosses 80%/100% of its monthly limit, instead of a passive progress bar only.
- โ๏ธ Balance Reconciliation: Explicit "reconcile balance" flow to align an account's recorded balance with its real-world value, logged as an auditable adjustment transaction.
- ๐ Email/Password Auth: Sign in with Google or a standalone email + password account (bcrypt-hashed), side by side via NextAuth Credentials provider.
- Framework: Next.js 16 (App Router, Server Actions, API Routes)
- Database ORM: Prisma 7 with PostgreSQL (via
@prisma/adapter-pgconnection pool) - Authentication: NextAuth.js v5 (Google Sign-In + email/password via Credentials provider, JWT sessions)
- Styles & Layout: TailwindCSS v4 & Shadcn UI
- Animation: Framer Motion & Tabler Icons
- Charts: Recharts
- AI: Gemini API (receipt parsing, per-user rate limit stored in DB)
- Testing: Vitest with mocked repositories (no DB required)
- State & Sync: Service Workers (PWA) & LocalStorage Sync Queue
The project follows a strict layered architecture to enforce user data isolation:
Client Component / Page
โ
Server Action (lib/actions/*.ts) โ auth() check, userId from session only
โ
Service (services/*.ts) โ business logic, ownership verification
โ
Repository (repositories/*.ts) โ Prisma queries, always scoped by userId
โ
PostgreSQL (Neon)
Key security invariants:
- Every Server Action validates the session before doing anything.
userIdis always taken fromsession.user.idโ never from client parameters.- Repository queries always include
userIdin thewhereclause.
Make sure you have Node.js (v18+) and Bun installed.
-
Clone the Repository:
git clone https://github.com/your-username/tsuzuru.git cd tsuzuru -
Install Dependencies:
bun install
-
Set Up Environment Variables: Create a
.envfile in the root directory:DATABASE_URL="postgresql://user:password@localhost:5432/tsuzuru" NEXTAUTH_SECRET="your-nextauth-secret-key" # Google OAuth Credentials GOOGLE_CLIENT_ID="your-google-client-id" GOOGLE_CLIENT_SECRET="your-google-client-secret" # Gemini AI (for receipt parsing) GEMINI_API_KEY="your-gemini-api-key" # Web Push (fixed recurring bill reminders) NEXT_PUBLIC_VAPID_PUBLIC_KEY="your-vapid-public-key" VAPID_PRIVATE_KEY="your-vapid-private-key" VAPID_SUBJECT="mailto:you@example.com" # Vercel Cron auth (protects /api/cron/bill-reminders) CRON_SECRET="your-cron-secret"
-
Initialize the Database:
# Generate Prisma client node node_modules/prisma/build/index.js generate # Push schema to database node node_modules/prisma/build/index.js db push
-
Run the Development Server:
bun dev
Open http://localhost:3000 on your browser.
Tests are written with Vitest and run entirely with mocked repositories โ no real database connection needed.
bun run test # run all tests once
bun run test:watch # watch mode for development
bun run test:coverage # generate coverage reportTest suites cover:
- Service layer: ownership enforcement, business rule validation (e.g. cannot delete
monthlybudget, cannot settle another user's bill) - Server Actions: auth enforcement on every action, session
userIdalways wins over client input
Tsuzuru registers a custom Service Worker that intercepts network requests, caching static assets and API payloads to enable offline capabilities:
- Offline Entry: If offline, transactions are pushed into a LocalStorage queue named
tsuzuru_offline_transactions. - Auto-Sync: The
PwaRegistercomponent registers awindow.addEventListener("online")event that flushes the queued transactions to the backend database server as soon as connection recovers.
Recurring bill templates can be flagged as fixed-amount with a due day (isFixedAmount / fixedDueDay). A daily Vercel Cron job hits /api/cron/bill-reminders (configured in vercel.json, guarded by the CRON_SECRET bearer token), which finds bills due the next day that haven't been paid yet this cycle and sends a Web Push notification via web-push to every subscribed device. The service worker (public/sw.js) handles the push/notificationclick events, and users opt in from Settings โ Profile โ Fixed Bill Reminders.
This project is licensed under the MIT License.