Zero-UI
← Back to docs/Self-Hosted Personal Finance Tracking – Architecture (Actual Budget + SimpleFIN)

Self-Hosted Personal Finance Tracking – Architecture (Actual Budget + SimpleFIN)

Decisions

Core product goals

  • Self-hosted UI that feels like “old school Mint”: fast browsing of transactions, categories, budgets, and net worth.
  • Reliable account connectivity for the household/business footprint: Truist, TD Bank, Chase (multiple), Amex (multiple), plus others as needed.
  • Local intelligence layer for insights (spend trends, anomalies, recurring bills, forecasting) that sits atop the finance dataset without compromising data integrity.

Confirmed decisions

  1. Primary solution = Actual Budget (self-hosted)

    • Actual is the core UI and daily system of record for budgets, categories, payees, transactions.
  2. Primary sync = SimpleFIN Bridge

    • Institutions sync via SimpleFIN; refresh is on-demand/scheduled polling (not push streaming).
  3. Minimize custom code

    • Prefer Actual + SimpleFIN as-is. Add custom components only when justified and keep them isolated.
  4. Optional “insights” sidecar (read-only)

    • Insights are additive and non-destructive (no automatic edits; no credentials). Not a hard dependency.

Failure Modes (Finance)

SimpleFIN / institution sync failures

  • Re-auth required (MFA, session invalidation, OAuth refresh): surface status; keep last-known data; notify operator.
  • Institution outage / aggregator degradation: stagger polling; backoff retries; Actual remains usable.
  • Rate limits / throttling: per-institution schedules; circuit breaker.
  • Partial updates: record sync timestamps per connection; show per-account freshness.

Data correctness failures

  • Duplicate transactions due to changing identifiers: canonical dedupe rules; merge/audit path.
  • Payee normalization conflicts: separate suggested vs locked payees; allow safe revert.
  • Posting date inconsistencies: store/show posted date and cleared semantics when supported.

Infrastructure failures

  • DB/volume corruption or disk full: nightly backups + retention; storage monitoring; test restores.
  • Container restart/upgrades: healthchecks + restart policies; predictable update playbook.
  • Secrets exposure: secrets outside git; avoid plaintext tokens in logs; rotate credentials.

Insights layer failures (non-critical)

  • LLM/analytics errors: insights cite numbers; read-only; disclaim uncertainty. Degrade silently.

Framework

Minimal target architecture

  1. actual-server (Actual Budget): canonical budgeting app + UI
  2. simplefin-bridge (external service): bank/CC connectivity for Actual’s sync integration
  3. reverse-proxy (NPM): TLS termination, hostname, access control via fin.teamlewis.co
  4. backups: automated backup/retention for Actual data volume; encrypted off-host copy

Optional add-ons (kept minimal)

  1. insights-sidecar (optional): periodic export → local Postgres/SQLite; dashboards/notifications
  2. llm-gateway (optional): read-only conversational queries over finance data

Data flow (high level)

  • SimpleFIN → Actual (scheduled on-demand refresh)
  • Actual (primary) → optional export → Insights DB → dashboards/notifications/LLM

Sync scheduling

  • Default: refresh every 6–12 hours + on-demand "Sync now"; institution-specific backoff

Integrations

Confirmed: SimpleFIN → Actual Budget

  • Covers checking/savings and credit cards (as supported).
  • Outputs accounts and transactions into Actual.

Bills/subscriptions

  • Primary: inferred from transaction patterns (recurring detection)
  • Optional: manual bill definitions (merchant + cadence + amount range)

Notifications (optional)

  • Re-auth required; no successful sync >24h; large/unusual charge; upcoming bill renewal

Crypto/brokerages (out-of-scope unless needed later)

  • If needed later: Kraken via read-only API keys; brokerages via separate pipeline if SimpleFIN cannot cover

Intent

What this system is

  • A local-first personal finance stack powered by Actual Budget and SimpleFIN, with optional read-only insights.

What this system is not

  • Not a real-time streaming system; refresh/poll based
  • Not a complex multi-aggregator ingestion platform (unless future requirements force it)
  • Not an autonomous agent changing financial records without explicit user action

Primary user workflows

  1. Link institutions via SimpleFIN
  2. Sync into Actual and confirm accounts
  3. Categorize and create rules
  4. Budget and reconcile
  5. (Optional) Review insights and receive alerts

Naming Conventions (Finance)

Services

  • actual-server, reverse-proxy (nginx-proxy-manager), backup-job
  • Optional: insights-sidecar, analytics-db, llm-gateway

Identifiers and casing

  • snake_case for analytics DB tables; kebab-case for service names; camelCase for JSON payloads

Suggested artifacts (optional add-ons)

  • insights.recurring_items, insights.anomalies, insights.monthly_rollups, insights.merchant_aliases