Added license and readme

This commit is contained in:
2026-04-29 22:23:04 -07:00
parent 0cbc98c82b
commit 2ab7c8d97a
2 changed files with 157 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Kevin Riehl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+136
View File
@@ -0,0 +1,136 @@
# TehRiehlBudget
A self-hosted personal finance application for tracking spending, balances, and net worth across all of your accounts — checking, savings, credit, loans, and investments — with manual transaction entry, receipt uploads, and a conversational AI advisor running entirely on your own hardware.
Deployed at `budget.tehriehldeal.com`.
## Features
- **Accounts** — track checking, savings, cash, credit cards, loans, stocks, brokerage, and retirement accounts. Drag-to-reorder, per-account history, and a balance integrity check that reverses counter-party transfers when an account is deleted.
- **Transactions** — record income, expenses, and transfers between accounts. Filter by account, category, type, and date. Attach receipt images. Edit, delete, and bulk-export to CSV.
- **Activity history** — every create / update / delete is recorded with a snapshot, so deleted transactions and accounts remain auditable for as long as you need them. Filter by entity, action, account, or date range.
- **CSV export** — pull a date-ranged transaction set out as CSV from the global list or scoped to a single account, with quick-range presets (last 30/60/90 days, this year, all time) plus custom start/end pickers.
- **Confirmation guards** — every destructive action prompts before running, with light/dark mode parity.
- **AI advisor** — a "financial buddy" that summarizes your month against last month and answers follow-ups. Runs against a local Ollama model — no transaction data leaves your network.
- **Dashboards** — net worth and total debt at a glance, spending-by-category pie, monthly cash flow bar chart, and per-account balance history with overlaid valuations.
- **Receipts** — store receipt images on your own filesystem, never on a third-party blob store.
- **Field-level encryption** — sensitive columns (account numbers, transaction notes) are AES-256-GCM encrypted at rest.
## Tech Stack
- **Frontend** — React 19 + TypeScript, Vite, TailwindCSS + ShadCN UI, Zustand, Recharts, React Router
- **Backend** — NestJS (TypeScript), REST, Prisma ORM
- **Database** — PostgreSQL (Dockerized for local dev)
- **Auth** — Supabase (email/password + OAuth, JWT-validated on the backend)
- **AI** — Ollama (self-hosted; defaults to `llama3`)
- **File storage** — local filesystem on the self-hosted server
- **Package manager** — pnpm workspaces
## Project Structure
```
tehriehlbudget/
├── tehriehlbudget-frontend/ # React + Vite app
├── tehriehlbudget-backend/ # NestJS API + Prisma schema
├── docker-compose.yml # Postgres for local dev
├── pnpm-workspace.yaml
└── package.json # Workspace-level scripts
```
## Prerequisites
- Node.js 20+
- pnpm 9+
- Docker (for local Postgres)
- A Supabase project (for auth) — free tier is fine
- An Ollama server reachable from the backend (local or LAN) for the AI advisor
## Quick Start
```bash
# Clone and install
git clone <your-fork-url>
cd tehriehlbudget
pnpm install
# Start local Postgres
docker-compose up -d
# Configure the backend
cp tehriehlbudget-backend/.env.example tehriehlbudget-backend/.env
# Edit .env to set DATABASE_URL, SUPABASE_*, ENCRYPTION_KEY, OLLAMA_URL, OLLAMA_MODEL
# Apply database migrations
pnpm --filter tehriehlbudget-backend prisma migrate deploy
pnpm --filter tehriehlbudget-backend prisma generate
# Configure the frontend
cp tehriehlbudget-frontend/.env.example tehriehlbudget-frontend/.env
# Edit .env to set VITE_API_URL and VITE_SUPABASE_*
# Run both servers (in separate terminals)
pnpm dev:backend
pnpm dev:frontend
```
The frontend is served at `http://localhost:5173` and the API at `http://localhost:3000`.
### Required environment variables
**Backend** (`tehriehlbudget-backend/.env`)
| Variable | Description |
| --- | --- |
| `DATABASE_URL` | Postgres connection string |
| `SUPABASE_URL` | Your Supabase project URL |
| `SUPABASE_SERVICE_ROLE_KEY` | Service-role key (used to validate JWTs) |
| `ENCRYPTION_KEY` | 32-byte hex key for AES-256-GCM field encryption |
| `OLLAMA_URL` | URL of your Ollama server (e.g. `http://localhost:11434`) |
| `OLLAMA_MODEL` | Ollama model id (e.g. `llama3.2:latest`) |
**Frontend** (`tehriehlbudget-frontend/.env`)
| Variable | Description |
| --- | --- |
| `VITE_API_URL` | Backend URL (e.g. `http://localhost:3000`) |
| `VITE_SUPABASE_URL` | Supabase project URL |
| `VITE_SUPABASE_ANON_KEY` | Supabase anon (publishable) key |
## Common Commands
```bash
# Run dev servers
pnpm dev:frontend
pnpm dev:backend
# Build
pnpm build:frontend
pnpm build:backend
# Tests
pnpm test # both packages
pnpm test:backend # Jest
pnpm test:frontend # Vitest
pnpm test:coverage # both, with coverage
# Lint & format
pnpm lint
pnpm format
# Prisma
pnpm --filter tehriehlbudget-backend prisma migrate dev
pnpm --filter tehriehlbudget-backend prisma studio
```
## Architecture Notes
- **Field-level encryption.** A NestJS interceptor encrypts sensitive columns on write and decrypts on read using AES-256-GCM. The plaintext only ever exists in memory inside the request handler.
- **Receipt storage.** Images are stored on the server's local filesystem. The backend issues access-controlled URLs for upload and retrieval — there is no S3 / external blob store.
- **Balance integrity on delete.** When an account is deleted, related transfers' counter-party balances are reversed inside the same Prisma `$transaction` *before* the cascade fires, so a surviving account never reflects a transfer that no longer exists.
- **Audit log.** `ActivityLog` rows capture create / update / delete actions for transactions, accounts, and account valuations. For account deletions the per-transaction snapshots are written before the cascade so the trail outlives the data.
- **AI advisor.** The advisor builds a per-request snapshot of standing balances, monthly flow numbers, and top spending categories, strips PII, and sends it to Ollama. The prompt explicitly separates point-in-time balances from monthly flow and instructs the model to never invent equations or derive new figures — your transaction data does not leave your network.
- **Auth.** Supabase issues JWTs; protected routes on both ends validate them. Sessions are persisted client-side via Supabase's SDK.
## License
[MIT](./LICENSE)