Skip to content

Database Schema

The database schema is managed using Drizzle ORM and serves as the backbone for the multi-currency financial tracking system.

This document provides a complete reference for all tables, columns, and their specific purposes within the application logic.


Foundation for multi-currency support and user management.

The master dictionary for globally supported currencies (e.g., USD, EUR, JPY).

ColumnTypeConstraintsDescription
codechar(3)PKThe ISO 4217 currency code (e.g., ‘USD’). Used as the primary key and foreign key reference throughout the app.
symboltextNOT NULLThe currency symbol (e.g., ’$’, ’€’) for display purposes.
nametextNOT NULLFull name of the currency (e.g., ‘United States Dollar’).
decimalsintNOT NULLNumber of decimal places commonly used (e.g., 2 for USD, 0 for JPY).

The central entity representing an application user.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique identifier for the user. Referenced by essentially every data table.
nametextNOT NULLThe user’s display name.
emailtextUnique, NOT NULLUser’s email address for login and notifications.
password_hashtextNOT NULLSecurely hashed password (managed by Auth).
currency_preferencetextNOT NULLStores formatting preferences or locale settings for currency display.
main_currency_codechar(3)FK -> currencies.codeCritical: The base currency for the user’s “Net Worth”. All aggregated stats are converted to this currency.
created_attimestampDefault NowTimestamp of account creation.
updated_attimestampDefault NowTimestamp of last profile update.

Stores historical exchange rates between currency pairs. Used to calculate historical net worth and valuations.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID for the rate entry.
source_currencychar(3)FK -> currencies.codeThe currency being converted from.
target_currencychar(3)FK -> currencies.codeThe currency being converted to.
ratenumeric(15,6)NOT NULLThe conversion rate. High precision (6 decimals) to minimize rounding errors.
effective_datetimestampNOT NULLThe date/time for which this rate is valid. The system selects the closest date when performing historical conversions.

Where the money lives.

A normalized list of banks, exchanges, and financial entities.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
nametextNOT NULLName of the institution (e.g., “Chase”, “Coinbase”).
logo_urltext-URL to the institution’s brand icon for UI display.

Represents a specific holding of funds (Bank Account, Wallet, Investment Account) belonging to a user.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
user_idbigintFK -> users.idOwner of the account.
institution_idbigintFK -> institutions.idThe bank this account belongs to. Used to fetch logos/metadata.
nametextNOT NULLUser’s custom name (e.g., “My Savings”).
typetextNOT NULLType discriminator (e.g., savings, checking, credit, investment).
currency_codetextNOT NULLBase Currency: The native currency of this account. All transactions in this account are impactful in this currency.
current_balancenumeric(15,2)NOT NULLCached current balance. Updated largely by transactions.
icon_colortext-UI customization: Hex code for the account card color.
is_included_in_net_worthbooleanDefault TRUEIf false, this account is hidden from total wealth calculations.
is_activebooleanDefault TRUESoft delete flag. If false, account is archived.

The most complex sector, handling double-entry logic, categorization, and transfers.

Hierarchical tree for classifying spending and income.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
user_idbigintFK -> users.idOwner.
parent_idbigintFK -> categories.idSelf-reference. If set, this is a sub-category (e.g., “Groceries” is child of “Food”).
nametextNOT NULLCategory name.
typetextNOT NULLincome or expense. Determines which transaction types it relates to.
icontext-Icon name/code.
icon_slugtext-Identifier for icon libraries.
color_hextext-Color coding for charts.

Normalized entities for Payees (who you pay) and Payers (who pays you).

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
nametextNOT NULLClean name (e.g., “Uber”, “Netflix”).
default_category_idbigintFK -> categories.idSmart feature: When creating a transaction for this merchant, this category is auto-selected (e.g., Netflix -> Entertainment).
logo_urltext-URL for merchant brand logo.

