Policy Structure
A Posting Policy contains all the rules for how a tenant's events get converted to journal entries. The rules_json column stores the configuration.
Key Points
- Each tenant has one default policy (marked
is_default = true) - Multiple policies can exist for different scenarios
- The
PostingRulesstruct is parsed fromrules_json
Category Mappings
Maps categories to their GL accounts. Uses string keys for flexibility: UUIDs for specific categories, or "sales"/"expense" for fallbacks.
{
"category_mappings": {
"sales": {
"revenue_account_id": "uuid-of-4000-sales-revenue",
"receivable_account_id": "uuid-of-1200-accounts-receivable"
},
"expense": {
"expense_account_id": "uuid-of-5000-general-expenses",
"payable_account_id": "uuid-of-2000-accounts-payable"
},
"specific-category-uuid": {
"revenue_account_id": "uuid-of-4100-consulting-revenue"
}
}
}| Key | Type | Purpose |
|---|---|---|
"sales" | Fallback | Default GL accounts for all sale categories |
"expense" | Fallback | Default GL accounts for all expense categories |
"uuid-..." | Specific | Override for a specific category UUID |
CategoryMapping Fields
- RevenueAccountID: Where revenue posts (for sales)
- ReceivableAccountID: AR account for invoiced sales
- ExpenseAccountID: Where expense posts (for expenses)
- PayableAccountID: AP account for billed expenses
- RecognitionMode:
immediateordeferred
Posting Defaults
System-wide GL accounts used for special scenarios that do not fit category mappings.
{
"posting_defaults": {
"suspense_account_id": "uuid-of-9000-suspense",
"accounts_receivable_account_id": "uuid-of-1200-ar",
"accounts_payable_account_id": "uuid-of-2000-ap",
"owner_capital_account_id": "uuid-of-3000-capital",
"owner_drawings_account_id": "uuid-of-3100-drawings"
}
}| Account | Used For |
|---|---|
| Suspense Account | Temporary holding for unclassified amounts |
| Accounts Receivable | Customer balances owed |
| Accounts Payable | Vendor balances owed |
| Owner Capital | Owner contributions |
| Owner Drawings | Owner withdrawals |
Posting Controls
Rules that govern the review workflow and period locking. These control who can approve flagged events and when edits are allowed.
{
"posting_controls": {
"who_can_override": "accountant_admin",
"override_requires": "reason",
"lock_after_days": 30,
"lock_closed_periods": true
}
}| Control | Options | Effect |
|---|---|---|
who_can_override | admin_only,accountant_admin,no_one | Who can mark flagged events as ready |
override_requires | reason,reason_and_attachment | What is needed to override |
lock_after_days | Number | Events older than X days cannot be edited |
lock_closed_periods | Boolean | Prevent changes in closed accounting periods |
Important Distinction
WhoCanOverride andOverrideRequires control the review workflow, not GL resolution. Category GL overrides are stored on the category itself (DefaultRevenueAccountID).
Transaction Categories
Categories hold the Layer 1 GL overrides and additional settings that affect review.
| Field | Type | Effect on Events |
|---|---|---|
AppliesTo | sale, expense, cash_only, transfer | Determines which transactions can use this category |
RequireAttachment | Boolean | Flags event for review if no attachment uploaded |
RequireInvoiceRef | Boolean | Flags event for review if no invoice/reference number |
RecognitionMode | immediate, deferred | When revenue/expense is recognized |
DefaultRevenueAccountID | UUID | Layer 1 GL override for revenue (sale categories) |
DefaultExpenseAccountID | UUID | Layer 1 GL override for expenses (expense categories) |
Auto-Assignment on Create
When a new category is created without explicit GL accounts, defaults are pulled from the policy.