@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from django.db import transaction
|
||||
|
||||
from .models import ProfileRevision, SearchProfile
|
||||
|
||||
|
||||
@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