| ledger_account_id | string, UUID, 🔒 system | ✅ Yes | unique; generated by gen_random_uuid() on INSERT | — | Public stable identifier for the ledger account. Use this in all API references; the internal pk is never exposed. |
| account_number | string | ✅ Yes | max length 20; PARTIAL UNIQUE on (workspace_pk, account_number) WHERE deleted_at IS NULL (index idx_ledger_accounts_workspace_account_number_active_unique); the legacy non-partial UNIQUE constraint was replaced by Migration20260529100000 | — | The chart-of-accounts code for this account within the workspace, e.g. ‘411000’ (PCG), ‘1200’ (IFRS). Uniqueness is enforced only among active (non-deleted) rows to allow re-creation after a soft-delete. |
| name | string | ✅ Yes | max length 255 | — | Human-readable display name for the ledger account. |
| account_type | enum (ledger_account_type_enum) | ✅ Yes | non-nullable; native PostgreSQL enum | ASSET | LIABILITY | EQUITY | REVENUE | EXPENSE | Broad accounting classification per the double-entry model. Drives debit/credit sign convention in journal entries and determines which financial statement section the account appears in. |
| account_class | integer | ✅ Yes | CHECK (account_class >= 1 AND account_class <= 9); composite index (workspace_pk, account_class) | 1 – 9 | Numeric account class (plan comptable class digit). Used to group accounts in chart-of-accounts views and as a fast filter for trial-balance queries. Indexed together with workspace_pk. |
| is_auxiliary | boolean | ✅ Yes | default false | true | false | Indicates whether this account carries an auxiliary (counterparty) dimension. When true, auxiliary_type must be set and journal entry lines on this account must reference a counterparty company. |
| auxiliary_type | enum (auxiliary_type_enum) | ⚪ No | nullable; native PostgreSQL enum; required in practice when is_auxiliary = true | CUSTOMER | SUPPLIER | EMPLOYEE | The counterparty dimension type for auxiliary accounts. CUSTOMER = accounts receivable style, SUPPLIER = accounts payable style, EMPLOYEE = payroll/expense style. |
| is_active | boolean | ✅ Yes | default true | true | false | Whether the account is currently open for posting. Inactive accounts remain in the chart for historical reporting but should be excluded from new posting selection lists. |
| description | string | ⚪ No | nullable; TEXT (unbounded) | — | Optional free-text description or instructions for use. Populated by the connector sync when the source accounting tool provides an account note. |
| created_at | Date, 🔒 system | ✅ Yes | set once on INSERT via MikroORM onCreate hook; TIMESTAMPTZ NOT NULL DEFAULT now() | — | Timestamp of row creation. Never modified after insert. |
| updated_at | Date, 🔒 system | ✅ Yes | TIMESTAMPTZ NOT NULL DEFAULT now() per migration; set on INSERT and on every UPDATE via MikroORM onUpdate hook | — | Timestamp of last modification. The database column is NOT NULL (baseline migration defines it as TIMESTAMPTZ NOT NULL DEFAULT now()). Updated automatically on every PATCH/flush. |
| deleted_at | Date | null, 🔒 system | ⚪ No | nullable; soft-delete sentinel; all queries must filter WHERE deleted_at IS NULL | — | Soft-delete timestamp. When non-null the row is logically deleted. Hard deletes are never performed. The partial unique index on (workspace_pk, account_number) ignores rows where deleted_at IS NOT NULL, so a previously deleted account number can be re-created. |