Skip to content

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).

  1. Ingest: Receive Connect.SyncCompleted payload.
  2. Normalise: Map vendor fields to UnifiedTransaction and UnifiedAccount.
    • Example: Map Plaid's iso_currency_code to FOS currency.
    • Example: Invert liability balances (Plaid sends positive, FOS expects negative for debt).
  3. Deduplicate: Use provider_transaction_id to ensure idempotency.
  4. Publish: Emit Core.TransactionsImported event.

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).
  • 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

  1. Trigger: Cron (Midnight UTC).
  2. Action: Will snapshot every account balance.
  3. Store: Save to HistoricalBalances time-series table.
  4. 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.