Gandzi (from Georgian 🇬🇪 განძი, "treasure") is a self-hosted personal finance management application built as privacy-by-default and local-first. The product is intentionally manual-entry first so users keep explicit control over every financial decision and every data point. Think of it as an Excel on steroids for personal finance: domain-driven workflows, stronger guardrails, richer analytics, and simulation engines, while still preserving transparency and user ownership. External market/banking/API connectors are part of the roadmap, but never at the expense of explicit user control.
Build a trustworthy financial cockpit that lets users:
- Track budgets month-by-month over each civil year.
- Monitor financial wealth, gross wealth, and net wealth precisely.
- Visualize spending and wealth trends with high-quality charts.
- Model real-estate ownership and fixed-rate mortgages.
- Run compound-interest and wealth-projection simulations (including Monte Carlo).
- Import/export all personal data in a transparent way.
- Hexagonal architecture (domain isolated from frameworks).
- TDD-first delivery.
- Privacy-by-design + privacy-by-default + GDPR-by-default.
- Local-first and self-hosted first, Docker-ready.
- Manual entry first by design to keep explicit user control.
- Public OSS project under Apache-2.0.
- Annual budgets split by month with year navigation (previous/next year).
- Per-year independent data storage via Pinia budget store.
- Budget dimensions: by category and by account.
- Rollover support month to month.
- Civil year as default period.
- Default alert threshold at 80% (configurable).
- Email notification channel configurable for budget alerts.
- Financial wealth, gross wealth, net wealth.
- Manual valuation for now.
- Designed to support future market-data adapters.
- Snapshot frequency configurable: daily, monthly, yearly, on-demand.
- Asset classification support:
- Asset category (e.g. Crypto, Equity, Bond, Cash, Real Estate).
- Holding container/support (e.g. PEA, CTO, Pension, Savings).
- Dedicated chart per wealth type.
- Budget chart with reusable monthly template.
- Effective-expenses chart for selected month or year.
- Filters by period, account, category, wealth type.
- Chart export support.
- Register primary residence with co-ownership share (%).
- Fixed-rate mortgage support.
- Standard monthly amortization schedule.
- Track outstanding principal (capital restant du).
- 3 scenarios (conservative/base/optimistic) + custom fixed rate.
- Duration and expected return inputs.
- Distribution/frequency: monthly, quarterly, yearly.
- Optional recurring contributions.
- Include inflation, income growth, and expense evolution.
- Deterministic mode + Monte Carlo mode.
- Horizon up to 100 years.
- Mandatory double-entry model.
- Manual add/edit/delete operations for expenses, income, wealth adjustments.
- Custom categories allowed.
- Built-in default categories:
- groceries, transport, health, gifts, vacation,
- home insurance, borrower insurance, vehicle insurance,
- taxes, personal care, car maintenance,
- subscriptions, investments (with asset-type subcategories),
- bank fees, mortgage, rent, property tax,
- electricity, gas, water, miscellaneous, leisure.
- JSON and CSV export/import.
- AI-powered import from CSV, Excel (.xlsx/.xls), and ODS files: an LLM parses the file content and maps rows to budget lines automatically, with multi-year and multi-sheet support.
- Import mode: merge or full replace.
- No encryption in V1.
- Export filenames include precise timestamp.
- Java 25
- Kotlin 2.x
- Spring Boot 4.0.3
- Gradle (Kotlin DSL)
- jOOQ
- Liquibase
- OAuth2 Resource Server (enabled from day one)
- Hexagonal architecture (
domain,application,ports,adapters)
- Astro
- Vue 3
- Pinia
- Vue-ChartJS
- i18n strategy: lightweight dictionary-based translation layer, English default, with full translations across 12 locales (en, fr, es, de, it, pt, zh, ja, hi, ar, ru, ka). Language selector shows native language names.
- PostgreSQL
- Docker + Docker Compose for local/self-hosted deployment
- GitHub Actions CI from start
- Default UI language: English.
- Frontend ships with a simple extensible locale registry (
en,fr,es,de,it,pt,zh,ja,hi,ar,ru,ka). - Locale can be user-configured and persisted.
- All budget matrix labels (months, headers, row labels) are fully translated.
- Configurable LLM provider in Account Settings: Anthropic, OpenAI, or Google.
- Model selection per provider (Claude Opus/Sonnet 4.6, GPT 5.3/5.4, Gemini 3/3.1).
- API key stored in browser localStorage (backend proxy planned).
- Used for AI-powered budget import: parses uploaded spreadsheets and maps data to budget lines.
Supported currencies in V1:
- EUR, USD, JPY, CNY, INR, GBP, CHF
Default timezone:
Europe/Paris(user-configurable)
- Data minimization by default.
- Explicit purpose limitation in domain services.
- User data export + delete capabilities planned as first-class use-cases.
- Clear separation between operational, analytics, and audit data.
- Strict adapter boundaries to prevent domain leakage.
- TDD required for all feature increments.
- One feature per commit (Conventional Commits).
- Strong domain tests + adapter integration tests + frontend component tests.
backend/Kotlin + Spring Boot + Hexagonal + jOOQ + Liquibasefrontend/Astro + Vue + Pinia + Charting + i18ndocs/architecture, GDPR, ADRs.github/workflows/CI workflows
- Docker + Docker Compose
- Java 25
- Node.js 22+
- npm
- Start PostgreSQL
docker compose up -d postgres- Start Keycloak (admin/admin)
docker run --name gandzi-keycloak --rm -p 8081:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:latest start-dev- Configure Keycloak (in browser)
- Open
http://localhost:8081 - Login with
admin/admin - Create realm:
gandzi - Create client:
- Client ID:
gandzi-frontend - Type: OpenID Connect
- Access type: Public
- Valid redirect URIs:
http://localhost:4321/* - Web origins:
http://localhost:4321
- Client ID:
- Create one user in realm
gandzi:Users->Add user- Set credentials (password), non-temporary for convenience
- Start backend
cd backend
GRADLE_USER_HOME=/tmp/.gradle-gandzi ./gradlew bootRun- Start frontend
cd frontend
npm install
npm run dev -- --host 0.0.0.0 --port 4321- Open in browser
- Frontend:
http://localhost:4321 - Backend health:
http://localhost:8080/actuator/health - Keycloak admin:
http://localhost:8081
Run stack containers from project root:
docker compose up --buildNotes:
- Current compose includes
postgres,backend, andfrontend. - You still need a Keycloak instance and realm/client/user setup for OAuth2 login.
- You can keep using the Keycloak command from Option A in parallel.
Apache License 2.0.