Skip to content

🧠 Enrichment

Enrichment turns raw payee/memo text into canonical entities and tags using YAML pattern registries, executed through dagpipe pipelines.


🏢 Entity Resolution

Lives under domain/enrichment/entity/:

  • identity.py — normalizes and fingerprints payee strings for matching.
  • resolver.py — EntityResolver: resolves a raw payee to an entity_id via name lookup + fingerprint + account linkage.
  • pipeline.py — the enrichment pipeline node that uses the resolver on expense records.
  • utils.py — helpers for entity display names and brand collapsing.

The pipeline is expressed as a dagpipe.Pipeline; the stub pipeline.pyi type-checks against dagpipe directly (see domain/enrichment/entity/pipeline.pyi).


🏷 Tag Assignment

Lives under domain/enrichment/tags/:

  • flags.py — tag candidate flags (priority/confidence hints) computed from memo and MCC.
  • pipeline.py — a dagpipe.Pipeline that assigns a tag_id to expenses based on matched rules.
  • Both are seeded with YAML pattern registries (regex + literal patterns per tag) under the enrichment rules data.

🔄 How Rules Are Wired

  1. The extraction stage yields expenses with raw memo/payee fields.
  2. The orchestrator (PipelineOrchestrator in domain/fetch_pipeline/) chains extraction → enrichment.
  3. Enrichment nodes receive entity/tag services and the http cache store for external lookups.
  4. Resolved entity_id / tag_id are written back onto the expense and persisted.

🧪 Testing

  • Unit tests in tests/domain/enrichment/ cover fingerprint/identity edge cases, tag flag computation, and pipeline wiring.
  • Golden fixtures for memo→entity and memo→tag mappings keep the registries honest.
  • Run them: .venv\Scripts\pytest.exe tests\domain\enrichment

Domain Resources · Fetch Request Workflow · Development