4.0 KiB
4.0 KiB
External Integrations
Database: PostgreSQL 16
Location: backend/internal/db/db.go, backend/internal/db/queries.go
Connection
- Driver:
github.com/jackc/pgx/v5(pgx connection pool) - Default URL:
postgres://simplefin:simplefin@localhost:5432/simplefindb?sslmode=disable - Environment Variable:
DATABASE_URL - Connection Pool:
pgxpool.Poolwith automatic management
Schema
Tables (from backend/migrations/001_initial.sql):
- users — id (UUID), email, password_hash, oidc_subject, display_name, preferred_locale, timestamps
- categories — id (UUID), user_id (FK), name, type (enum), icon, sort_order, timestamps
- budgets — id (UUID), user_id (FK), name, start_date, end_date, currency, carryover_amount, timestamps
- budget_items — id (UUID), budget_id (FK), category_id (FK), budgeted_amount, actual_amount, notes, timestamps
- schema_migrations — version tracking
Enum: category_type — bill, variable_expense, debt, saving, investment, income
Numeric precision: NUMERIC(12, 2) in PostgreSQL, shopspring/decimal in Go
Migration Runner
- Custom implementation in
backend/internal/db/db.go - Reads
.sqlfiles from embedded filesystem (embed.FS) - Tracks applied versions in
schema_migrationstable - Sequential numbering:
001_initial.sql,002_..., etc.
Authentication
Local Auth (Active)
Location: backend/internal/auth/auth.go
- Password hashing: bcrypt with
DefaultCost - Session: JWT (HS256) in HTTP-only cookie
- Secret:
SESSION_SECRETenvironment variable - Token TTL: 7 days
- Cookie: HttpOnly, SameSite=Lax, MaxAge=7 days
Routes:
POST /api/auth/register— Create accountPOST /api/auth/login— LoginPOST /api/auth/logout— Clear cookieGET /api/auth/me— Current user
OIDC (Planned, Not Implemented)
Location: backend/internal/api/handlers.go (stubs returning 501)
- Routes:
GET /api/auth/oidc,GET /api/auth/oidc/callback - Environment variables defined in
compose.yml:OIDC_ISSUER,OIDC_CLIENT_ID,OIDC_CLIENT_SECRET - DB support ready:
oidc_subjectcolumn,GetUserByOIDCSubject(),UpsertOIDCUser()queries
CORS
Location: backend/internal/api/router.go
AllowedOrigins: ["http://localhost:5173", "http://localhost:8080"]
AllowedMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
AllowedHeaders: ["Content-Type"]
AllowCredentials: true
Frontend API Client
Location: frontend/src/lib/api.ts
- Base URL:
/api(proxied tohttp://localhost:8080via Vite in dev) - Uses native Fetch API with
credentials: 'include' - Custom
ApiErrorclass for error handling - Typed endpoints:
auth.*,categories.*,budgets.*,budgetItems.*,settings.*
Internationalization (i18n)
Location: frontend/src/i18n/
- Library: i18next + react-i18next
- Languages: English (en, default), German (de)
- Keys: ~87 per language (auth, navigation, dashboard, budget, categories, settings)
- User preference: Stored in DB (
preferred_localecolumn)
Deployment
Docker (Multi-stage Build)
Location: Dockerfile
- Stage 1 (bun): Build frontend →
frontend/dist - Stage 2 (golang:1.24-alpine): Build Go binary with embedded frontend + migrations
- Stage 3 (alpine): Runtime with
ca-certificates, port 8080
Docker Compose
Location: compose.yml
- app: Go server (:8080), depends on db
- db: PostgreSQL 16 (:5432), health check,
pgdatavolume
Environment Variables
| Variable | Purpose | Required |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Yes |
SESSION_SECRET |
JWT signing secret | Yes (production) |
OIDC_ISSUER |
OIDC provider URL | No (future) |
OIDC_CLIENT_ID |
OIDC client ID | No (future) |
OIDC_CLIENT_SECRET |
OIDC client secret | No (future) |
External Services
None currently integrated. No third-party APIs, webhooks, payment processors, email providers, or message queues.