Skip to content

Data Model

The AI Accountant stores minimal data locally. Tripletex is the system of record for all accounting data. We store only what is needed for audit compliance, company configuration, and rules.

ER Diagram

Data Model

Core Tables

audit_trail

Every action taken by the system is logged. Required by bokforingsloven (Norwegian Bookkeeping Act, section 13).

Column Type Description
id UUID Primary key
company_id UUID FK to company
timestamp TIMESTAMPTZ When the action occurred (UTC)
user_id VARCHAR Slack user ID or email of the requesting user
action_type VARCHAR e.g., create_invoice, register_payment, query_budget
resource_type VARCHAR Tripletex entity type: invoice, supplierInvoice, voucher, etc.
resource_id INTEGER Tripletex entity ID
request_summary TEXT Natural-language summary of what was requested
response_summary TEXT What the system did
tripletex_calls JSONB Array of API calls made: method, path, status, duration
llm_model VARCHAR Which LLM was used (or deterministic for rule-based)
llm_turns INTEGER Number of agent loop turns
llm_tokens_in INTEGER Input tokens consumed
llm_tokens_out INTEGER Output tokens consumed
status VARCHAR success, error, partial, undone
error_detail TEXT Error message if status is not success
undone_at TIMESTAMPTZ If the action was undone, when
undone_by VARCHAR User who triggered undo

Indexes: company_id + timestamp, company_id + action_type, resource_type + resource_id.

Retention: 10 years (bokforingsloven requires 5 years minimum for accounting records, 10 years for primary documentation).

company

Column Type Description
id UUID Primary key
name VARCHAR Company name
org_number VARCHAR(9) Norwegian organization number
tripletex_company_id INTEGER Tripletex internal company ID
tripletex_token_encrypted BYTEA Encrypted OAuth refresh token
tripletex_token_expires_at TIMESTAMPTZ Token expiry
slack_workspace_id VARCHAR Slack workspace ID
slack_bot_token_encrypted BYTEA Encrypted Slack bot token
email_domain VARCHAR Inbound email domain (e.g., firma.no)
timezone VARCHAR Default Europe/Oslo
language VARCHAR nb or en
plan VARCHAR free, pro, business, enterprise
task_count_month INTEGER Tasks used this billing period
created_at TIMESTAMPTZ
updated_at TIMESTAMPTZ

company_context_cache

Pre-fetched Tripletex data to avoid redundant API calls. Refreshed hourly.

Column Type Description
company_id UUID FK to company
context_type VARCHAR departments, accounts, vat_types, employees, customers, suppliers
data JSONB Cached response from Tripletex
fetched_at TIMESTAMPTZ When the cache was last refreshed
expires_at TIMESTAMPTZ Cache expiry (typically fetched_at + 1 hour)

rules_config

Company-specific rules stored as YAML in the database. See Rules Engine for the full specification.

Column Type Description
id UUID Primary key
company_id UUID FK to company
rule_type VARCHAR e.g., expense_policy, approval_threshold, account_mapping
config_yaml TEXT YAML rule definition
enabled BOOLEAN Whether this rule is active
created_at TIMESTAMPTZ
updated_at TIMESTAMPTZ

employee_mapping

Maps external identities (Slack, email) to Tripletex employee IDs.

Column Type Description
id UUID Primary key
company_id UUID FK to company
tripletex_employee_id INTEGER Tripletex employee ID
slack_user_id VARCHAR Slack user ID
email VARCHAR Employee email
role VARCHAR employee, manager, accountant, admin
department_id INTEGER Tripletex department ID

Data Flow

Employee (Slack/Email) ──→ AI Accountant ──→ Tripletex (system of record)
                                │
                                ├── audit_trail (every action)
                                ├── company (config + tokens)
                                ├── rules_config (company policies)
                                └── company_context_cache (performance)

All accounting data lives in Tripletex. The AI Accountant never stores financial transactions, balances, or personally identifiable information beyond what is needed for audit trail and identity mapping.