| account_balance_id | string, UUID | ✅ Yes | unique; defaultRaw: gen_random_uuid() | — | Public stable identifier for this balance snapshot. Used in all API responses and external references. Never expose the internal pk. |
| accounting_balance | object (JSONB), nullable | ⚪ No | JSONB; all sub-fields documented below | — | Bank-reported balance figures for this period. Contains four monetary fields (opening_booked, opening_value, closing_booked, closing_value) and the ISO-4217 currency code. closing_booked and closing_value may be null for open (current) periods. |
| accounting_balance.opening_booked | number | ⚪ No | JSONB sub-field; display_type: amount | — | Booked (settled) opening balance for the period in the account’s currency. |
| accounting_balance.opening_value | number | ⚪ No | JSONB sub-field; display_type: amount | — | Value (including pending) opening balance for the period. |
| accounting_balance.closing_booked | number | null | ⚪ No | JSONB sub-field; display_type: amount; null for open periods | — | Booked closing balance at the end of the period. Null when balance_at_to is null (current open period). |
| accounting_balance.closing_value | number | null | ⚪ No | JSONB sub-field; display_type: amount; null for open periods | — | Value closing balance at the end of the period. Null when balance_at_to is null. |
| accounting_balance.currency | string | ⚪ No | JSONB sub-field; display_type: unique_key; ISO-4217 3-letter code | — | ISO-4217 currency code for all monetary figures within this accounting_balance object. |
| foreign_exchange | array of objects (JSONB), nullable | ⚪ No | JSONB array; each element has currency_rate, currency_pair, currency_rate_source, currency_rate_at | — | Optional array of FX rate snapshots applied to this balance period. Carries the rate, the pair (e.g. EUR/USD), the source (e.g. ECB), and the timestamp of the rate. Populated by connectors that provide multi-currency balance data. |
| foreign_exchange[].currency_rate | number | ⚪ No | JSONB sub-field | — | The exchange rate value for the currency pair at currency_rate_at. |
| foreign_exchange[].currency_pair | string | ⚪ No | JSONB sub-field | — | Currency pair in ISO-4217 slash notation (e.g. EUR/USD). |
| foreign_exchange[].currency_rate_source | string | ⚪ No | JSONB sub-field | — | Source of the exchange rate (e.g. ECB, Plaid, provider-specific). |
| foreign_exchange[].currency_rate_at | string (ISO-8601 timestamp) | ⚪ No | JSONB sub-field | — | Timestamp at which the FX rate was observed or fixed. |
| balance_at_from | string (timestamp), nullable | ⚪ No | columnType: timestamp; display_type: datetime; indexed in idx_account_balances_date_range; also in partial index idx_account_balances_current | — | Start of the validity window for this balance snapshot. Inclusive lower bound of the period. Combined with balance_at_to it defines the interval. Indexed for efficient period range lookups. |
| balance_at_to | string (timestamp), nullable | ⚪ No | columnType: timestamp; display_type: datetime; indexed in idx_account_balances_date_range; null when period is still open (current balance) | — | End of the validity window. Null for the current (open) balance period. The partial index idx_account_balances_current targets rows WHERE balance_at_to IS NULL for fast current-balance lookups. |
| verified_at | string (timestamp), nullable | ⚪ No | columnType: timestamp | — | Timestamp when the reconciliation pipeline last successfully verified this balance period (i.e. sum of transactions matched the closing_booked figure within tolerance). |
| verification_error | boolean, nullable | ⚪ No | nullable boolean | true | false | null | Flag set by the reconciliation pipeline. True when calculated_balance_diff does not equal expected_balance_diff. Null means verification has not yet run for this period. |
| verification_error_detail | string (text), nullable | ⚪ No | type: text | — | Human-readable explanation of the verification failure. Populated only when verification_error is true. Contains the discrepancy detail reported by the reconciliation pipeline. |
| calculated_balance_diff | number (numeric), nullable | ⚪ No | type: numeric(10,0) — integer precision, no decimal places | — | The balance difference computed by the verification pipeline: sum of transaction amounts in the period minus the expected delta between opening and closing booked balances. |
| expected_balance_diff | number (numeric), nullable | ⚪ No | type: numeric(10,0) — integer precision, no decimal places | — | The expected balance difference derived from accounting_balance (closing_booked minus opening_booked). Compared against calculated_balance_diff to detect missing or duplicate transactions. |
| verification_last_run_at | string (timestamp), nullable | ⚪ No | columnType: timestamp | — | Timestamp of the most recent reconciliation pipeline run against this balance period, regardless of outcome. Distinct from verified_at, which is only stamped on success. |
| raw_data | unknown (JSONB), nullable | ⚪ No | JSONB; shape is connector-specific | — | Complete provider-native payload from which this balance was derived (e.g. the full Plaid account/balance JSON response). Shape varies by connector. Preserved for audit and re-processing; not exposed in standard API responses. |
| created_at | string (timestamptz), 🔒 system | ✅ Yes | onCreate: () => new Date(); not null | — | Timestamp when the record was first persisted. Set automatically by the MikroORM onCreate lifecycle hook. |
| updated_at | string (timestamptz), 🔒 system | ⚪ No | onCreate and onUpdate: () => new Date() | — | Timestamp of the last update. Set automatically on create and every subsequent write by the MikroORM onUpdate lifecycle hook. |
| deleted_at | string (timestamptz), nullable | ⚪ No | nullable; soft-delete sentinel; partial index idx_account_balances_current WHERE deleted_at IS NULL | — | Soft-delete timestamp. Null means the record is active. All queries must filter deleted_at IS NULL. Also guards the partial index idx_account_balances_workspace_deleted. |