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 with Matcher’s embedded extraction engine
- 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 you reconcile)
- 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, schema detection, and extraction orchestration with the extraction engine. Discovery runs inside Matcher. There is no separate extraction service to deploy. Responsibilities:- Manage external data source connections
- Detect and cache source schemas
- Run in-process extractions and hand results directly to Ingestion
- Track connection and extraction lifecycles
FetcherConnection: External source connection managed locally by the extraction engineExtractionRequest: Tracks an extraction lifecycle run by the embedded engine
See Discovery for how Discovery connects to external databases with the extraction engine.
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
ingestion.completed: 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, fuzzy, 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 for issue tracking
- ServiceNow for Table API incidents
- Webhooks for custom workflows
Governance
The Governance bounded context preserves reconciliation traceability. Responsibilities:- Record instrumented auditable mutation workflows in immutable audit logs
- Provide queryable audit history
- Support regulatory and compliance reporting
AuditLog: Append-only record of instrumented auditable mutation workflows
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
You define reconciliation contexts, sources, field mappings, and rules through the API.
2
Discovery
Discovery connects to external sources, detects their schemas, and runs extractions in-process with the extraction engine. Discovery hands extracted results directly to Ingestion.
3
Ingestion
Ingestion parses, validates, normalizes, and deduplicates uploaded files and the data that Discovery extracts. Ingestion emits an
ingestion.completed event.4
Matching
Matching applies rules to eligible transactions and produces match groups with confidence scores on an integer scale of 0 to 100. EXACT and TOLERANCE groups with a confidence of at least 90 out of 100 can auto-confirm. FUZZY and DATE_LAG groups always require manual review. Unmatched items become exceptions.
5
Exception handling
The Exception context classifies and routes exceptions. Resolution happens manually or through external systems. Resolution updates return to Matcher.
6
Governance
Governance records instrumented auditable mutation workflows across the pipeline in immutable audit logs.
7
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
- Tenant-specific pool resolution in configured multi-tenant deployments for data separation
- Strong consistency for matching and exception state
- Eventual consistency for reporting views
Multi-tenancy
Matcher enforces strict tenant isolation:- In multi-tenant deployments with
AUTH_PROVIDER=plugin-auth, Matcher takes tenant identity fromtenant_idortenantIdJWT claims - Single-tenant and authentication-disabled deployments use the configured default tenant
- Matcher never accepts tenant identifiers from request parameters
- All database access goes through the active tenant’s connection pool
- Matcher automatically constrains every query 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
Matcher separates write and read paths at the service level:*_commands.gofor state mutations*_queries.gofor read operations
Outbox pattern
Matcher uses per-event delivery policies. Matcher persists an outbox record for outbox-backed events and dispatches them asynchronously. Other events can use direct delivery with an outbox fallback when the circuit is open.Next steps
Quick start
Explore the architecture through a guided example.
Security
Review authentication, authorization, and tenant isolation mechanisms.