The core ledger. Every inflow and outflow is recorded here.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
user_idbigintFK -> users.idOwner.
account_idbigintFK -> accounts.idThe account impacted by this transaction.
category_idbigintFK -> categories.idClassification of the transaction.
merchant_idbigintFK -> merchants.id”Who” the transaction interacts with. Cleaner than raw descriptions.
amountnumeric(15,2)NOT NULLThe magnitude of the transaction.
currency_codetextNOT NULLCurrency of the amount. Usually matches accounts.currency_code.
transaction_datetimestamptzNOT NULLWhen the transaction occurred.
typetextNOT NULLincome, expense, or transfer.
statustextNOT NULLpending, cleared, reconciled.
notestext-User comments.
attachment_urltext-Link to receipt image/PDF.
exchange_rate_appliednumeric(15,6)-Audit Trail: The specific rate used at the moment of transaction. Critical for multi-currency transfers to lock in the value.
transfer_group_iduuid-Transfer Logic: Groups two related transactions (one withdrawal, one deposit) into a single logical “Transfer”. The system knows that tx_A (Out of Account 1) and tx_B (Into Account 2) are the same event if they share this ID.
location_lat / _lonnumeric-Geotagging coordinates.

Handles complex transactions where a single payment covers multiple categories.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
transaction_idbigintFK -> transactions.idThe parent transaction (totals).
category_idbigintFK -> categories.idThe category for this specific portion of the total.
amountnumeric(15,2)NOT NULLThe amount allocated to this split. Sum of splits should equal parent amount.

Spending limits defined for specific periods.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
user_idbigintFK -> users.idOwner.
category_idbigintFK -> categories.idThe category this budget limits (e.g., “Restaurants”).
limit_amountnumeric(15,2)NOT NULLThe maximum spending target.
periodtextNOT NULLweekly, monthly, yearly.
start_datedateNOT NULLEffective start of budget.
end_datedateNOT NULLEffective end of budget.
rolloverbooleanDefault FALSELogic: If true, unspent money from the previous period is added to the next period’s limit. Excess spending is deducted from next period.

Financial targets for saving.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
user_idbigintFK -> users.idOwner.
nametextNOT NULLName (e.g., “New Car”).
target_amountnumeric(15,2)NOT NULLThe saving goal.
current_amountnumeric(15,2)NOT NULLAmount saved so far.
linked_account_idbigintFK -> accounts.idSmart Goal: If linked, the goal’s current_amount automatically mirrors the balance of this specific account. If null, it’s a “virtual” goal updated manually.
monthly_contributionnumeric(15,2)-Recommended monthly saving to hit target by deadline.
deadline_datedate-Target date to reach goal.
statustextNOT NULLactive, achieved, paused.

Automation engine for repeating transactions.

Note: This table does NOT store transactions. It stores instructions.

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
typetextNOT NULLexpense (Subscription), income (Salary), transfer.
amountnumeric(15,2)NOT NULLThe amount to generate.
frequencytextNOT NULLdaily, weekly, monthly, yearly.
next_execution_datedateNOT NULLThe trigger date. A background job checks this daily. If today >= next_execution_date, it executes the logic and updates this field.
goal_idbigintFK -> goals.idIf present, the rule automatically increases a Goal’s balance (Auto-Save).

Standalone log for calculation history (The “Calculator” feature).

ColumnTypeConstraintsDescription
idbigintPK, IdentityUnique ID.
user_idbigintFK -> users.idOwner.
source_currencytextNOT NULLFrom user input.
target_currencytextNOT NULLFrom user input.
source_amountnumericNOT NULLAmount converted.
target_amountnumericNOT NULLResult amount.
exchange_ratenumericNOT NULLRate used for the calculation.
fee_percentagenumeric-Optional fee simulation.
created_attimestamptzDefault NowLog timestamp.

  1. Users -> Currencies: main_currency_code determines how the user views their entire financial life.
  2. Transactions -> Transfer Group: Linking two transactions (Withdrawal + Deposit) via transfer_group_id allows the system to treat them as a single “Movement” event, preventing double-counting in Expense/Income reports.
  3. Merchants -> Categories: default_category_id enables auto-categorization AI/Automation when selecting a merchant.
  4. Goals -> Accounts: linked_account_id turns a conceptual goal into a real tracking mechanism tied to a physical bank account.