Skip to content

Repository files navigation

SvelteKit TypeScript Fastify Drizzle ORM SQLite Tailwind CSS Vitest Playwright MIT License

Pockt Logo

Personal Disposable Income & Cash Flow Companion

Pockt is a high-performance, self-hosted personal finance tracker focused on answering the single most important financial question:

"How much money can I safely spend today?"

🌟 Key Highlights

  • Net Disposable Income Engine: Calculates real-time spendable cash by factoring Current Cash - Outstanding Bills - Outstanding Debts.
  • Single-Owner Authentication: First-time setup, cookie-based sessions, and route protection across all pages.
  • Bilingual UI (ID/EN): One-tap language toggle that re-renders the entire app — every page, modal, and label.
  • Hallmark OKLCH Dual Theme System:
    • Bloom (Light): Warm Oat canvas oklch(0.975 0.008 75) with Signal Terracotta accent oklch(0.64 0.18 40).
    • Aurora (Dark): Obsidian Slate canvas oklch(0.14 0.012 250) with Teal Emerald accent oklch(0.74 0.16 170).
  • Side-Rail Compact Navigation (N3 Archetype): Compactable sidebar with logo toggle and 100% monochrome controls.
  • 2-Row Mobile-First Layout: Guaranteed zero horizontal scrollbar or clipped content across all viewports (320px–412px+).
  • Automated Testing Suite: Full API integration testing (Vitest) and End-to-End browser testing (Playwright).

🚀 Features

  • 🔐 Single-Owner Authentication: First-time setup flow creates the owner account; session-based login (cookie) protects all data; logout supported.
  • 📊 Free-to-Spend Dashboard (/dashboard): Instant visibility into net disposable income, monthly stats, and live cashflow timeline.
  • 💰 Payday Allocation View (/payday): Planning matrix for incoming salary vs. upcoming commitments, bills, debts, and spent totals.
  • 📥 Income Tracking (/incomes): Log salary, freelance work, investments, or reimbursements.
  • 💸 Expense Management (/expenses): Category filtering, search, and fast entry under 10 seconds.
  • 📅 Monthly Bills Tracker (/bills): One-click paid/unpaid toggling and automated monthly reset flow.
  • 🤝 Debt & Loan Register (/debts): Installment payment log, remaining balance calculations, and repayment history.
  • ⚡ Quick Add Modal: Record an expense or income from anywhere in the app in seconds.
  • 🌐 Bilingual UI (Bahasa Indonesia / English): Full language toggle applied across every page, modal, and label, persisted to localStorage.
  • 🎨 Dual Theme System: Bloom (Light) and Aurora (Dark) themes with one-click switching.
  • 📁 CSV Data Export: One-click database export for offline reporting and backup.

🛠️ Tech Stack & Monorepo Architecture

pockt/
├── apps/
│   ├── backend/         # Fastify 5 REST API + Drizzle ORM + SQLite + Vitest
│   └── web/             # SvelteKit 5 + Tailwind CSS v4 + Playwright E2E
├── packages/
│   └── shared/          # Shared TypeScript schemas & domain utilities
├── turbo.json           # Turborepo build orchestration
└── pnpm-workspace.yaml  # pnpm workspace configuration

⚙️ Development Guide

1. Install Dependencies

pnpm install

2. Run Development Servers

Starts frontend (http://localhost:5173) and backend (http://localhost:3001):

pnpm dev

3. Production Build

pnpm build

4. Database Files (Dev / Prod / Test Separation)

Pockt uses separate SQLite files so testing never touches your real data:

Environment DB file When used
Development pockt.dev.db pnpm dev (default, NODE_ENV not production)
Production pockt.prod.db Docker deploy / pnpm start with NODE_ENV=production
Backend tests pockt.test.db Vitest (wiped on every run)

The schema auto-creates on server start; you can also run pnpm --filter @pockt/backend db:migrate. Override any path with the DATABASE_URL env var. In Docker, the prod DB lives inside the pockt-db-data volume, and the web container proxies /api to the backend via API_INTERNAL_URL (server-side proxy, no extra reverse proxy needed).

Backups: pnpm --filter @pockt/backend backup writes a WAL-safe snapshot into backups/ next to the DB file (keeps the last 14). In Docker, that lands inside the pockt-db-data volume (/app/apps/backend/data/backups/) — run it regularly (e.g. cron on the host: docker exec pockt-backend pnpm --filter @pockt/backend backup).

5. Owner Account (First-Time Setup)

The app asks you to create the owner account on the /register page when it detects no owner exists. You can also create or reset the owner via CLI:

# Create/reset owner credentials (prompts for username + password)
pnpm --filter @pockt/backend user

Registration is locked once an owner exists (single-owner app). Reset your password with the user CLI command if you ever forget it.

6. Security Model

  • Sessions: login issues a random 256-bit token stored server-side in the sessions table (30-day expiry). The cookie is HttpOnly + SameSite=Lax and gets the Secure flag in production. Logout deletes the row, so stolen cookies die at logout.
  • Rate limiting: login/register are limited to 10 attempts per 15 minutes per IP (honors CF-Connecting-IP behind Cloudflare Tunnel).
  • Fail-closed secret: in production the backend refuses to start without a strong COOKIE_SECRET (placeholder values are rejected).
  • CORS: same-origin only (origin: false); every /api/* route except health/auth validates the session on each request.
  • Password hashing: bcrypt (10 rounds); SQL is parameterized (Drizzle); frontend escapes all output (Svelte).

🧪 Testing Suite

Pockt includes an automated testing suite for both backend APIs and frontend UI viewports. Backend tests run against an isolated pockt.test.db database that is wiped on every run; E2E tests use a global setup that ensures an owner exists and seeds dummy data when empty.

# Run backend API integration tests (17 tests via Vitest, isolated test DB)
pnpm test

# Run frontend E2E layout & responsive tests (33 tests via Playwright, 3 viewports)
pnpm test:web

# Run all backend + frontend tests
pnpm test:all

📜 License

Distributed under the MIT License.

About

Self-hosted personal finance tracker built with SvelteKit, Fastify, and SQLite.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages