from inbox.models import Inbox from typing import Any,List,Dict from job.candidate.plugins import documents_from_message, source_from_message_to from job.interviews.serializers import serialize_interview from job.activity.serializers import serialize_activity from job.feedback.serializers import serialize_feedback def serialize_candidate(row) -> dict: return { "id": str(row.id), "job_id": str(row.job_id), "inbox_message_id": str(row.inbox_message_id) if row.inbox_message_id else None, "source": row.source, "filename": row.filename, "file_path": row.file_path, "content_sha256": row.content_sha256, "candidate_name": row.candidate_name, "job_title": row.job_title, "current_company": row.current_company, "years_experience": row.years_experience, "match_score": row.match_score, "matched_keywords": list(row.matched_keywords or []), "missing_keywords": list(row.missing_keywords or []), "summary_critique": row.summary_critique, "status": row.status, "error_code": row.error_code, "error_message": row.error_message, "model": row.model, "created_by": str(row.created_by), "created_at": row.created_at.isoformat() if row.created_at else None, "updated_at": row.updated_at.isoformat() if row.updated_at else None, } def serialize_manual_upload_candidate(row) -> Dict[str,Any]: return { "id":str(row.id) if row.id else None, "candidate_email":row.candidate_email, "candidate_name":row.candidate_name, "candidate_phone":row.candidate_phone, "job_post_id":str(row.job_post_id) if row.job_post_id else None, "full_text":row.full_text, "current_company":row.current_company, "user_id":str(row.user_id) if row.user_id else None, "platform":row.platform, "created_by":str(row.created_by) if row.created_by else None, "experience":row.experience, "status":row.status, "referral_by":row.referral_by, "file_name":row.file_name, "file_path":row.file_path, "created_at":row.created_at.isoformat() if row.created_at else None, "updated_at":row.updated_at.isoformat() if row.updated_at else None, } def serialize_candidate_profile( link:Inbox|List[Inbox]|Dict[str,Any]|List[Dict[str,Any]], *, detail:bool=False, ) -> Dict[str,Any]|List[Dict[str,Any]]: if isinstance(link,list): return [serialize_candidate_profile(item,detail=detail) for item in link] if isinstance(link,dict): return link user = link.user message = link.messages payload = { "inbox_id": link.id, "user_id": str(link.user_id) if link.user_id else None, "name": user.name if user else None, "email": user.email if user else None, "is_active": user.is_active if user else None, "message_id": str(link.message_id) if link.message_id else None, "created_at": link.created_at.isoformat() if link.created_at else None, "application_status": message.application_status if message else None, "experience": message.experience if message else None, "current_employment": message.current_employment if message else None, "resume_text": message.resume_text if message else None, "suggested_job_post_ids": list(message.suggested_job_post_ids or []) if message else [], "assigned_job_post_id": str(message.assigned_job_post_id) if message and message.assigned_job_post_id else None, "match_summary": message.match_summary if message else None, "match_reasoning": message.match_reasoning if message else None, "match_status": message.match_status if message else None, "match_error": message.match_error if message else None, "matched_at": message.matched_at.isoformat() if message and message.matched_at else None, "job_posts": [], } if not detail: return payload payload.update({ "favorite": link.favorite, "rating": link.rating, "phone": message.candidate_phone_number if message else None, "education": message.candidate_education if message else None, "currentCompany": message.current_employment if message else None, "stage": message.application_status if message else None, "source": source_from_message_to(message.message_to if message else None), "applied": message.message_received_time if message else None, "documents": documents_from_message( message.file_name if message else None, message.file_path if message else None, ), "recruiter": None, "recruiter_id": None, "job_title": None, "ai_score": None, "recommendation": None, "sub_scores": None, "interviews": [serialize_interview(r) for r in (link.interviews or [])], "activity": [serialize_activity(r) for r in (link.activity or [])], "feedback": [serialize_feedback(r) for r in (link.feedback or [])], "notes": [], }) return payload