You've already forked RekomenciBackend
fix(): update schemas
This commit is contained in:
@@ -136,35 +136,89 @@ class ResumeListItemResponse:
|
||||
about_me: str
|
||||
key_skills: list[str]
|
||||
experience_type: ExperienceType
|
||||
experience: list[ExperienceItemResponse]
|
||||
education: list[EducationItemResponse]
|
||||
projects: list[ProjectItemResponse]
|
||||
prediction: ResumePredictionResponse | None
|
||||
|
||||
|
||||
@to_interactor
|
||||
class GetResumeListInteractor:
|
||||
identity_provider: IdentityProvider
|
||||
resume_data_gateway: ResumeDataGateway
|
||||
resume_prediction_data_gateway: ResumePredictionDataGateway
|
||||
resume_experience_data_gateway: ResumeExperienceDataGateway
|
||||
resume_education_data_gateway: ResumeEducationDataGateway
|
||||
resume_project_data_gateway: ResumeProjectDataGateway
|
||||
|
||||
async def execute(self, limit: int, offset: int) -> list[ResumeListItemResponse]:
|
||||
user = await self.identity_provider.get_current_user()
|
||||
|
||||
resumes = await self.resume_data_gateway.list_latest_by_user_id(user.id, limit=limit, offset=offset)
|
||||
|
||||
return [
|
||||
ResumeListItemResponse(
|
||||
id=r.id,
|
||||
position=r.position,
|
||||
location=r.location,
|
||||
about_me=r.about_me,
|
||||
key_skills=r.key_skills,
|
||||
experience_type=r.experience_type,
|
||||
result = []
|
||||
for r in resumes:
|
||||
resume_prediction = await self.resume_prediction_data_gateway.load_by_resume_id(r.id)
|
||||
if resume_prediction is not None:
|
||||
prediction = ResumePredictionResponse(
|
||||
from_salary=resume_prediction.from_salary,
|
||||
to_salary=resume_prediction.to_salary,
|
||||
recommended_skills=resume_prediction.recommended_skills,
|
||||
)
|
||||
else:
|
||||
prediction = None
|
||||
|
||||
experiences = await self.resume_experience_data_gateway.load_by_resume_id(r.id)
|
||||
educations = await self.resume_education_data_gateway.load_by_resume_id(r.id)
|
||||
projects = await self.resume_project_data_gateway.load_by_resume_id(r.id)
|
||||
|
||||
result.append(
|
||||
ResumeListItemResponse(
|
||||
id=r.id,
|
||||
position=r.position,
|
||||
location=r.location,
|
||||
about_me=r.about_me,
|
||||
key_skills=r.key_skills,
|
||||
experience_type=r.experience_type,
|
||||
experience=[
|
||||
ExperienceItemResponse(
|
||||
place=exp.place,
|
||||
description=exp.description,
|
||||
months_duration=exp.months_duration,
|
||||
)
|
||||
for exp in experiences
|
||||
],
|
||||
education=[
|
||||
EducationItemResponse(
|
||||
place=edu.place,
|
||||
grade=edu.grade,
|
||||
specialization=edu.specialization,
|
||||
description=edu.description,
|
||||
)
|
||||
for edu in educations
|
||||
],
|
||||
projects=[
|
||||
ProjectItemResponse(
|
||||
name=proj.name,
|
||||
description=proj.description,
|
||||
)
|
||||
for proj in projects
|
||||
],
|
||||
prediction=prediction,
|
||||
)
|
||||
)
|
||||
for r in resumes
|
||||
]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@to_interactor
|
||||
class GetResumeHistoryInteractor:
|
||||
identity_provider: IdentityProvider
|
||||
resume_data_gateway: ResumeDataGateway
|
||||
resume_prediction_data_gateway: ResumePredictionDataGateway
|
||||
resume_experience_data_gateway: ResumeExperienceDataGateway
|
||||
resume_education_data_gateway: ResumeEducationDataGateway
|
||||
resume_project_data_gateway: ResumeProjectDataGateway
|
||||
|
||||
async def execute(self, resume_id: ResumeId) -> list[ResumeListItemResponse]:
|
||||
user = await self.identity_provider.get_current_user()
|
||||
@@ -177,14 +231,56 @@ class GetResumeHistoryInteractor:
|
||||
|
||||
history = await self.resume_data_gateway.get_history(resume_id)
|
||||
|
||||
return [
|
||||
ResumeListItemResponse(
|
||||
id=r.id,
|
||||
position=r.position,
|
||||
location=r.location,
|
||||
about_me=r.about_me,
|
||||
key_skills=r.key_skills,
|
||||
experience_type=r.experience_type,
|
||||
result = []
|
||||
for r in history:
|
||||
resume_prediction = await self.resume_prediction_data_gateway.load_by_resume_id(r.id)
|
||||
if resume_prediction is not None:
|
||||
prediction = ResumePredictionResponse(
|
||||
from_salary=resume_prediction.from_salary,
|
||||
to_salary=resume_prediction.to_salary,
|
||||
recommended_skills=resume_prediction.recommended_skills,
|
||||
)
|
||||
else:
|
||||
prediction = None
|
||||
|
||||
experiences = await self.resume_experience_data_gateway.load_by_resume_id(r.id)
|
||||
educations = await self.resume_education_data_gateway.load_by_resume_id(r.id)
|
||||
projects = await self.resume_project_data_gateway.load_by_resume_id(r.id)
|
||||
|
||||
result.append(
|
||||
ResumeListItemResponse(
|
||||
id=r.id,
|
||||
position=r.position,
|
||||
location=r.location,
|
||||
about_me=r.about_me,
|
||||
key_skills=r.key_skills,
|
||||
experience_type=r.experience_type,
|
||||
experience=[
|
||||
ExperienceItemResponse(
|
||||
place=exp.place,
|
||||
description=exp.description,
|
||||
months_duration=exp.months_duration,
|
||||
)
|
||||
for exp in experiences
|
||||
],
|
||||
education=[
|
||||
EducationItemResponse(
|
||||
place=edu.place,
|
||||
grade=edu.grade,
|
||||
specialization=edu.specialization,
|
||||
description=edu.description,
|
||||
)
|
||||
for edu in educations
|
||||
],
|
||||
projects=[
|
||||
ProjectItemResponse(
|
||||
name=proj.name,
|
||||
description=proj.description,
|
||||
)
|
||||
for proj in projects
|
||||
],
|
||||
prediction=prediction,
|
||||
)
|
||||
)
|
||||
for r in history
|
||||
]
|
||||
|
||||
return result
|
||||
|
||||
@@ -41,23 +41,21 @@ def _filter_and_sort_vacancies(
|
||||
suitable_vacancies: list[SuitableVacancy],
|
||||
limit: int = 50,
|
||||
) -> list[SuitableVacancy]:
|
||||
def is_suitable(vacancy: SuitableVacancy) -> bool:
|
||||
experience_match = resume.experience_type == vacancy.vacancy.experience_type
|
||||
skills_matching = _calculate_skills_matching(resume.key_skills, vacancy.vacancy.key_skills)
|
||||
skills_match = skills_matching >= 0.5
|
||||
return experience_match and skills_match
|
||||
def calculate_priority(vacancy: SuitableVacancy) -> float:
|
||||
priority = vacancy.resume_similarity
|
||||
|
||||
filtered = [v for v in suitable_vacancies if is_suitable(v)]
|
||||
if resume.experience_type == vacancy.vacancy.experience_type:
|
||||
priority += 0.1
|
||||
|
||||
if len(filtered) >= limit:
|
||||
filtered.sort(key=lambda v: v.resume_similarity, reverse=True)
|
||||
return filtered[:limit]
|
||||
if resume.key_skills:
|
||||
skills_matching = _calculate_skills_matching(resume.key_skills, vacancy.vacancy.key_skills)
|
||||
priority += skills_matching * 0.2
|
||||
|
||||
remaining = [v for v in suitable_vacancies if v not in filtered]
|
||||
remaining.sort(key=lambda v: v.resume_similarity, reverse=True)
|
||||
return priority
|
||||
|
||||
total_needed = limit - len(filtered)
|
||||
return filtered + remaining[:total_needed]
|
||||
sorted_vacancies = sorted(suitable_vacancies, key=calculate_priority, reverse=True)
|
||||
|
||||
return sorted_vacancies[:limit]
|
||||
|
||||
|
||||
@to_data_structure
|
||||
|
||||
Reference in New Issue
Block a user