Fix release blockers and deployment build
deploy / deploy (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-21 21:22:29 +02:00
parent b8091e59bd
commit a4eced8be5
64 changed files with 1011 additions and 675 deletions
+40 -16
View File
@@ -9,7 +9,6 @@ from apps.sources.models import Source
from .normalization import CanonicalJobDraft, normalize_token
MERGE_THRESHOLD = 0.96
TITLE_MIN_THRESHOLD = 0.92
CONFLICT_TITLE_THRESHOLD = 0.70
@@ -46,11 +45,13 @@ def _weighted_similarity(
employer_domain_match: bool,
canonical_host_match: bool,
) -> float:
weights: list[tuple[float, float]] = [(title_score, 0.68), (employer_domain_match and 1.0 or 0.0, 0.12)]
weights: list[tuple[float, float]] = [(title_score, 0.68)]
if location_score is not None:
weights.append((location_score, 0.12))
if employer_score is not None:
weights.append((employer_score, 0.06))
if employer_domain_match:
weights.append((1.0, 0.12))
if canonical_host_match:
weights.append((1.0, 0.05))
total_weight = sum(weight for _, weight in weights)
@@ -62,7 +63,10 @@ def _weighted_similarity(
def _domain_match(value: str, candidate: str) -> bool:
if not value or not candidate:
return False
return _normalize_similarity(value).strip(".").lower() == _normalize_similarity(candidate).strip(".").lower()
return (
_normalize_similarity(value).strip(".").lower()
== _normalize_similarity(candidate).strip(".").lower()
)
def _host(value: str) -> str:
@@ -73,12 +77,18 @@ def resolve_direct_employer_match(
draft: CanonicalJobDraft, *, source: Source | None
) -> EmployerResolutionDecision:
if source is None or source.source_type == Source.Type.EMPLOYER or not draft.normalized_title:
return EmployerResolutionDecision(None, "no_direct_resolution", 0.0, canonical_url=None, conflict=False)
return EmployerResolutionDecision(
None, "no_direct_resolution", 0.0, canonical_url=None, conflict=False
)
candidates = JobPosting.objects.filter(
status__in=[JobPosting.Status.ACTIVE, JobPosting.Status.NEW],
direct_employer=True,
).select_related("employer").order_by("id")
candidates = (
JobPosting.objects.filter(
status__in=[JobPosting.Status.ACTIVE, JobPosting.Status.NEW],
direct_employer=True,
)
.select_related("employer")
.order_by("id")
)
best: JobPosting | None = None
best_score = 0.0
@@ -92,7 +102,13 @@ def resolve_direct_employer_match(
continue
location_score: float | None = None
if draft.location_text and candidate.raw_location:
if (
draft.municipality
and candidate.municipality
and normalize_token(draft.municipality) == normalize_token(candidate.municipality)
):
location_score = 1.0
elif draft.location_text and candidate.raw_location:
location_score = _token_similarity(draft.location_text, candidate.raw_location)
employer_score: float | None = None
@@ -112,15 +128,23 @@ def resolve_direct_employer_match(
canonical_host_match=canonical_host_match,
)
has_conflict = False
if draft.location_text and candidate.raw_location:
if location_score is not None and location_score < CONFLICT_LOCATION_THRESHOLD:
has_conflict = True
if draft.employer_name and candidate.employer_name and (
employer_score is not None and employer_score < CONFLICT_EMPLOYER_THRESHOLD
has_conflict = bool(
draft.location_text
and candidate.raw_location
and location_score is not None
and location_score < CONFLICT_LOCATION_THRESHOLD
)
if (
draft.employer_name
and candidate.employer_name
and (employer_score is not None and employer_score < CONFLICT_EMPLOYER_THRESHOLD)
):
has_conflict = True
if draft.employer_name and not candidate.employer_name and title_score < CONFLICT_TITLE_THRESHOLD:
if (
draft.employer_name
and not candidate.employer_name
and title_score < CONFLICT_TITLE_THRESHOLD
):
has_conflict = True
if score > best_score: