Module Spec: FintraOS Core
1. Overview
FintraOS Core is designed to be the heart of the platform. It will act as a high-throughput State Engine that ingests raw data from Connect and maintains the live "Financial Twin" (the Profile) defined in the Domain-Model.
It will be responsible for Normalisation, Identity Resolution, and State Management.
Key Philosophy: "The Truth is in the Stream." Core is built on an Event Sourcing architecture (see ADR-001). The current state of a user's finances is simply the aggregation of all historical events.
2. Core Responsibilities
2.1. The "Ingestion & Normalisation" Pipeline
Raw data will arrive from Connect in various vendor-specific formats (Plaid JSON, Yapily JSON, CSV). Core will normalise this into the FintraOS Open Standard (FOS).
- Ingest: Receive
Connect.SyncCompletedpayload. - Normalise: Map vendor fields to
UnifiedTransactionandUnifiedAccount.- Example: Map Plaid's
iso_currency_codeto FOScurrency. - Example: Invert liability balances (Plaid sends positive, FOS expects negative for debt).
- Example: Map Plaid's
- Deduplicate: Use
provider_transaction_idto ensure idempotency. - Publish: Emit
Core.TransactionsImportedevent.
2.2. The Financial Graph Engines
Core will maintain the live "Financial Twin" via two specialised sub-engines, matching the architectural design:
2.2.1. Balance Sheet Engine
Responsible for the "Stock" of wealth (Assets vs. Liabilities).
* Trigger: Core.TransactionsImported or Core.WealthUpdated.
* Logic: Aggregates all asset values (Cash, Investments, Property) and subtracts liabilities (Loans, Credit Cards).
* Output: Updates Profile.net_worth and Profile.total_debt.
2.2.2. Cashflow Engine
Responsible for the "Flow" of wealth (Income vs. Expenses).
* Trigger: Core.TransactionsImported.
* Logic:
* Identifies recurring income streams (Salary, Dividends).
* Categorises spending velocity (Burn Rate).
* Calculates "Free Cash Flow" (Disposable Income).
* Output: Updates Profile.monthly_burn and Profile.savings_rate.
2.3. Identity Merging (The Passport Logic)
Core will execute the heavy lifting for the "Financial Passport" strategy.
* Trigger: Connect.ProfileLinked (User consents to link existing profile).
* Process:
1. Lock: Lock both Source (Global) and Target (Tenant) profiles.
2. Replay: Replay all historical events from Source into Target's event stream.
3. Anonymise: Strip any Source-specific metadata (e.g., old Tenant IDs).
4. Unlock: Release locks.
* Result: The new Tenant Profile now contains 5 years of history instantly.
2.4. Platform Extensibility Handler
Core will act as the storage engine for tenant-defined data points, ensuring the "Financial Twin" includes platform-specific context.
* Trigger: Connect.CustomDataReceived
* Process:
1. Validate: Check if the tenant has defined this metric in Module-Brain's Dynamic Registry.
2. Enrich: Attach tenant_id and metadata.
3. Persist: Append PlatformDataRecorded to the Event Stream.
* Result: The data becomes available for Module-Brain calculators and Module-Guard context scoping.
3. Data Architecture (Event Sourcing)
3.1. The Event Log (Source of Truth)
We will not just store the "Current Balance." We will store every change.
| Event Type | Payload |
|---|---|
AccountCreated |
{ id: "acc_1", type: "CHECKING", currency: "GBP" } |
BalanceUpdated |
{ id: "acc_1", new_balance: 100.00, timestamp: "T12:00" } |
TransactionAdded |
{ id: "tx_99", amount: -50.00, merchant: "Tesco" } |
TransactionEnriched |
{ id: "tx_99", category: "Groceries" } |
PlatformDataRecorded |
{ key: "rides_completed", value: 45, context: {...} } |
3.2. Materialised Views (Read Models)
For fast API access, we will maintain optimised projections in a Document Store (PostgreSQL (JSONB)).
View_UnifiedProfile: The full nested JSON object (Accounts + Transactions + Insights).- Optimised for:
GET /v1/profile/me(The Dashboard Load).
- Optimised for:
View_TransactionSearch: An ElasticSearch index.- Optimised for: "Show me all coffee purchases in 2023."
4. Workflows
4.1. The "Revaluation" Job (Wealth Engine)
Will run every 15 minutes for users with Investment/Crypto assets or foreign currency holdings.
1. Trigger: MarketStream.PriceUpdated (from Connect).
2. Select: Find all Profiles holding the affected Asset Class or Currency.
3. Calculate:
* Investments: NewValue = Quantity * NewPrice.
* FX: HomeCurrencyValue = ForeignBalance * ExchangeRate.
4. Update: Write new balance to UnifiedAccount.
5. Emit: Core.WealthUpdated (Triggers "Net Worth High" alerts in Brain).
4.2. The "End of Day" Snapshot
- Trigger: Cron (Midnight UTC).
- Action: Will snapshot every account balance.
- Store: Save to
HistoricalBalancestime-series table. - Purpose: Powers the "Net Worth over Time" graph.
5. Interfaces & API
5.1. POST /v1/core/command
Will act as the internal command bus.
{
"command": "UpdateTransactionCategory",
"payload": {
"transaction_id": "tx_123",
"new_category": "Business Expense"
},
"metadata": {
"user_id": "usr_ABC",
"source": "USER_OVERRIDE"
}
}
5.2. GET /v1/core/stream
Will provide a firehose for downstream services (Brain, Pulse). * Format: Server-Sent Events (SSE) or gRPC Stream. * Content: Real-time feed of all financial events for a specific Tenant.
6. Technology Stack
- Language: Go (Golang) - for high throughput and concurrency.
- Event Bus: Kafka / Redpanda.
- State Store: PostgreSQL (JSONB) + TimescaleDB (Time-series).
- Search: ElasticSearch / OpenSearch.