HR-ATS-Portal/backend/talent/serializers.py

61 lines
2.9 KiB
Python

from talent.plugins import extract_education, extract_experience
def serialize_talent_run(row) -> dict:
return {
"id": str(row.id) if row.id else None,
"job_post_id": str(row.job_post_id) if row.job_post_id else None,
"status": row.status,
"actor_id": row.actor_id,
"search_input": row.search_input or {},
"max_results": row.max_results,
"profiles_found": row.profiles_found,
"apify_run_id": row.apify_run_id,
"apify_error": row.apify_error,
"started_at": row.started_at.isoformat() if row.started_at else None,
"finished_at": row.finished_at.isoformat() if row.finished_at else None,
"created_at": row.created_at.isoformat() if row.created_at else None,
}
def serialize_talent_profile(row, *, user_names=None) -> dict:
# `raw` stays server-side: it is an actor-shaped blob that can be large and
# is only needed for debugging/re-mapping, not for the profile cards.
# `user_names` maps str(user_id) -> name for the shortlisted_by/contacted_by
# stamps (resolved by the caller in one query, Users.names_by_ids).
names = user_names or {}
return {
"id": str(row.id) if row.id else None,
"job_post_id": str(row.job_post_id) if row.job_post_id else None,
"linkedin_url": row.linkedin_url,
"public_id": row.public_id,
"full_name": row.full_name,
"headline": row.headline,
"location": row.location,
"current_title": row.current_title,
"current_company": row.current_company,
"avatar_url": row.avatar_url,
"summary": row.summary,
"skills": row.skills or [],
"match_score": row.match_score,
"outreach_status": row.outreach_status,
"shortlisted_at": row.shortlisted_at.isoformat() if row.shortlisted_at else None,
"shortlisted_by": str(row.shortlisted_by) if row.shortlisted_by else None,
"shortlisted_by_name": names.get(str(row.shortlisted_by)) if row.shortlisted_by else None,
"contacted_at": row.contacted_at.isoformat() if row.contacted_at else None,
"contacted_by": str(row.contacted_by) if row.contacted_by else None,
"contacted_by_name": names.get(str(row.contacted_by)) if row.contacted_by else None,
"first_seen_at": row.first_seen_at.isoformat() if row.first_seen_at else None,
"last_seen_at": row.last_seen_at.isoformat() if row.last_seen_at else None,
}
def serialize_talent_profile_detail(row, *, user_names=None) -> dict:
# The card payload plus employment/education history unpacked from the raw
# actor item. Detail is fetched one profile at a time, so the extra weight
# never rides along with the list endpoint.
data = serialize_talent_profile(row, user_names=user_names)
data["experience"] = extract_experience(row.raw or {})
data["education"] = extract_education(row.raw or {})
return data