""" Entity resolution (docs/06): block, score, and link records across sources so the same company from GLEIF + Brreg + CVR collapses to one record with corroborated confidence. rapidfuzz only; deterministic; no external calls. """ from __future__ import annotations from typing import Any from rapidfuzz import fuzz def block_key(rec: dict[str, Any]) -> tuple[str, str]: """Cheap blocking key — same market + first initial — to avoid O(n^2).""" return (rec.get("market") or "", (rec.get("name") or "")[:1].upper()) def resolve(records: list[dict[str, Any]], threshold: int = 92) -> list[dict[str, Any]]: out: list[dict[str, Any]] = [] for r in records: match = None for o in out: if block_key(o) == block_key(r) and fuzz.token_sort_ratio(o.get("name", ""), r.get("name", "")) >= threshold: match = o break if match: # corroboration: independent source agreeing bumps confidence + level match["confidence"] = min(0.99, match.get("confidence", 0.0) + 0.1) match["agreed_sources"] = match.get("agreed_sources", 1) + 1 match.setdefault("merged_from", []).append(r.get("source")) else: out.append({**r, "agreed_sources": 1}) return out