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
+35 -15
View File
@@ -1,15 +1,16 @@
from __future__ import annotations
from collections.abc import Iterable
from dataclasses import dataclass
from difflib import SequenceMatcher
from typing import Any, Iterable
from typing import Any
from django.db import transaction
from apps.jobs.models import JobPosting, ScoreRun
from apps.jobs.services.ai import AiAnalysis, AiAnalysisCache, analyze_job_text
from apps.jobs.services.distance import estimate_commute, haversine_km
from apps.jobs.services.geocoding import resolve_cached_location
from apps.jobs.models import JobPosting, ScoreRun
from apps.profiles.models import SearchProfile
from .normalization import normalize_token
@@ -106,7 +107,9 @@ def _profile_reference(profile: SearchProfile) -> _GeoReference | None:
def _title_fit(job: JobPosting, profile: SearchProfile) -> float:
if not profile.desired_titles:
return 0.65
return max(_similarity(job.normalized_title, desired_title) for desired_title in profile.desired_titles)
return max(
_similarity(job.normalized_title, desired_title) for desired_title in profile.desired_titles
)
def _skill_fit(job: JobPosting, profile: SearchProfile) -> tuple[float, list[str], list[str]]:
@@ -191,9 +194,15 @@ def _hard_exclusions(
):
reasons.append(f"Uitgesloten regio: {job.region or job.municipality}")
if distance.exact_distance_km is not None and distance.exact_distance_km > distance_limit:
if job.workplace_type != "remote":
reasons.append(f"Afstand {distance.exact_distance_km:.0f} km boven maximum {profile.max_distance_km} km")
if (
distance.exact_distance_km is not None
and distance.exact_distance_km > distance_limit
and job.workplace_type != "remote"
):
reasons.append(
f"Afstand {distance.exact_distance_km:.0f} km boven maximum "
f"{profile.max_distance_km} km"
)
max_commute_minutes = profile.hard_rules.get("max_commute_minutes")
try:
@@ -206,7 +215,8 @@ def _hard_exclusions(
and distance.commute_minutes > max_commute_limit
):
reasons.append(
f"Geschatte reistijd {distance.commute_minutes} minuten boven limiet van {max_commute_limit}"
f"Geschatte reistijd {distance.commute_minutes} minuten boven limiet van "
f"{max_commute_limit}"
)
excluded_skills = {
@@ -244,7 +254,9 @@ def _ai_feature_score(features: dict[str, Any]) -> float:
"unknown": 0.03,
"": 0.03,
}.get(seniority, 0.05)
score = 0.5 * (1.0 - support_ratio) + 0.25 * (1.0 - consultancy_ratio) + 0.15 * (1.0 - travel_ratio)
score = (
0.5 * (1.0 - support_ratio) + 0.25 * (1.0 - consultancy_ratio) + 0.15 * (1.0 - travel_ratio)
)
return max(0.0, min(1.0, score + seniority_boost))
@@ -373,7 +385,10 @@ def calculate_score(job: JobPosting, profile: SearchProfile) -> ScoreResult:
positives.append("Herkenbare skills: " + ", ".join(present_skills[:6]))
if job.direct_employer and not job.recruiter:
positives.append("Rechtstreekse werkgeversbron.")
if distance.exact_distance_km is not None and distance.exact_distance_km <= profile.max_distance_km:
if (
distance.exact_distance_km is not None
and distance.exact_distance_km <= profile.max_distance_km
):
positives.append(f"Binnen de ingestelde afstand ({distance.exact_distance_km:.0f} km).")
if (
distance.exact_distance_km is None
@@ -382,13 +397,18 @@ def calculate_score(job: JobPosting, profile: SearchProfile) -> ScoreResult:
):
estimate_label = "geschatte" if distance.commute_estimate else "ingeschatte"
concerns.append(
f"Schatting: {estimate_label} reistijd ca. {distance.commute_minutes} min (conservatief)."
f"Schatting: {estimate_label} reistijd ca. {distance.commute_minutes} min "
"(conservatief)."
)
if support_ratio >= 0.5:
concerns.append("Vacature bevat sterke first-line/helpdesksignalen.")
if missing_skills:
concerns.append("Niet duidelijk teruggevonden: " + ", ".join(missing_skills[:6]))
if distance.exact_distance_km is None and distance.has_distance_data and job.workplace_type != "remote":
if (
distance.exact_distance_km is None
and distance.has_distance_data
and job.workplace_type != "remote"
):
concerns.append("Afstand kon nog niet exact betrouwbaar worden berekend.")
if not job.compensation:
concerns.append("Salaris of barema is niet vermeld.")
@@ -436,7 +456,9 @@ def calculate_score(job: JobPosting, profile: SearchProfile) -> ScoreResult:
"warnings": ai_analysis.warnings,
"features": ai_analysis.features,
"weight_requested": float(profile.weights.get("ai", 0) or 0),
"weight_applied": ai_weight if ai_analysis.status == AiAnalysisCache.Status.OK else 0.0,
"weight_applied": ai_weight
if ai_analysis.status == AiAnalysisCache.Status.OK
else 0.0,
},
},
model_version=ai_analysis.model,
@@ -451,9 +473,7 @@ def _iter_active_profiles(profile_id: int | None):
return profiles
def rescore_jobs_with_profiles(
jobs: Iterable[JobPosting], *, profile_id: int | None = None
) -> int:
def rescore_jobs_with_profiles(jobs: Iterable[JobPosting], *, profile_id: int | None = None) -> int:
count = 0
for profile in _iter_active_profiles(profile_id):
for job in jobs: