Architecture overview
Matcher architecture overview
Bounded contexts
Matcher has seven modules. Each owns its data and exposes clean interfaces to the others.
- Configuration: What you’re reconciling (contexts, sources, field maps, rules)
- Discovery: External data source connections, schema detection, and extraction orchestration (via Fetcher)
- Ingestion: Getting data in (parsing, validation, normalization)
- Matching: The engine (rule execution, confidence scoring)
- Exception: Handling unmatched items (workflow, routing, resolution)
- Governance: Audit trails (immutable logs for compliance)
- Reporting: Visibility (reports, exports, dashboards)
Configuration
Defines what you’re reconciling and how. Handles:- Contexts (what’s being reconciled)
- Sources (where data comes from)
- Field maps (translating external fields)
- Rules (how to match)
ReconciliationContext: The reconciliation scopeReconciliationSource: Source configurationFieldMap: Field translation rulesMatchRule: Matching logic
Discovery
The Discovery bounded context manages external data source connectivity and extraction orchestration through Fetcher, Lerian’s internal data-extraction service. Responsibilities:- Manage external data source connections
- Detect and cache source schemas
- Orchestrate extraction requests and bridge results into ingestion
- Track connection and extraction health
DiscoveryConnection: External source connection configurationExtractionRequest: Tracks an extraction lifecycle through Fetcher
See Discovery for how Discovery connects to external databases through Fetcher.
Ingestion
The Ingestion bounded context handles data intake and normalization. Responsibilities:- Parse uploaded files (CSV, JSON, XML)
- Validate incoming data against configured schemas
- Normalize external data into a canonical representation
- Detect and handle duplicate records
- Emit domain events when ingestion completes
IngestionJob: Tracks ingestion lifecycle and statusTransaction: Normalized canonical transaction record
IngestionCompleted: Indicates data readiness for matching
Matching
The Matching bounded context contains the reconciliation engine. Responsibilities:- Load applicable rules for a reconciliation context
- Execute matching strategies (exact, tolerance, date-based)
- Calculate confidence scores
- Create match groups and allocate transactions
- Identify unmatched transactions
MatchRun: Execution of a matching jobMatchGroup: Group of reconciled transactionsMatchItem: Individual transaction allocation
match_group.confirmed: A match group has been finalizedmatch_group.unmatched: A previously confirmed match was revertedtransaction.pending_review: A non-automatic candidate needs review
Exception management
The Exception bounded context manages unresolved transactions. Responsibilities:- Classify exceptions by severity
- Route exceptions to internal teams or external systems
- Support manual overrides and adjustments
- Track resolution status and SLAs
- Integrate with external workflow tools
Exception: An unresolved transactionResolution: Outcome of exception handlingRoutingRule: Routing and escalation logic
- JIRA and ServiceNow for issue tracking
- Webhooks for custom workflows
Governance
The Governance bounded context preserves reconciliation traceability. Responsibilities:- Record all system actions in immutable audit logs
- Provide queryable audit history
- Support regulatory and compliance reporting
AuditLog: Append-only record of system activity
Reporting
The Reporting bounded context provides operational visibility. Responsibilities:- Generate reconciliation reports
- Expose dashboard metrics
- Export reconciliation data in multiple formats
Report: Reconciliation summaryDashboard: Aggregated operational metricsExportJob: Asynchronous export execution
Data flow
Reconciliation follows a deterministic pipeline across bounded contexts:
1
Configuration
Reconciliation contexts, sources, field mappings, and rules are defined through the API.
2
Ingestion
External data is uploaded or fetched. Files are parsed, validated, normalized, and deduplicated. An
IngestionCompleted event is emitted.3
Matching
Matching rules are applied to eligible transactions, producing match groups with confidence scores. High-confidence matches are approved automatically. Unmatched items become exceptions.
4
Exception handling
Exceptions are classified, routed, and resolved either manually or via external systems. Resolution updates are propagated back to Matcher.
5
Governance
All actions across the pipeline are recorded in immutable audit logs.
6
Reporting
Users access reports and dashboards showing reconciliation status, match rates, and exception aging.
Infrastructure components
Matcher relies on the following infrastructure services:
Database architecture
- Pool-per-tenant isolation (a dedicated PostgreSQL database per tenant) for strong data separation
- Strong consistency for matching and exception state
- Eventual consistency for reporting views
Multi-tenancy
Matcher enforces strict tenant isolation:- Tenant identity is extracted exclusively from JWT claims
- Tenant identifiers are never accepted via request parameters
- Database access is scoped through a per-tenant connection pool resolved from the JWT
- All queries are automatically constrained to the active tenant
This model prevents cross-tenant data access and supports regulatory and audit requirements.
Design patterns
Hexagonal architecture
Each bounded context follows the ports-and-adapters pattern:Cqrs-light
Write and read paths are separated at the service level:*_command.gofor state mutations*_query.gofor read operations
Outbox pattern
Event publication follows the outbox pattern:- Domain state and outbox records are persisted atomically
- Background workers publish events to the streaming backbone
- Events are marked as processed after successful delivery
Next steps
Quick start
Explore the architecture through a guided example.
Security
Review authentication, authorization, and tenant isolation mechanisms.

