Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.wellapp.ai/llms.txt

Use this file to discover all available pages before exploring further.

A Journal (record root: journals) represents a named accounting book used to categorize and post financial entries within a workspace — for example, a Sales journal, a Bank journal, or a Miscellaneous journal. It is the top-level organizational unit for double-entry bookkeeping, grouping JournalEntry records beneath it, and optionally carrying default debit/credit LedgerAccount references to pre-fill lines on new entries. Journals are workspace-scoped, soft-deleted, and provisioned either manually or by the financial-pipeline sync (via sourceWorkspaceConnector); the source_entity_id field is the stable provider-side identifier used for idempotent upserts during sync.
NamingValue
ObjectJournal
Resource type (JSON:API type)journal
Collection / records rootjournals
REST base/v1/journals
Entity classJournal

API operations

OperationMethod & pathStatus
ListGET /v1/journals✅ Implemented
RetrieveGET /v1/journals/{id}✅ Implemented
CreatePOST /v1/journals🟡 Planned
UpdatePATCH /v1/journals/{id}🟡 Planned
DeleteDELETE /v1/journals/{id}🟡 Planned

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
journal_idstring, UUID, 🔒 system✅ YesUNIQUE; generated via gen_random_uuid() on insertPublic stable identifier for the journal, exposed in all API responses. Generated server-side; never writable by the client.
codestring✅ Yesmax length 10; UNIQUE(workspace_pk, code) — plain unique constraint on all rows including soft-deleted ones, enforced at the database level; mirrored by @Unique({ properties: [‘workspace’, ‘code’] }) on the entityShort alphanumeric book code assigned by the workspace or imported from the accounting provider (e.g. ‘VT’ for sales, ‘BQ’ for bank, ‘OD’ for miscellaneous). Must be unique per workspace across all rows.
namestring✅ Yesmax length 255Human-readable display label for the journal (e.g. ‘Ventes — Clients France’, ‘Banque Qonto EUR’).
journal_typeenum (journal_type_enum)✅ YesNOT NULL; mapped to PostgreSQL native enum journal_type_enumBANK, SALES, PURCHASES, MISC, OPENING, CLOSINGAccounting classification of the journal. BANK: cash/bank movement book. SALES: receivables and revenue. PURCHASES: payables and expenses. MISC: catch-all for adjustments. OPENING/CLOSING: period-boundary entries.
source_entity_idstring⚪ Nonullable; max length 255 (varchar(255) in DDL); PARTIAL UNIQUE INDEX journals_workspace_source_entity_id_unique on (workspace_pk, source_entity_id) WHERE source_entity_id IS NOT NULL AND deleted_at IS NULL — ensures idempotent upserts per provider without conflicting on NULLStable identifier assigned by the originating financial provider (e.g. Pennylane journal ID). Used by the sync pipeline for deduplication/upsert. NULL for manually created journals.
is_activeboolean✅ YesDEFAULT true; indexed (idx_journals_is_active)true, falseWhether the journal is currently in use. Inactive journals are hidden from accounting entry creation flows but remain queryable for historical reporting.
created_atDate, 🔒 system✅ YesNOT NULL DEFAULT now(); set once via MikroORM onCreate lifecycle hook; not writable by clientISO 8601 timestamp of record creation.
updated_atDate, 🔒 system✅ YesNOT NULL DEFAULT now(); set via MikroORM onCreate + onUpdate lifecycle hooks; not writable by clientISO 8601 timestamp of the last modification. Always set at insert time via DEFAULT now(); refreshed on every ORM flush that touches this entity.
deleted_atDate⚪ Nonullable; soft-delete sentinel — all active queries must predicate deleted_at IS NULLISO 8601 timestamp set when the journal is soft-deleted. NULL means the record is active. Hard deletes are not supported.

Relationships

