A browser UI for financial data generated by finsynth. Browse accounts and transactions by date, with balances calculated from the transaction ledger.
Backend — Bun + Hono. Serves the Vue app in production and exposes two API routes: /api/accounts and /api/transactions. Connects to Postgres via Prisma ORM 8.
Frontend — Vue 3 with Vue Router and Pinia. Styled with Tailwind CSS v4 and DaisyUI v5. Built with Vite.
Database — Postgres 18, running in Docker.
finui/
├── src/
│ ├── index.ts # Bun entrypoint
│ ├── server.ts # Hono app and DB adapter
│ └── frontend/
│ ├── main.ts
│ ├── main.css
│ ├── App.vue
│ ├── router.ts
│ ├── pages/
│ │ ├── Accounts.vue
│ │ └── Transactions.vue
│ ├── stores/
│ │ ├── app.ts
│ │ ├── accounts.ts
│ │ └── transactions.ts
│ ├── components/
│ │ └── icons.ts
│ └── utils/
│ └── format.ts
├── docker/
│ ├── seed.sql # loads CSV from docker/seed/
│ └── seed/
│ └── finsynth_transactions.csv # finsynth output goes here
├── prisma/
│ └── contract.prisma # Prisma 8 data contract
├── generated/prisma/ # emitted contract artifacts
├── migrations/ # Prisma 8 schema migrations
├── tests/
├── docker-compose.yml
├── eslint.config.mjs
├── mise.toml
├── mise.lock
├── vite.config.ts
├── tsconfig.json
└── package.json
This project is managed by mise. It installs the Bun version pinned in mise.toml and mise.lock.
mise install
mise run installCreate a .env file at the project root:
POSTGRES_USER=finui
POSTGRES_PASSWORD=finui
POSTGRES_DB=finui
DATABASE_URL=postgresql://finui:finui@localhost:5432/finuiPut a finsynth-generated CSV into docker/seed/finsynth_transactions.csv. The file should have this shape:
id,date,from_account_id,to_account_id,amount,category,description,is_recurring
7624e641-...,2023-01-01,acc_checking,acc_external,1400.0,rent,Monthly rent,True
mise run db-upThis starts a Postgres 18 container. Apply the Prisma contract and load the CSV explicitly:
mise run db-migrate
mise run db-seedFor an existing database, use mise run db-verify rather than applying the baseline migration.
If you need to reset and reload from scratch:
mise run db-down
docker volume rm finui_postgres_data
mise run db-up| Command | What it does |
|---|---|
mise run install |
Installs Bun dependencies |
mise run dev |
Starts Vite (:5173) and Hono (:3001) in parallel. Vite proxies /api/* to Hono. |
mise run build |
Builds the Vue app into dist/ |
mise run lint |
Runs ESLint |
mise run test |
Runs Vitest |
mise run typecheck |
Runs the TypeScript compiler |
mise run start |
Builds then serves everything from Hono on :3001 |
mise run db-up |
Starts Postgres with Docker Compose |
mise run db-down |
Stops Postgres with Docker Compose |
mise run db-psql |
Opens psql with docker exec |
mise run db-migrate |
Applies pending Prisma 8 migrations |
mise run db-seed |
Loads the finsynth CSV into PostgreSQL |
mise run db-verify |
Verifies the database against the Prisma contract |
mise run contract-emit |
Regenerates the Prisma contract artifacts |
mise run check |
Runs the current Definition of Done: lint, test, then build |
During development, open http://localhost:5173. The Hono server on :3001 only matters for mise run start.
Edit prisma/contract.prisma, then run mise run contract-emit. For schema changes, review the migration generated by bunx prisma migration plan --name <change> before applying it with mise run db-migrate. Commit the contract artifacts and migration files.
Returns all accounts with their balance as of the given date.
| Param | Default | Description |
|---|---|---|
date |
today | Calculate balances up to and including this date (YYYY-MM-DD) |
Returns transactions in ascending date order.
| Param | Default | Description |
|---|---|---|
date |
— | Return only transactions on or after this date |
limit |
12 |
Number of rows to return |
page |
1 |
Page number (1-indexed) |