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.

JournalEntryPostingAttempt is an append-only audit ledger that records every attempt to post a double-entry journal entry from a source document (invoice, invoice_transaction, or bank transaction). One row is written per attempt — persisted or halted — so that human-driven retries never overwrite prior halt reasons and the full posting history is preserved. It is workspace-scoped and carries actor metadata (system vs user) together with a nullable reference to the People who triggered a manual retry. The table is the authority for why a journal entry was or was not created for a given source document.
NamingValue
ObjectJournalEntryPostingAttempt
Resource type (JSON:API type)journal_entry_posting_attempt
Collection / records root(not a records root)
REST base/v1/journal-entry-posting-attempts
Entity classJournalEntryPostingAttempt
Internal object. Not currently exposed on the public REST API. The operations below describe the intended contract.

API operations

OperationMethod & pathStatus
ListGET /v1/journal-entry-posting-attempts🟡 Planned
RetrieveGET /v1/journal-entry-posting-attempts/{id}🟡 Planned
CreatePOST /v1/journal-entry-posting-attempts🟡 Planned
UpdatePATCH /v1/journal-entry-posting-attempts/{id}🟡 Planned
DeleteDELETE /v1/journal-entry-posting-attempts/{id}🟡 Planned

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
journal_entry_posting_attempt_idstring (UUID) 🔒 system✅ YesUNIQUEPublic UUID identifier for this posting attempt. Generated by gen_random_uuid() on insert. This is the value exposed as the JSON:API resource id.
source_kindenum (JournalEntryPostingAttemptSourceKindEnum)✅ YesNative Postgres enum: journal_entry_posting_attempt_source_kind_enum. NOT NULL.invoice | invoice_transaction | transactionIdentifies the type of source document that triggered the posting attempt. ‘invoice’ = invoice-driven JE; ‘invoice_transaction’ = legacy per-bridge-row trigger (D9, preserved for backward compat); ‘transaction’ = D9.1 per-bank-transaction payment-settlement JE.
source_idstring✅ YesVARCHAR(64), NOT NULLPublic UUID string of the source row (invoice_id, invoice_transaction_id, or transaction_id). Stored as VARCHAR(64) rather than a typed FK so new source kinds do not require schema changes.
source_pkinteger⚪ NoINTEGER, NULLABLEInternal integer PK of the source row for fast joins when the source kind is known. Nullable because legacy attempt rows pre-dating the D9.1 migration may not have this populated.
statusenum (JournalEntryPostingAttemptStatusEnum)✅ YesNative Postgres enum: journal_entry_posting_attempt_status_enum. NOT NULL.persisted | haltOutcome of this posting attempt. ‘persisted’ = a journal entry was written; ‘halt’ = posting was blocked (see reason/details). Halts never roll back the source document.
reasonstring⚪ NoVARCHAR(100), NULLABLEShort machine-readable reason code for a halt (e.g. ‘missing_mapping’, ‘polarity_conflict’). Free-string rather than enum because halt reasons span multiple subsystems and are expected to grow. NULL on status=persisted.
detailsstring⚪ NoVARCHAR(500), NULLABLEHuman-readable explanation of the halt reason, providing context for the operator reviewing the audit trail. NULL on status=persisted.
idempotency_keystring⚪ NoVARCHAR(160), NULLABLEIdempotency key passed to the journal entry persister. Set on status=persisted; null on status=halt. Allows the persister to detect duplicate attempts and avoid double-writing JEs.
line_countinteger⚪ NoINTEGER, NULLABLENumber of journal entry lines written when status=persisted. Null on status=halt. Useful for sanity-checking multi-line JEs (e.g. AR/AP lines per counterparty).
createdboolean⚪ NoBOOLEAN, NULLABLETrue when a new journal entry was created; false when an existing one was updated/reused via the idempotency key. Null on status=halt.
attempted_atDate (timestamptz)✅ YesTIMESTAMPTZ, NOT NULLWall-clock timestamp at which the posting was attempted. Used as the DESC sort key in the latest-per-source and timeline indexes. Stored as TIMESTAMPTZ.
attempted_by_kindenum (JournalEntryPostingAttemptActorKindEnum)✅ YesNative Postgres enum: journal_entry_posting_attempt_actor_kind_enum. NOT NULL. DEFAULT ‘system’.system | userWhether the attempt was triggered by an automated pipeline (‘system’) or by an explicit human action such as a manual retry after fixing a classification (‘user’). Defaults to ‘system’.
created_atDate 🔒 system✅ YesTIMESTAMP, NOT NULL, DEFAULT now()Row creation timestamp. Set by the onCreate hook; never user-editable.
updated_atDate 🔒 system⚪ NoTIMESTAMP, NULLABLELast modification timestamp. Set by onUpdate hook. Nullable per entity declaration.
deleted_atDate 🔒 system⚪ NoTIMESTAMP, NULLABLESoft-delete timestamp. NULL means the row is active. Used in the workspace-status composite index to keep halted-attempt dashboard queries efficient.

Relationships

NameTypeRequiredDescription
workspaceto-one (ManyToOne)✅ YesThe workspace this posting attempt belongs to. All queries must filter by workspace_pk for tenant isolation. References core_api.workspaces(pk).
journal_entryto-one (ManyToOne, nullable)⚪ NoThe journal entry that was written on a successful (persisted) attempt. NULL on status=halt. References core_api.journal_entries(pk).
attempted_byto-one (ManyToOne, nullable)⚪ NoThe People record of the user who triggered a manual retry when attempted_by_kind=‘user’. NULL when attempted_by_kind=‘system’. References core_api.peoples(pk).

System-computed

  • journal_entry_posting_attempt_id — generated by gen_random_uuid() on insert; never user-supplied
  • created_at — set by MikroORM onCreate hook (new Date()); immutable after creation
  • updated_at — set by MikroORM onUpdate hook on every flush
  • deleted_at — soft-delete; set by repository-layer soft-delete helpers; not set by the application layer on normal posting flows
  • attempted_by_kind defaults to JournalEntryPostingAttemptActorKindEnum.SYSTEM (‘system’) when not explicitly provided
  • source_kind native enum extended via Migration20260526030000 to include ‘transaction’ for D9.1 payment-settlement attempts; ‘invoice_transaction’ retained for backward compat with pre-D9.1 rows

Example

{
  "data": {
    "type": "journal_entry_posting_attempt",
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "attributes": {
      "source_kind": "invoice",
      "source_id": "inv_7e2f3a1b-4c5d-6e7f-8a9b-0c1d2e3f4a5b",
      "source_pk": 10482,
      "status": "halt",
      "reason": "missing_mapping",
      "details": "No ledger account mapping found for category 'operating_expense' in chart of accounts version 3.",
      "idempotency_key": "inv_7e2f3a1b-4c5d-6e7f-8a9b-0c1d2e3f4a5b:attempt:3",
      "line_count": null,
      "created": null,
      "attempted_at": "2026-05-26T14:23:11.000Z",
      "attempted_by_kind": "system",
      "created_at": "2026-05-26T14:23:11.000Z",
      "updated_at": "2026-05-26T14:23:11.000Z",
      "deleted_at": null
    },
    "relationships": {
      "workspace": {
        "data": { "type": "workspace", "id": "ws_00000000-0000-0000-0000-000000000001" }
      },
      "journal_entry": {
        "data": null
      },
      "attempted_by": {
        "data": null
      }
    }
  }
}
Source: apps/api/src/database/entities/JournalEntryPostingAttempt.ts · domain: financial-graph · tier: Infrastructure