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.
WorkspacePostingMapping encodes a single posting rule that maps a semantic document context (CoA version, semantic role, posting kind, document polarity) to accounting targets (LedgerAccount, TaxRate, Journal) for a workspace. The posting engine writes these rows deterministically or via LLM review; the rule-resolver reads them at journal-entry draft time to auto-classify postings. Each row is scoped to a Workspace and optionally to a specific WorkspaceConnector, with precision modifiers for tax behaviour, counterparty kind, currency, country code, and effective date range. A partial unique index (WHERE deleted_at IS NULL AND mapping_status = ‘active’) prevents duplicate active mappings for the same context tuple.
| Naming | Value |
|---|
| Object | WorkspacePostingMapping |
Resource type (JSON:API type) | workspace_posting_mapping |
| Collection / records root | — (not a records root) |
| REST base | /v1/workspace-posting-mappings |
| Entity class | WorkspacePostingMapping |
Internal object. Not currently exposed on the public REST API. The operations below describe the intended contract.
API operations
| Operation | Method & path | Status |
|---|
| List | GET /v1/workspace-posting-mappings | 🟡 Planned |
| Retrieve | GET /v1/workspace-posting-mappings/{id} | 🟡 Planned |
| Create | POST /v1/workspace-posting-mappings | 🟡 Planned |
| Update | PATCH /v1/workspace-posting-mappings/{id} | 🟡 Planned |
| Delete | DELETE /v1/workspace-posting-mappings/{id} | 🟡 Planned |
Data model
Attributes
| Field | Type | Required | Constraints | Allowed values | Description |
|---|
| workspace_posting_mapping_id | string (UUID) | ✅ Yes | UNIQUE | — | Public UUID identifying this posting rule. Generated via gen_random_uuid() on insert. |
| well_coa_version | string | ✅ Yes | max length 32 | — | Version tag of the Well Chart-of-Accounts taxonomy this mapping targets (e.g. ‘v2024’). |
| well_semantic_role | string | ✅ Yes | max length 100 | — | Semantic accounting role within the CoA taxonomy (e.g. ‘accounts_payable’, ‘revenue_product’). |
| posting_kind | string | ✅ Yes | max length 50 | — | Kind of source document or transaction driving the posting (e.g. ‘invoice’, ‘bank_transaction’). |
| document_polarity | string | ✅ Yes | max length 50 | — | Polarity direction of the posting line: whether this rule applies to the debit or credit leg. |
| tax_behavior | string | null | ⚪ No | max length 50 | — | Optional tax inclusion modifier narrowing the rule (‘exclusive’, ‘inclusive’, ‘none’). NULL means the rule applies regardless of tax behaviour. |
| counterparty_kind | string | null | ⚪ No | max length 50 | — | Optional counterparty classification narrowing the rule (e.g. ‘supplier’, ‘customer’). NULL matches any counterparty kind. |
| currency | string | null | ⚪ No | max length 3 | — | Optional ISO 4217 currency code narrowing the rule. NULL matches any currency. |
| country_code | string | null | ⚪ No | max length 2 | — | Optional ISO 3166-1 alpha-2 country code narrowing the rule. NULL matches any country. |
| effective_from | date | null | ⚪ No | CHECK: effective_from <= effective_to when both non-NULL | — | Inclusive start date from which this rule is effective. NULL means no lower bound. Used in the partial-unique active-context index via COALESCE. |
| effective_to | date | null | ⚪ No | CHECK: effective_from <= effective_to when both non-NULL | — | Exclusive end date after which this rule is no longer effective. NULL means open-ended. |
| mapping_status | 🔒 system — enum (WorkspacePostingMappingStatusEnum) | ✅ Yes | default: ‘active’; native enum workspace_posting_mapping_status_enum | active | needs_review | inactive | Lifecycle state of this mapping rule. The partial unique index on active-context enforces one active rule per context tuple. Managed by the posting engine. |
| confidence | string (decimal 4,3) | null | ⚪ No | CHECK: value IS NULL OR (value >= 0 AND value <= 1); decimal(4,3) | — | Confidence score in [0.000, 1.000] assigned by the LLM jury or deterministic engine. Stored as decimal(4,3); exposed as string in JSON to preserve precision. |
| evidence | object (JSONB) | null | ⚪ No | — | — | Free-form JSONB payload recording why this mapping was created (matched patterns, rule sources, jury rationale). Shape varies by created_by value. |
| created_by | 🔒 system — enum (WorkspacePostingMappingCreatedByEnum) | ✅ Yes | default: ‘deterministic’; native enum workspace_posting_mapping_created_by_enum | deterministic | manual | reviewed_llm | Provenance of this mapping: whether it was produced by a deterministic rule, manual human edit, or an LLM that was subsequently reviewed. |
| mapping_version | 🔒 system — integer | ✅ Yes | default: 1 | — | Monotonically increasing version counter incremented by the posting engine on each rule revision. Default 1. |
| created_at | 🔒 system — datetime | ✅ Yes | — | — | Timestamp when this mapping was created. Set automatically via onCreate hook. |
| updated_at | 🔒 system — datetime | null | ⚪ No | — | — | Timestamp of the last update to this mapping. Set automatically via onUpdate hook. |
| deleted_at | 🔒 system — datetime | null | ⚪ No | — | — | Soft-delete timestamp. Non-null means the mapping is logically deleted and excluded from the partial unique active-context index. All queries must filter deleted_at IS NULL. |
Relationships
| Name | Type | Required | Description |
|---|
| workspace | to-one (ManyToOne) | ✅ Yes | The Workspace this posting rule belongs to. All queries must scope by workspace_pk. Indexed as part of the role and status composite indexes. |
| sourceWorkspaceConnector | to-one (ManyToOne) | ⚪ No | Optional WorkspaceConnector that provided the data driving this rule. NULL means the rule applies generically across all connectors for this workspace. ON DELETE SET NULL — deleting the connector nullifies but does not delete the mapping. |
| ledger_account | to-one (ManyToOne) | ⚪ No | Target LedgerAccount to post to for this context. NULL is valid when the rule’s primary purpose is to select only a TaxRate or Journal without specifying a ledger account. |
| tax_rate | to-one (ManyToOne) | ⚪ No | Target TaxRate to apply when posting. NULL means no tax rate is assigned by this mapping; the posting engine may inherit or default. |
| journal | to-one (ManyToOne) | ⚪ No | Target Journal (accounting book) to route journal entries into. NULL defers journal selection to the posting engine’s default resolution logic. |
System-computed
- workspace_posting_mapping_id — generated via gen_random_uuid() on insert, exposed as the public API id
- created_at — set automatically by the MikroORM onCreate hook; never writable after creation
- updated_at — set automatically by the MikroORM onUpdate hook on every write
- deleted_at — soft-delete field written by the posting engine on rule retirement; not writable by users
- mapping_status — managed exclusively by the posting engine (transitions: active → needs_review → inactive or active → deleted_at); default ‘active’ on creation
- mapping_version — incremented by the posting engine on each rule revision; default 1
- created_by — set at creation time by the engine to record provenance (‘deterministic’, ‘reviewed_llm’) or set to ‘manual’ for human-authored rules; not subsequently editable
- confidence — computed and stamped by the LLM jury or deterministic scoring logic; null for fully-deterministic rules
- evidence — populated by the engine with the reasoning payload from the mapping generation run
- sourceWorkspaceConnector provenance — when set, records which connector sync triggered the mapping creation; ON DELETE SET NULL ensures orphan safety on connector removal
- Partial unique index workspace_posting_mappings_active_context_unique (WHERE deleted_at IS NULL AND mapping_status = ‘active’) — enforced at the DB layer only; cannot be expressed via MikroORM decorators (COALESCE expressions + partial predicate). The entity comment documents this divergence from schema:fresh.
Example
{
"data": {
"type": "workspace_posting_mapping",
"id": "a3f1c2e4-8b7d-4f9a-b2c1-0d5e6f7a8b9c",
"attributes": {
"workspace_posting_mapping_id": "a3f1c2e4-8b7d-4f9a-b2c1-0d5e6f7a8b9c",
"well_coa_version": "v2024",
"well_semantic_role": "accounts_payable",
"posting_kind": "invoice",
"document_polarity": "debit",
"tax_behavior": "exclusive",
"counterparty_kind": "supplier",
"currency": "EUR",
"country_code": "FR",
"effective_from": "2024-01-01",
"effective_to": null,
"mapping_status": "active",
"confidence": "0.950",
"evidence": {
"rule_source": "deterministic_coa_bootstrap",
"matched_patterns": ["vat_fr_20", "supplier_invoice"]
},
"created_by": "deterministic",
"mapping_version": 1,
"created_at": "2025-05-25T10:00:00.000Z",
"updated_at": "2025-05-25T10:00:00.000Z",
"deleted_at": null
},
"relationships": {
"workspace": {
"data": { "type": "workspace", "id": "b1c2d3e4-0000-0000-0000-000000000001" }
},
"source_workspace_connector": {
"data": null
},
"ledger_account": {
"data": { "type": "ledger_account", "id": "c9d8e7f6-0000-0000-0000-000000000002" }
},
"tax_rate": {
"data": { "type": "tax_rate", "id": "d1e2f3a4-0000-0000-0000-000000000003" }
},
"journal": {
"data": null
}
}
}
}
Source: apps/api/src/database/entities/WorkspacePostingMapping.ts · domain: financial-graph · tier: Infrastructure