Doanh Van Vu commited on
Commit
69934b0
·
1 Parent(s): 7083cd1

Refactor mentor availability handling across services

Browse files

- Removed the `available_slots` and `has_availability` fields from the MentorUpsertRequest and RecommendationRequest models, streamlining the data structure.
- Updated the PineconeService and RecommendationService to eliminate references to availability metrics in logging and processing.
- Simplified scoring logic in the rerank_mentors function by removing the availability score calculation, enhancing performance and clarity.
- Adjusted the mentor text building process to exclude available slots information, improving the output format.

models/schemas.py CHANGED
@@ -45,13 +45,11 @@ class MentorUpsertRequest(BaseModel):
45
  rating: Optional[float] = Field(None, ge=0.0, le=5.0)
46
  total_ratings: Optional[int] = Field(None, ge=0)
47
  session_count: Optional[int] = Field(None, ge=0)
48
- available_slots: Optional[int] = Field(None, ge=0)
49
  schedules: Optional[List[Union[ScheduleDto, Dict[str, Any]]]] = None
50
  career_id: Optional[int] = None
51
  skill_ids: Optional[List[int]] = None
52
  domain_ids: Optional[List[int]] = None
53
  status: Optional[str] = "ACTIVATED"
54
- has_availability: Optional[bool] = False
55
 
56
  class MentorUpsertResponse(BaseModel):
57
  success: bool
@@ -67,7 +65,6 @@ class RecommendationRequest(BaseModel):
67
  availability: Optional[str] = None
68
  preferred_availability: Optional[str] = None
69
  min_rating: Optional[float] = Field(None, ge=0.0, le=5.0)
70
- require_availability: Optional[bool] = False
71
  skill_ids: Optional[List[int]] = None
72
  domain_ids: Optional[List[int]] = None
73
  career_id: Optional[int] = None
 
45
  rating: Optional[float] = Field(None, ge=0.0, le=5.0)
46
  total_ratings: Optional[int] = Field(None, ge=0)
47
  session_count: Optional[int] = Field(None, ge=0)
 
48
  schedules: Optional[List[Union[ScheduleDto, Dict[str, Any]]]] = None
49
  career_id: Optional[int] = None
50
  skill_ids: Optional[List[int]] = None
51
  domain_ids: Optional[List[int]] = None
52
  status: Optional[str] = "ACTIVATED"
 
53
 
54
  class MentorUpsertResponse(BaseModel):
55
  success: bool
 
65
  availability: Optional[str] = None
66
  preferred_availability: Optional[str] = None
67
  min_rating: Optional[float] = Field(None, ge=0.0, le=5.0)
 
68
  skill_ids: Optional[List[int]] = None
69
  domain_ids: Optional[List[int]] = None
70
  career_id: Optional[int] = None
services/pinecone_service.py CHANGED
@@ -135,9 +135,7 @@ class PineconeService:
135
  f"score={match.score:.4f}, "
136
  f"rating={metadata.get('rating', 'N/A')}, "
137
  f"total_ratings={metadata.get('total_ratings', 0)}, "
138
- f"available_slots={metadata.get('available_slots', 0)}, "
139
  f"session_count={metadata.get('session_count', 0)}, "
140
- f"has_availability={metadata.get('has_availability', False)}, "
141
  f"status={metadata.get('status', 'N/A')}, "
142
  f"career_id={metadata.get('career_id', 'N/A')}, "
143
  f"skill_ids={metadata.get('skill_ids', [])}, "
 
135
  f"score={match.score:.4f}, "
136
  f"rating={metadata.get('rating', 'N/A')}, "
137
  f"total_ratings={metadata.get('total_ratings', 0)}, "
 
138
  f"session_count={metadata.get('session_count', 0)}, "
 
139
  f"status={metadata.get('status', 'N/A')}, "
140
  f"career_id={metadata.get('career_id', 'N/A')}, "
141
  f"skill_ids={metadata.get('skill_ids', [])}, "
services/recommendation_service.py CHANGED
@@ -45,8 +45,6 @@ class RecommendationService:
45
  "rating": safe_float(mentor_data.get("rating"), 0.0),
46
  "total_ratings": safe_int(mentor_data.get("total_ratings"), 0),
47
  "session_count": safe_int(mentor_data.get("session_count"), 0),
48
- "available_slots": safe_int(mentor_data.get("available_slots"), 0),
49
- "has_availability": bool(mentor_data.get("has_availability", False)),
50
  "career_id": safe_int(mentor_data.get("career_id")) if mentor_data.get("career_id") else None,
51
  "status": str(mentor_data.get("status") or "ACTIVATED"),
52
  "mentor_text": mentor_text
 
45
  "rating": safe_float(mentor_data.get("rating"), 0.0),
46
  "total_ratings": safe_int(mentor_data.get("total_ratings"), 0),
47
  "session_count": safe_int(mentor_data.get("session_count"), 0),
 
 
48
  "career_id": safe_int(mentor_data.get("career_id")) if mentor_data.get("career_id") else None,
49
  "status": str(mentor_data.get("status") or "ACTIVATED"),
