botboss-backend / services /application_manager.py
muhammadtabishkha's picture
Resume analysis upgrade: structured CV↔JD analysis (sub-scores, matched/missing skills, experience, summary, verdict), .docx parsing, strong skills-based fallback; store full cv_analysis
46df6a4
Raw
History Blame Contribute Delete
4.45 kB
import uuid
from datetime import datetime
from services.db import applications_col
import logging
logger = logging.getLogger(__name__)
def create_application(data):
"""
Create a new application record in database
"""
try:
application = {
"id": str(uuid.uuid4()),
"job_id": data.get("job_id"),
"user_id": data.get("user_id"),
"candidate_name": data.get("candidate_name"),
"candidate_email": data.get("candidate_email"),
"cover_letter": data.get("cover_letter", ""),
"resume_path": data.get("resume_path"),
"cv_text": data.get("cv_text", ""),
"cv_score": data.get("cv_score", 0),
"cv_analysis": data.get("cv_analysis"), # full CV↔JD breakdown for recruiters
"status": data.get("status", "pending"),
"applied_at": data.get("applied_at", datetime.now().isoformat()),
"updated_at": datetime.now().isoformat()
}
applications_col.insert_one(application)
application.pop("_id", None)
logger.info(f"✅ Application created: {application['id']} for user {application['user_id']}")
return application
except Exception as e:
logger.error(f"Error creating application: {e}")
raise e
def get_applications_by_job(job_id):
"""
Get all applications for a specific job
"""
try:
apps = list(applications_col.find({"job_id": job_id}))
for app in apps:
app.pop("_id", None)
logger.info(f"Found {len(apps)} applications for job {job_id}")
return apps
except Exception as e:
logger.error(f"Error getting applications by job: {e}")
return []
def get_applications_by_user(user_id):
"""
Get all applications by a specific user (candidate)
"""
try:
apps = list(applications_col.find({"user_id": user_id}))
for app in apps:
app.pop("_id", None)
logger.info(f"Found {len(apps)} applications for user {user_id}")
return apps
except Exception as e:
logger.error(f"Error getting applications by user: {e}")
return []
def get_application_by_id(application_id):
"""
Get a single application by ID
"""
try:
app = applications_col.find_one({"id": application_id})
if app:
app.pop("_id", None)
return app
except Exception as e:
logger.error(f"Error getting application: {e}")
return None
def update_status(application_id, new_status):
"""
Update the status of an application
"""
try:
applications_col.update_one(
{"id": application_id},
{"$set": {
"status": new_status,
"updated_at": datetime.now().isoformat()
}}
)
app = get_application_by_id(application_id)
logger.info(f"✅ Application {application_id} status updated to {new_status}")
return app
except Exception as e:
logger.error(f"Error updating application status: {e}")
raise e
def update_cv_score(application_id, cv_score):
"""
Update the CV score for an application
"""
try:
applications_col.update_one(
{"id": application_id},
{"$set": {
"cv_score": cv_score,
"updated_at": datetime.now().isoformat()
}}
)
logger.info(f"✅ CV score updated for {application_id}: {cv_score}%")
return get_application_by_id(application_id)
except Exception as e:
logger.error(f"Error updating CV score: {e}")
raise e
def get_applications_by_company(company_id):
"""
Get all applications for jobs posted by a company
This requires joining with jobs collection
"""
try:
from services.job_manager import get_jobs_by_company
company_jobs = get_jobs_by_company(company_id)
job_ids = [job["id"] for job in company_jobs]
apps = list(applications_col.find({"job_id": {"$in": job_ids}}))
for app in apps:
app.pop("_id", None)
logger.info(f"Found {len(apps)} applications for company {company_id}")
return apps
except Exception as e:
logger.error(f"Error getting applications by company: {e}")
return []