Skip to main content
A LedgerAccount represents a single line in a workspace’s chart of accounts (CoA), classified by accounting type (ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE) and grouped into account classes 1–9. It is the foundational node of the accounting graph: invoice items, journal entry lines, and workspace posting mappings all FK into it. Ledger accounts may be arranged in a parent–child hierarchy (one self-referential ManyToOne), and they can be marked as auxiliary (linked to a customer, supplier, or employee counterparty dimension). The connector sync pipeline writes ledger accounts from external accounting tools (Xero, Pennylane, etc.) and stamps each row with source_workspace_connector_pk for provenance tracking.

API operations

Data model

Attributes

Relationships

System-computed

  • ledger_account_id is generated by PostgreSQL gen_random_uuid() on INSERT and also seeded in-process via randomUUID() from Node crypto as the MikroORM default; it is unique and immutable.
  • created_at is set once via MikroORM onCreate lifecycle hook (new Date()); never written again.
  • updated_at is set on CREATE and on every UPDATE via MikroORM onUpdate lifecycle hook. The database column is NOT NULL (TIMESTAMPTZ NOT NULL DEFAULT now() per Migration20260306100000); the MikroORM entity declares it optional (updated_at?: Date) but that only affects TypeScript nullability — the DB enforces NOT NULL.
  • deleted_at is null on creation; set to now() by the application (never by the database) to perform a soft-delete. The partial unique index idx_ledger_accounts_workspace_account_number_active_unique (WHERE deleted_at IS NULL) ensures uniqueness only among active rows — soft-deleted rows are excluded, allowing re-insertion of the same (workspace_pk, account_number) pair after a soft-delete.
  • The non-partial UNIQUE(workspace_pk, account_number) constraint from Migration20260306100000 was dropped by Migration20260529100000_ledger_accounts_dedup_unique_idx. That migration also deduped existing active duplicates (keeping the earliest pk) before building the partial index.
  • source_workspace_connector_pk is set by the connector sync pipeline (MCP / Xero / Pennylane / etc.) to record provenance. It is NULL for manually created accounts and is SET NULL (not cascade-deleted) when the workspace_connector row is removed. Column and partial index added by Migration20260406100000_expand_mcp_sync_models.
  • account_class is a human-supplied classification digit (1–9) enforced by a CHECK constraint in the database; it is not derived.
  • is_auxiliary defaults to false; auxiliary_type defaults to NULL. The pipeline or user must explicitly set both when creating an auxiliary account.
  • is_active defaults to true; setting it to false deactivates the account without soft-deleting it, preserving historical journal entry lines.
  • The (workspace_pk, account_class) composite index (idx_ledger_accounts_workspace_class) and the (workspace_pk, parent_account_pk) composite index (idx_ledger_accounts_workspace_parent) are created by Migration20260306100000 and are transparent to the application layer.

Example

Source: apps/api/src/database/entities/LedgerAccount.ts · domain: financial-graph · tier: Main