Skip to content

Data Ownership

Who owns what data. Services access other services' data through APIs, never the database directly.

Ownership Map

Data Owner Storage Others access via
Events (proposals, approvals, executions) Event Store API PostgreSQL events table GET /events, POST /events
Patterns (merchant → account mappings) Event Store API PostgreSQL patterns table Embedded in event responses
Cost snapshots (usage data) Cost API Cost API's own storage GET /usage/*
Conversations (Discord thread history) Book-E In-memory / Postgres Not shared
Bank transactions Folio (external) Folio's systems Accounting API → Folio API
Accounting records Fiken (external) Fiken's systems Accounting API → Fiken API
Character config Git ConfigMap on k8s Mounted in Book-E pod

The Rule

Each piece of data has exactly one owner. Other services read it through the owner's API.

Wrong

Review-E reads the events table directly via SQL

Right

Review-E calls GET /events?status=PROPOSED via the Event Store API

Database Access

Only the Event Store API has Postgres credentials. All other services go through HTTP APIs.

graph LR
    B[Book-E] -->|HTTP| ES[Event Store API]
    R[Review-E] -->|HTTP| ES
    A[Accounting API] -->|HTTP called by| ES
    C[Cost API] -->|HTTP called by| ES
    ES -->|SQL| DB[(PostgreSQL)]
    M[Metabase] -->|SQL read-only| DB

Systems of Record

Data we store is secondary. The systems of record are external:

Data System of Record We store
Bank transactions Folio Events referencing Folio event IDs
Accounting entries Fiken Events referencing Fiken purchase/entry IDs
Receipts/invoices Folio attachments Events with file URLs, not the files
AI usage Anthropic/Google/Cloudflare Periodic cost snapshots

We never duplicate financial data. Our events reference external IDs.