Data Ownership
Who owns what data. No shared databases between services.
Ownership Map
| Data | Owner | Storage | Other services access via |
|---|---|---|---|
| Events (proposals, approvals, executions) | Accounting API | PostgreSQL events table |
Event Store API (GET /events) |
| Patterns (merchant → account mappings) | Accounting API | PostgreSQL patterns table |
Event Store API (embedded in events) |
| Conversations (Discord thread history) | Book-E | In-memory (Phase 1) / Postgres (Phase 2) | Not shared |
| User facts (preferences, learned behaviors) | Book-E | In-memory (Phase 1) / Postgres (Phase 2) | Not shared |
| Bank transactions | Folio (external) | Folio's systems | Accounting API reads via Folio API |
| Accounting records | Fiken (external) | Fiken's systems | Accounting API reads via Fiken API |
| Character config | Git (ai-accountant repo) | ConfigMap on k8s | Mounted as volume in Book-E pod |
The Rule
Each piece of data has exactly one owner. Other services read it through the owner's API, never by accessing the database directly.
❌ Review-E reads the events table directly
✅ Review-E calls GET /events?status=PROPOSED via the Accounting API
❌ Accounting API reads Book-E's conversation history
✅ Book-E includes relevant context in the proposal event
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 themselves |
We never duplicate financial data. Our events reference external IDs. If Folio or Fiken data changes, the source of truth is there, not in our event store.
Growth: Adding a Cost API
When we add a Cost API for monitoring spending (Anthropic, Google, Twilio):
Cost API owns:
- cost_snapshots table (periodic usage snapshots)
- cost_budgets table (monthly limits per service)
Cost API reads (via event store):
- ReceiptAttachmentExecuted events (to correlate with costs)
Cost API does NOT:
- Write to the events table (that's Accounting API's)
- Read Folio/Fiken directly (that's Accounting API's job)
Each new service owns its own data and reads others through APIs.