50
  "mentor_text": mentor_text
test_api.py CHANGED
@@ -18,7 +18,6 @@ def test_recommend():
18
  {"id": 1, "name": "Web Development"}
19
  ],
20
  "min_rating": 4.0,
21
- "require_availability": True,
22
  "skill_ids": [1, 2],
23
  "domain_ids": [1],
24
  "top_k": 30,
@@ -63,7 +62,6 @@ def test_recommend():
63
  if "metadata" in mentor:
64
  meta = mentor["metadata"]
65
  print(f" Rating: {meta.get('rating', 'N/A')}")
66
- print(f" Available Slots: {meta.get('available_slots', 0)}")
67
 
68
  if "query_text" in result:
69
  print(f"\nQuery Text: {result['query_text']}")
 
18
  {"id": 1, "name": "Web Development"}
19
  ],
20
  "min_rating": 4.0,
 
21
  "skill_ids": [1, 2],
22
  "domain_ids": [1],
23
  "top_k": 30,
 
62
  if "metadata" in mentor:
63
  meta = mentor["metadata"]
64
  print(f" Rating: {meta.get('rating', 'N/A')}")
 
65
 
66
  if "query_text" in result:
67
  print(f"\nQuery Text: {result['query_text']}")
utils/scoring.py CHANGED
@@ -28,12 +28,8 @@ def rerank_mentors(
28
  semantic_score = reranker_score * settings.SEMANTIC_WEIGHT
29
 
30
  rating_score = _calculate_rating_score(metadata.get("rating", 0.0))
31
- availability_score = _calculate_availability_score(metadata.get("available_slots", 0))
32
 
33
- rule_based_score = (
34
- rating_score * 0.5 +
35
- availability_score * 0.5
36
- ) * settings.RULE_BASED_WEIGHT
37
 
38
  final_score = semantic_score + rule_based_score
39
 
@@ -43,8 +39,7 @@ def rerank_mentors(
43
  reranker_score,
44
  metadata,
45
  mentee_data,
46
- rating_score,
47
- availability_score
48
  )
49
 
50
  scored_mentors.append({
@@ -75,20 +70,12 @@ def _calculate_rating_score(rating: float) -> float:
75
  return 0.0
76
  return min(rating / 5.0, 1.0)
77
 
78
- def _calculate_availability_score(available_slots: int) -> float:
79
- if available_slots <= 0:
80
- return 0.0
81
- if available_slots >= 10:
82
- return 1.0
83
- return min(available_slots / 10.0, 1.0)
84
-
85
 
86
  def _generate_reason(
87
  reranker_score: float,
88
  metadata: Dict[str, Any],
89
  mentee_data: Dict[str, Any],
90
- rating_score: float,
91
- availability_score: float
92
  ) -> str:
93
  reasons = []
94
 
@@ -103,10 +90,6 @@ def _generate_reason(
103
  elif rating >= 4.0:
104
  reasons.append("High ratings")
105
 
106
- available_slots = metadata.get("available_slots", 0)
107
- if available_slots > 0:
108
- reasons.append("Has available slots")
109
-
110
  if not reasons:
111
  reasons.append("Good overall match")
112
 
 
28
  semantic_score = reranker_score * settings.SEMANTIC_WEIGHT
29
 
30
  rating_score = _calculate_rating_score(metadata.get("rating", 0.0))
 
31
 
32
+ rule_based_score = rating_score * settings.RULE_BASED_WEIGHT
 
 
 
33
 
34
  final_score = semantic_score + rule_based_score
35
 
 
39
  reranker_score,
40
  metadata,
41
  mentee_data,
42
+ rating_score
 
43
  )
44
 
45
  scored_mentors.append({
 
70
  return 0.0
71
  return min(rating / 5.0, 1.0)
72
 
 
 
 
 
 
 
 
73
 
74
  def _generate_reason(
75
  reranker_score: float,
76
  metadata: Dict[str, Any],
77
  mentee_data: Dict[str, Any],
78
+ rating_score: float
 
79
  ) -> str:
80
  reasons = []
81
 
 
90
  elif rating >= 4.0:
91
  reasons.append("High ratings")
92
 
 
 
 
 
93
  if not reasons:
94
  reasons.append("Good overall match")
95
 
utils/text_builder.py CHANGED
@@ -99,10 +99,6 @@ def build_mentor_text(mentor_data: Dict[str, Any]) -> str:
99
  if session_count:
100
  parts.append(f"Sessions Conducted: {session_count}")
101
 
102
- available_slots = mentor_data.get("available_slots", 0)
103
- if available_slots:
104
- parts.append(f"Available Slots: {available_slots}")
105
-
106
  schedules = mentor_data.get("schedules", [])
107
  if schedules:
108
  schedule_summary = _build_schedule_summary(schedules)
 
99
  if session_count:
100
  parts.append(f"Sessions Conducted: {session_count}")
101
 
 
 
 
 
102
  schedules = mentor_data.get("schedules", [])
103
  if schedules:
104
  schedule_summary = _build_schedule_summary(schedules)