life-docs/features/finance.md
2026-03-20 09:32:20 -07:00

7.6 KiB

Feature — Finance

Unified financial tracking with encrypted amounts, recurring transactions, budget targets, billable entries, monthly summaries, and cash flow projections.


Schema

financial_entries

Column Type Constraints Description
id uuid PK
type varchar(10) NOT NULL income or expense
date date NOT NULL
amount_encrypted bytea NOT NULL Encrypted amount
currency varchar(3) default 'USD'
category varchar(30) NOT NULL
description varchar(255) nullable Plaintext (expenses only)
description_encrypted bytea nullable Encrypted (income only)
domain_id uuid FK → domains.id, nullable
project_id uuid FK → projects.id, nullable, ON DELETE CASCADE
recurring_transaction_id uuid FK → recurring_transactions.id, nullable Link to recurring source
contact_id uuid nullable
duration_minutes integer nullable For time-based income
notes text nullable

Indexes: type, date, category, domain_id, project_id, recurring_transaction_id

recurring_transactions

Column Type Constraints Description
id uuid PK
type varchar(10) NOT NULL income or expense
name varchar(255) NOT NULL
amount_encrypted bytea NOT NULL
currency varchar(3) default 'USD'
category varchar(30) NOT NULL
day_of_month integer NOT NULL
domain_id uuid FK → domains.id, nullable
project_id uuid FK → projects.id, nullable, ON DELETE CASCADE
is_active boolean default true
notes text nullable

Indexes: type, category, domain_id

budget_targets

Column Type Constraints Description
id uuid PK
month varchar(7) NOT NULL YYYY-MM or default
category varchar(30) NOT NULL
limit_encrypted bytea NOT NULL Encrypted budget limit
currency varchar(3) default 'USD'
domain_id uuid FK → domains.id, nullable
notes text nullable

Indexes: (month, category), domain_id Unique: (month, category, domain_id)

billable_entries

Column Type Constraints Description
id uuid PK
domain_id uuid NOT NULL
project_id uuid FK → projects.id, NOT NULL, ON DELETE CASCADE
contact_id uuid nullable
date date NOT NULL
title varchar(255) NOT NULL
description text nullable
amount numeric(12,2) NOT NULL Plaintext (not encrypted)
currency varchar(3) default 'USD'
duration_minutes integer nullable
status varchar(20) default 'pending' pending, invoiced, paid
due_date date nullable
paid_date date nullable

Indexes: domain_id, project_id, contact_id, date, status


API

Method Endpoint Description
GET /api/finance/summary Monthly summary (?month=YYYY-MM, ?domainId=)
GET /api/finance/projection Cash flow projection (?months=)
GET /api/finance/trend Monthly trend data (?months=)
GET /api/finance/entries List entries (paginated, ?type=, ?domainId=, ?category=, ?dateStart=, ?dateEnd=, ?contactId=)
POST /api/finance/entries Create financial entry
PATCH /api/finance/entries/:id Update entry
DELETE /api/finance/entries/:id Delete entry
GET /api/finance/recurring List recurring transactions (?type=)
POST /api/finance/recurring Create recurring transaction
PATCH /api/finance/recurring/:id Update recurring
DELETE /api/finance/recurring/:id Delete recurring
POST /api/finance/recurring/:id/mark-paid Create entry from recurring for month { month }
GET /api/finance/targets List budget targets (?month=)
POST /api/finance/targets Create budget target
PATCH /api/finance/targets/:id Update target
DELETE /api/finance/targets/:id Delete target
GET /api/finance/billable List billable entries (paginated, ?domainId=, ?projectId=, ?status=, ?dateStart=, ?dateEnd=)
POST /api/finance/billable Create billable entry
PATCH /api/finance/billable/:id Update billable
DELETE /api/finance/billable/:id Delete billable

Summary Response

{
  "month": "2026-03",
  "incomeTotal": "4500.00",
  "expenseTotal": "2100.00",
  "projectedExpenseTotal": "2800.00",
  "recurringExpenseTotal": "1200.00",
  "recurringIncomeTotal": "0.00",
  "oneTimeExpenseTotal": "900.00",
  "balance": "2400.00",
  "projectedBalance": "1700.00",
  "currency": "USD",
  "changePercentage": 12.5,
  "recurringTransactions": [{ "id": "...", "name": "...", "isPaid": true }],
  "expensesByCategory": [{ "category": "food", "total": "600.00", "budgetLimit": "800.00", "percentUsed": 75.0 }],
  "incomeBySource": [{ "sourceType": "session", "total": "4500.00", "count": 12 }],
  "incomeByDomain": [{ "domain": { "id": "...", "name": "Work" }, "total": "4500.00" }],
  "projection": { "estimatedIncome": "4200.00", "trend": "stable" }
}

Backend Module

FinanceModule — imports DomainsModule (via Domain entity).

Services:

  • FinanceService — CRUD for financial entries with encryption/decryption via EncryptionService
  • RecurringTransactionService — recurring transaction management, mark-paid (creates entry with idempotency check)
  • BudgetTargetService — budget targets with default fallback for unconfigured months
  • FinanceSummaryService — monthly summary aggregation, trend calculation, 3-month trailing projection
  • BillableService — billable entry CRUD with status tracking (pending/invoiced/paid)

Business rules:

  • All monetary amounts are encrypted at rest via EncryptionService (except billable entries which use plaintext numeric)
  • Income entry descriptions are encrypted; expense descriptions are plaintext
  • Mark-paid is idempotent: throws ConflictException if recurring already paid for the month
  • Budget targets support default month as template; month-specific targets override defaults
  • Summary computes projected expenses = actual expenses + unpaid recurring still expected
  • Projection uses 3-month trailing average for estimated income/expenses
  • Domain auto-resolution: if projectId provided without domainId, resolves via ProjectResolverService

Frontend

Routes

  • /finance — Finance dashboard with summary, entries, recurring, targets

Components

  • FinancePage — Main finance dashboard
  • FinanceModals — Create/edit modals for entries, recurring, targets

Data (hooks)

const { summary, entries, recurring, targets, billable, createEntry, markPaid } = useFinance();

Key Interactions

  • View monthly summary with income vs expense breakdown
  • Track recurring transactions and mark them paid each month
  • Set budget targets per category and track percent used
  • View spending trend over configurable months
  • Manage billable entries with status workflow (pending → invoiced → paid)

Implementation Phase

Phase 2 (Core Features) — FinanceModule, encrypted storage, budget targets, summary aggregation.