Publish curated VacatureRadar source snapshot
This commit is contained in:
commit
e29774cb7f
338 files changed
+32699
No files matched your search
@@ -0,0 +1,64 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from django.db import transaction
|
||||
|
||||
from apps.jobs.services.geocoding import LocationMatchResult, resolve_cached_location
|
||||
|
||||
from .models import ProfileRevision, SearchProfile
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def resolve_profile_home_location(profile: SearchProfile) -> LocationMatchResult:
|
||||
"""Resolve a user-entered postal code without exposing coordinate fields in the UI."""
|
||||
query = profile.home_postal_code.strip()
|
||||
result = (
|
||||
resolve_cached_location(query) if query else LocationMatchResult(query=query, location=None)
|
||||
)
|
||||
location = result.location
|
||||
profile.home_municipality = location.municipality or "" if location else ""
|
||||
profile.home_latitude = location.point.latitude if location and location.point else None
|
||||
profile.home_longitude = location.point.longitude if location and location.point else None
|
||||
profile.save(
|
||||
update_fields=[
|
||||
"home_municipality",
|
||||
"home_latitude",
|
||||
"home_longitude",
|
||||
"updated_at",
|
||||
]
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def save_profile_revision(profile: SearchProfile, *, reason: str) -> ProfileRevision:
|
||||
latest = profile.revisions.order_by("-version").first()
|
||||
next_version = (latest.version if latest else 0) + 1
|
||||
if profile.version != next_version:
|
||||
profile.version = next_version
|
||||
profile.save(update_fields=["version", "updated_at"])
|
||||
return ProfileRevision.objects.create(
|
||||
profile=profile,
|
||||
version=next_version,
|
||||
snapshot=profile.snapshot(),
|
||||
reason=reason,
|
||||
)
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def apply_feedback_delta(
|
||||
profile: SearchProfile,
|
||||
feature: str,
|
||||
delta: float,
|
||||
*,
|
||||
min_weight: float = 0.0,
|
||||
max_weight: float = 40.0,
|
||||
) -> SearchProfile:
|
||||
if not profile.learning_enabled:
|
||||
return profile
|
||||
weights = dict(profile.weights)
|
||||
current = float(weights.get(feature, 0.0))
|
||||
weights[feature] = round(max(min_weight, min(max_weight, current + delta)), 2)
|
||||
profile.weights = weights
|
||||
profile.save(update_fields=["weights", "updated_at"])
|
||||
save_profile_revision(profile, reason=f"feedback_delta:{feature}:{delta:+.2f}")
|
||||
return profile
|
||||
Reference in new issue
Block a user