NameTypeRequiredDescription
workspaceto-one (workspace)✅ YesThe tenant workspace that owns this journal. All queries must scope to the authenticated workspace; the combination (workspace_pk, code) carries a plain UNIQUE constraint enforcing per-workspace code uniqueness. References core_api.workspaces.
default_debit_accountto-one (ledger_account)⚪ NoOptional default LedgerAccount pre-filled as the debit leg when creating new JournalEntry lines under this journal. Indexed (idx_journals_default_debit_account). References core_api.ledger_accounts.
default_credit_accountto-one (ledger_account)⚪ NoOptional default LedgerAccount pre-filled as the credit leg when creating new JournalEntry lines under this journal. References core_api.ledger_accounts.
source_workspace_connectorto-one (workspace_connector)⚪ NoThe WorkspaceConnector sync instance that created or last reconciled this journal record. NULL for manually created journals. Used for provenance tracking and to identify connector-managed records that should not be edited manually. References core_api.workspace_connectors.

System-computed

  • journal_id is generated server-side via PostgreSQL gen_random_uuid() (defaultRaw) and mirrored in the ORM entity initializer randomUUID(). Never supplied by the client.
  • created_at is set once by the MikroORM onCreate lifecycle hook at insert time. The database column is NOT NULL DEFAULT now(). Not writable by the client.
  • updated_at is set by both onCreate and onUpdate MikroORM lifecycle hooks. The database column is NOT NULL DEFAULT now(), so it is always populated from the moment of insert. Reflects the timestamp of the last ORM flush touching this entity.
  • deleted_at is null on active records. Set to the current timestamp on soft-delete. All repository queries must include deleted_at: null as a filter predicate.
  • The combination (workspace_pk, code) carries a plain database-level UNIQUE constraint (defined in the DDL as UNIQUE(workspace_pk, code) and mirrored by @Unique({ properties: ['workspace', 'code'] }) on the entity). This constraint applies to all rows, including soft-deleted ones.
  • source_entity_id carries a PARTIAL UNIQUE INDEX journals_workspace_source_entity_id_unique on (workspace_pk, source_entity_id) WHERE source_entity_id IS NOT NULL AND deleted_at IS NULL. This enables idempotent upserts by the financial sync pipeline without conflicting on NULL values for manually created journals.
  • sourceWorkspaceConnector (→ source_workspace_connector_pk FK column) is set by the ingestion pipeline when a journal is created via connector sync (e.g. Pennylane). NULL indicates manual creation. Presence signals that the record is pipeline-owned and should not be edited without understanding sync implications. A partial index idx_journals_source_wc on (source_workspace_connector_pk) WHERE source_workspace_connector_pk IS NOT NULL supports provenance queries.
  • Journals are reachable from a Company via the Hasura computed field company_journals(company_row, hasura_session), which traverses the 3-hop path: companies → journal_entry_lines (company_pk) → journal_entries (journal_entry_pk) → journals (journal_pk). No direct company_pk FK exists on the journals table itself.
  • is_active defaults to true at creation. The pipeline or a workspace admin may flip it to false to retire a journal while preserving historical entries.

Example

{
  "data": {
    "type": "journal",
    "id": "a3f1c2d4-7e8b-4a9c-b5f6-0d1e2f3a4b5c",
    "attributes": {
      "journal_id": "a3f1c2d4-7e8b-4a9c-b5f6-0d1e2f3a4b5c",
      "code": "VT",
      "name": "Ventes — Clients France",
      "journal_type": "SALES",
      "source_entity_id": "pnl_jnl_00042",
      "is_active": true,
      "created_at": "2026-01-15T09:23:11.000Z",
      "updated_at": "2026-03-04T14:07:55.000Z",
      "deleted_at": null
    },
    "relationships": {
      "workspace": {
        "data": { "type": "workspace", "id": "d5e6f7a8-b9c0-4d1e-a2f3-b4c5d6e7f8a9" }
      },
      "default_debit_account": {
        "data": { "type": "ledger_account", "id": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e" }
      },
      "default_credit_account": {
        "data": { "type": "ledger_account", "id": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f" }
      },
      "source_workspace_connector": {
        "data": { "type": "workspace_connector", "id": "e3f4a5b6-c7d8-4e9f-a0b1-c2d3e4f5a6b7" }
      }
    }
  }
}
Source: apps/api/src/database/entities/Journal.ts · domain: financial-graph · tier: Main