-
Notifications
You must be signed in to change notification settings - Fork 0
Domain Glossary
Authoritative vocabulary for FinCore Engine. Every term used in code, docs, ADRs, API specs and Wiki pages is defined here. If a term appears in this glossary, use it consistently - never invent synonyms. If you find a term in code or docs that's not here, add it.
- Bold term = canonical name. Use exactly this casing in code where naming applies.
- Italic = a term defined elsewhere in this glossary (clickable navigation).
- Note: = common misuse to avoid.
- = external authoritative reference where applicable.
A holder of monetary value, identified by a UUID, with an Account Type and Currency. The unit of bookkeeping in the Ledger. Accounts have Balance derived from their Entries.
Note: Not a "user account" or "customer account" - those are application-level concepts. An Account in FinCore is purely a Ledger entity, the equivalent of a row in a chart of accounts.
Categorization that determines accounting treatment. Allowed values:
-
ASSET- owned (bank float, settlement balance) -
LIABILITY- owed (customer balance, accrued fees) -
EQUITY- owners' stake (retained earnings) -
REVENUE- income recognized -
EXPENSE- costs incurred -
USER_WALLET- customer-held value (subset of LIABILITY) -
FEE- fee income (subset of REVENUE) -
RESERVE- held for future obligations -
SUSPENSE- temporary holding for unallocated funds
Stored in DB as VARCHAR(32) with @Enumerated(EnumType.STRING).
The set of regulations, controls and processes that prevent illicit funds from entering the financial system. In FinCore: rules engine + alert generation + case management + AI copilot.
Record produced when an AML rule matches a transaction. Contains: transactionId, riskScore (0-100), reasons (list of matched rule codes), status (OPEN/CLOSED).
Linked to a Compliance Case for human review when severity warrants.
A pluggable component (fincore-ml) that computes a numeric score from a transaction or sequence. Implementations: Isolation Forest, statistical outlier (z-score, MAD), graph-based detector. Used as input to Decision Engine, never as authoritative decision-maker.
The single inbound entry point for HTTP traffic. Responsibilities: TLS termination, rate limiting, JWT verification (cached JWKS from Keycloak), correlation ID injection, request routing to services. In FinCore: a Spring Cloud Gateway service.
Append-only record of who did what when. In FinCore there are several:
-
decision_logs- every Decision Engine evaluation -
transactions+entries- the immutable Ledger journal - Application-level audit (Spring
AuditingEntityListenerpopulatescreated_by,updated_by) - Outbox events (transient - dispatched and archived)
Note: Not the same as application logs (those are observability output, mutable).
The current sum of all Entries for an Account in a given Currency. Computed from the immutable journal:
balance(account, currency) = SUM(entries.amount WHERE entries.account_id = account AND entries.currency = currency)
Materialized in the account_balances view for read performance.
Pluggable component that talks to an external Banking Partner. Implements interface BankProvider. Sandbox implementation provided in OSS; real implementations are out of OSS scope.
External regulated entity that holds customer funds and performs settlement. FinCore is not a banking partner - it orchestrates and tracks; the partner moves money.
The OSS license used by FinCore Engine. Permits all use cases except offering the software as a competitive commercial service. Auto-converts to Apache 2.0 four years after each release. Used by Sentry, MariaDB MaxScale, CockroachDB (until 2024), HashiCorp.
Speed at which Error Budget is consumed. A 1-hour burn rate of 14.4× exhausts a monthly budget in 24 hours. Used to trigger fast/slow alerts.
Google SRE Book - Alerting on SLOs
Record opened when a transaction or onboarding event flags as needing human review. Lifecycle: OPEN → IN_REVIEW → RESOLVED (APPROVED|REJECTED|ESCALATED). Resolved cases are immutable.
Practice of defining AML rules, KYC policies and screening lists in version-controlled code (YAML/JSON), reviewed via PRs, deployed via GitOps. A FinCore Tier-2 Killer Feature.
Human role responsible for resolving Compliance Cases, drafting SAR/STR reports, owning regulatory relationships. In FinCore: any user with role COMPLIANCE_RESOLVER or higher.
Service that subscribes to one or more Topics and processes Events. Must be Idempotent (see also Dedup).
UUID injected into every inbound request by the Gateway. Propagated through all services via X-Correlation-Id header and traceparent (W3C). Available in logs as MDC key correlationId. Lets you trace a single user request across services and time.
US regulatory filing required when a single transaction exceeds $10,000. Auto Regulatory Reporting feature drafts these.
ISO 4217 three-letter code (USD, EUR, GBP, …). Stored as CHAR(3). Money values are always paired with a Currency. FX between Currencies is not done by FinCore - it's delegated to a Banking Partner.
Kafka topic where messages land after exhausting retries. In FinCore: <topic>.dlq per main topic. Monitored, alert fires on non-zero depth.
Practice of ensuring the same Event produces the same effect at most once. Implemented via processed_events(event_id, processed_at) table written atomically with business state.
Output of the Decision Engine. Values: APPROVE, REJECT, REVIEW. Always accompanied by matchedRules, explanation, latencyMs.
Pluggable, deterministic, JSON-DSL rule engine. Inputs context, outputs Decision, writes to decision_logs. No ML, no side effects, no external calls. A standalone library (fincore-decision-engine) and the engine's flagship piece.
Note: Not a workflow engine, not a BPM tool. Single-shot evaluations.
Row in decision_logs capturing every Decision Engine invocation: input_payload, matched_rules, decision, latency_ms, rule_version, created_at. Used for audit, replay, regulatory inquiries.
The JSON format used to define rules in the Decision Engine. Has fixed schema, validated at insert time. Example:
{ "all": [
{ "field": "amount", "op": ">", "value": 10000 },
{ "field": "country", "op": "in", "value": ["NG", "PK"] }
],
"action": { "decision": "REVIEW", "reason": "high_amount_high_risk" }
}Accounting principle: every transaction has at least two Entries summing to zero per Currency. Enforced at the database level via deferred trigger.
Wikipedia: Double-entry bookkeeping
Background worker that polls outbox_events, publishes to Kafka, marks rows as PUBLISHED. Uses SELECT ... FOR UPDATE SKIP LOCKED for multi-worker safety.
Single-side debit or credit posting to an Account, part of a Transaction. Fields: id, transaction_id, account_id, amount (signed NUMERIC(38,18)), currency, direction (DEBIT | CREDIT).
Note: Although stored as signed amount, the direction is also persisted explicitly. Sign reflects direction (DEBIT = negative for asset/expense; CREDIT = positive). Trigger validates SUM(amount) = 0 per (transaction_id, currency).
Allowed amount of unreliability per period. Computed as (1 - SLO) × period. E.g., 99.95% availability over 30 days = 21m 36s. Consumed by incidents, accumulated when reliable.
Immutable record of "something happened." Two flavors:
-
Domain event - internal (
account.created,transaction.posted,payment.completed,aml.flagged,decision.rule.activated, etc.) - Webhook event - external (signed delivery to subscribers)
Standard wrapper for all Events:
{
"id": "evt_uuid",
"type": "transaction.posted",
"version": "1.0",
"occurredAt": "2026-04-25T10:00:00Z",
"aggregateId": "...",
"correlationId": "...",
"actor": { "type": "USER|SERVICE|SYSTEM", "id": "..." },
"data": { ... }
}The system reaches consistency after outbox dispatch, downstream consumers, materialized view refresh. The Ledger itself is strictly consistent (single DB transaction). Cross-service aggregates and webhook deliveries are eventually consistent.
See User-Flows#failure-classification. Eleven canonical classes from validation error to DB unavailability.
International standards body for AML/CFT. FinCore AML Rules map to FATF recommendations 10-12 (CDD), 16 (wire transfers), 20 (suspicious transactions reporting).
This project. The OSS umbrella covering ledger + payments + compliance + decision engine + sandbox.
Currency conversion. Not done in FinCore Engine. When a payment crosses currencies, a Banking Partner provides the rate; FinCore tracks both sides via separate Transactions in their respective currencies.
See API Gateway.
EU regulation on personal data. FinCore design implications: encryption at rest, soft delete with key destruction (right to be forgotten), data portability API, audit of all PII access.
Practice of declaring infrastructure and configuration in Git, reconciled by an automated agent. FinCore's Compliance-as-Code feature uses GitOps for AML rules.
Used to sign webhooks (outbound to subscribers, inbound from bank providers). Algorithm: HMAC-SHA256(rawBody, sharedSecret). Conveyed in X-Signature header.
Architectural style separating domain logic from adapters (UI, DB, external services). Used in every FinCore service:
-
domain/- pure Kotlin, no Spring -
application/- use-case services with ports -
infrastructure/- JPA, REST clients, Kafka adapters
Alistair Cockburn - Hexagonal Architecture
Guarantee that applying the same operation twice has the same effect as applying it once. Required for all FinCore mutating endpoints. Implemented via Idempotency-Key header + idempotency_keys table.
String (max 255 chars) provided by client in Idempotency-Key header. Hashed and stored along with the response. TTL = 24 hours.
Property of the Ledger: transactions and entries rows are never updated or deleted, only appended. Reverses are new transactions linked to originals.
Mathematical property the system always upholds. The flagship FinCore invariant: SUM(entries.amount) = 0 per (transaction_id, currency). Enforced via deferred Postgres trigger.
Financial messaging standard used by SEPA, SWIFT, RTP. FinCore Killer Feature #9: native PACS.008, PAIN.001, CAMT.053 mappings.
The format for rules in the Decision Engine. See DSL.
Token format used by Keycloak for authentication. Signed RS256, TTL 5 minutes, contains sub (user id), roles, scope, aud. Verified by Gateway with cached JWKS.
The OAuth2/OIDC identity provider used by FinCore. Version 26.6.1. Realm name: fincore. Provides JWT issuance, introspection, user management, fine-grained authorization.
A capability that few or no alternatives in the OSS fintech space offer. Top-10: Replay Mode, Compliance-as-Code, AI Reconciliation, Plug-In Marketplace, Time-Travel Balance, GDPR Engine, ISO 20022, AI AML Copilot, Auto Regulatory Reporting, LLM Rule Synthesis.
Process of verifying a customer's identity. FinCore provides KYC Orchestration - the framework for integrating with KYC providers - but does not implement identity verification itself.
Framework for sequencing KYC steps: document upload, identity verification, sanctions screening, PEP screening, decision. Pluggable provider interface (KycProvider). Sandbox provider in OSS; real provider adapters are out of OSS scope.
Same concept as KYC, applied to corporate entities. Includes UBO (ultimate beneficial owner) verification.
The double-entry accounting subsystem. Tables: accounts, transactions, entries, account_balances (materialized view).
Database migration tool. Version 5.0.2. Changelog format: XML. Migrations in src/main/resources/db/changelog/v0.1/. Every change is a new file, never an edit to an existing file.
External or local AI model used for natural-language tasks (AML copilot, rule synthesis, reconciliation). Pluggable provider in fincore-llm module: OpenAI, Anthropic, Ollama, Mistral, Bedrock.
Note: LLMs are advisory in FinCore - never authoritative for money movement decisions.
Postgres feature: stored snapshot of a query, refreshed on demand. FinCore uses account_balances as a materialized view for fast balance reads. Refreshed CONCURRENTLY after each transaction post (or batched).
Annotation processor for type-safe object mapping. Used via KSP (not kapt) in FinCore. Replaces manual mappers and Kotlin extension functions for entity↔DTO conversion.
SLF4J feature for per-thread structured logging context. FinCore MDC keys: correlationId, requestId, userId, tenantId, serviceName. Auto-populated by interceptor.
Architectural pattern: single deployment unit, but internally structured as bounded contexts with strict module boundaries. FinCore starts as modular monolith, prepared for extraction to microservices in Y1 H2.
Modular Monoliths - Simon Brown
Domain value type. data class Money(val amount: BigDecimal, val currency: Currency). Always uses BigDecimal with MathContext.DECIMAL128, RoundingMode.HALF_EVEN. Comparison via compareTo, never equals.
Note: Never use Float or Double for monetary values. Ever.
Anti-pattern: a SELECT for the parent followed by N SELECTs for each child. Forbidden in FinCore. Use @EntityGraph or explicit JOIN FETCH.
Three pillars:
- Logs - structured JSON via Logback + logstash-logback-encoder, shipped to Loki
- Metrics - Micrometer + Prometheus
- Traces - OpenTelemetry, shipped to Tempo
Visualized in Grafana dashboards.
Concurrency strategy: each entity has a version column; updates check it and fail if changed. Hibernate's @Version. Used universally in FinCore. Failures retry up to 3 times.
Row in outbox_events table representing an event to be dispatched to Kafka. Fields: id, aggregate_type, aggregate_id, event_type, payload (JSONB), status (PENDING/PUBLISHED/FAILED), attempts, created_at, published_at, last_error.
Architectural pattern for transactionally consistent event publishing: business writes + outbox row in one DB transaction, async dispatcher publishes to Kafka. Solves the dual-write problem.
Microservices.io - Transactional Outbox
Aggregate representing money movement between two Accounts (internal-internal or internal-external via Bank Adapter). Lifecycle states: CREATED → PROCESSING → COMPLETED, or → FAILED, → PERMANENTLY_FAILED, → REJECTED, → PENDING_REVIEW.
Individual entrusted with a prominent public function. Heightened AML scrutiny required. Screening done via external provider (SanctionsProvider interface), not in OSS.
Data that identifies a real person: name, ID number, address, biometric. FinCore design: PII is encrypted at rest, never logged, only IDs and hashes appear in logs.
Implementation of an interface, registered via Spring profiles or programmatic configuration. FinCore plug-in interfaces: BankProvider, KycProvider, SanctionsProvider, RiskScorer, AnomalyDetector, AmlCopilot, RuleSynthesizer, LlmClient.
Repository strategy: each service / library lives in its own GitHub repo, plus an umbrella repo (fincore-engine) holding meta-deployment (docker-compose, Helm meta-chart), integration tests, shared docs.
The default and recommended database. Version 17. Used for ledger, payments, compliance, idempotency, outbox. Optional alternative storage backend: TigerBeetle (via adapter, Y1 H2).
Process publishing events to a Topic. In FinCore, producer = Outbox Dispatcher. No service publishes to Kafka directly.
Test that asserts a property holds for many auto-generated inputs (vs. specific examples). Library: Kotest property testing. Used for ledger invariants, idempotency, decision engine determinism.
Kafka-API-compatible streaming platform. The default broker in FinCore docker-compose (single binary, no ZooKeeper, fast startup). Production deployments can use any Kafka-compatible broker (Apache Kafka, Confluent, MSK, Strimzi).
External, client-supplied unique identifier for a Transaction. Used for idempotency and reconciliation. Indexed unique. Format: free text up to 255 chars.
Killer Feature: re-run historical decisions against a new rule set, produce diff report. Supports compliance scenarios like "if we'd had this rule 6 months ago, what would have changed?"
Compensating Transaction that negates a previously POSTED transaction. Original is marked REVERSED. The journal grows; nothing is deleted.
Numeric value (0-100) expressing relative risk of a transaction or entity. Computed by Risk Scorer plug-in. Advisory only - feeds into Decision Engine alongside rules.
Standard format for HTTP error responses. Used by FinCore for all 4xx/5xx:
{
"type": "https://docs.fincore.dev/errors/insufficient-balance",
"title": "Insufficient balance",
"status": 422,
"detail": "Account abc-123 has 50.00 EUR, transfer requires 100.00 EUR",
"instance": "/v1/payments",
"correlationId": "..."
}Named collection of Rules in the Decision Engine. Examples: payment-screening, aml-screening, onboarding-decision. Evaluated as a unit.
Snapshot of a rule's definition at a point in time. Stored in rule_versions. Immutable. Referenced by decision_logs.rule_version for replay.
US AML regulatory filing. Drafts auto-generated by FinCore Auto Regulatory Reporting (Y1 H2 feature) from compliance cases.
Pattern for distributed transactions across services using compensating actions. Not used in FinCore v0.1 (modular monolith - single DB transaction). Becomes relevant after polyrepo extraction.
Isolated test environment with fake providers (bank, KYC, sanctions). Default mode for docker compose up. Reproducible scenarios for testing.
EU payment scheme. ISO 20022 PACS messages. Out-of-OSS-scope direct integration; BankProvider plug-in implements it for adopters.
External commitment to a customer about service quality. FinCore Engine OSS does NOT publish SLA - adopters define their own with their customers. We publish SLO targets as best-effort recommendations.
Internal target for a metric. Examples: 99.95% availability, p99 < 500ms. See Architecture-SLA-SLI-SLO.
Quantitative measure of service quality. Examples: success rate, p99 latency, error rate.
Standard format for license identification. FinCore source files start with // SPDX-License-Identifier: BUSL-1.1.
Explicit definition of allowed state transitions for an aggregate. Payment state machine:
CREATED → PROCESSING → COMPLETED
↘ REJECTED
↘ PENDING_REVIEW → CREATED (after manual approval)
↘ FAILED → PROCESSING (retry) | PERMANENTLY_FAILED
Implemented as a guard in *ServiceImpl - illegal transitions throw IllegalStateException.
EU equivalent of SAR. See SAR.
Library for spinning up real Docker containers in tests. Used for integration tests against real Postgres, Redpanda, Keycloak. No mocks for these.
Open-source financial OLTP database written in Zig. ~1000× throughput vs Postgres. FinCore strategy: optional pluggable storage backend via LedgerStorageProvider adapter (Y1 H2 in fincore-tigerbeetle-adapter repo). Postgres remains default.
Killer Feature: query account balance at any historical timestamp, replayed from the immutable journal. GET /v1/accounts/{id}/balance?asOf=2026-03-15T12:00:00Z.
Named, partitioned stream of events. FinCore topics: ledger.events, payment.events, compliance.events, decision.events. Each has a .retry and .dlq companion.
Aggregate of two or more Entries summing to zero per currency. Persisted as a row in transactions plus N rows in entries. The fundamental Ledger write.
Note: Two senses of "transaction":
- Domain transaction - the bookkeeping concept above
-
DB transaction -
BEGIN ... COMMITboundary
When ambiguous, say "ledger transaction" or "DB transaction" explicitly.
Person who ultimately owns or controls a corporate entity, even through multiple layers. Required in KYB. Verified via external providers, recorded as evidence.
Functional capability of FinCore Engine, defined in Use-Cases. Each UC has an ID (UC-NN), Actor, Preconditions, Main flow, Alternative flows, Postconditions, Acceptance criteria.
The fincore-engine repo. Holds: docker-compose meta, Helm meta-chart, integration tests, README, this Wiki. Does not hold service code - that lives in sibling repos (ledger-service, decision-engine, etc.).
Numeric column on every JPA entity, incremented on update via Hibernate @Version. Used for Optimistic Locking. Unrelated to Rule Version (different concept).
A specific Account Type (USER_WALLET) representing customer-held value. Subtype of LIABILITY from FinCore's perspective (we owe the customer their money).
HTTP POST from FinCore to an external subscriber URL, signed with HMAC. Or: HTTP POST from an external Banking Partner to FinCore, signed with provider HMAC. Two directions, same protocol.
Persistent record (webhook_subscriptions table) defining: subscriber URL, secret, event types of interest, delivery state. Created via POST /v1/webhooks/subscriptions.
These terms appear in industry but are deliberately not used in FinCore:
| Avoided | Why | Use instead |
|---|---|---|
| "Wallet balance" | Ambiguous (some use it as cash equivalent) | Account Balance, with explicit Account Type |
| "Transfer" | Ambiguous in fintech (internal vs external) | Transaction (internal) or Payment (external) |
| "Ledger entry" | Technically correct but verbose | Entry |
| "Money amount" | Redundant | Money (always has currency) |
| "Auth token" | Imprecise | JWT |
| "API key" | Imprecise - we use OAuth2 client_credentials | Client credentials or service account JWT |
| "User account" / "customer account" | Conflates with Account in ledger sense | User + Account (separate concepts) |
| "Hash" (without algorithm) | Imprecise | "SHA-256 hash" / "HMAC-SHA256" |
| Acronym | Expansion |
|---|---|
| AML | Anti-Money Laundering |
| BSL | Business Source License |
| CTR | Currency Transaction Report |
| DLQ | Dead Letter Queue |
| DSL | Domain-Specific Language |
| FATF | Financial Action Task Force |
| FX | Foreign Exchange |
| GDPR | General Data Protection Regulation |
| HMAC | Hash-Based Message Authentication Code |
| IBAN | International Bank Account Number |
| ISO 20022 | Financial messaging standard |
| ISO 4217 | Currency codes standard |
| JWT | JSON Web Token |
| KSP | Kotlin Symbol Processing |
| KYB | Know Your Business |
| KYC | Know Your Customer |
| LLM | Large Language Model |
| MDC | Mapped Diagnostic Context |
| OIDC | OpenID Connect |
| PEP | Politically Exposed Person |
| PII | Personally Identifiable Information |
| RFC 7807 | HTTP Problem Details standard |
| RTP | Real-Time Payments |
| SAR | Suspicious Activity Report |
| SCA | Strong Customer Authentication |
| SEPA | Single Euro Payments Area |
| SLA | Service Level Agreement |
| SLI | Service Level Indicator |
| SLO | Service Level Objective |
| SPDX | Software Package Data Exchange |
| STR | Suspicious Transaction Report |
| SWIFT | Society for Worldwide Interbank Financial Telecommunication |
| UBO | Ultimate Beneficial Owner |
| UC | Use Case |
- Overview
- Services
- Data Model
- Domain Model
- Event Flow
- Security
- Observability
- Resilience
- SLA / SLI / SLO