# packages/matching Job posting similarity, dedupe clustering, and keyword coverage for the jobhunt-platform v1.1 agency duplicate detection feature (ADR-0003). ## Modules ### similarity.py - `normalize_employer(name)` -- lowercase, strip agency/legal suffixes (AB, Consulting, etc.), remove punctuation. - `title_score(a, b)` -- rapidfuzz token_set_ratio on job titles (0-100). - `employer_match(a, b)` -- True if normalized employer names are equal. - `desc_score(a, b, max_chars=2000)` -- token_set_ratio on first 2000 chars of descriptions. ### dedupe.py - `cluster(postings: list[dict]) -> dict[str, list[str]]` -- group postings into duplicate clusters. Clustering rule (per ADR-0003): - Same employer (normalized) **OR** - Title similarity >= 85 **AND** description similarity >= 80 Uses union-find for transitive grouping. Clusters are sorted by descending max pairwise score (`c1` = tightest cluster). ### keywords.py - `extract_keywords(text, top_n=30)` -- frequency-based keyword extraction with Swedish + English stopword removal. - `coverage(cv_text, posting_text)` -- computes keyword coverage of a CV against a job posting. Multiword tech terms like "fast api" are collapsed to "fastapi" so they survive as single keywords. ## Installation (uv) ```bash cd packages/matching uv venv && source .venv/bin/activate uv pip install -e ".[dev]" pytest ``` ## License MIT