Spaces:
Running
Running
| """ | |
| processor_utils.py | |
| ================== | |
| Shared taxonomy data and pure helper functions. | |
| THIS IS THE SINGLE SOURCE OF TRUTH for skill aliases, category mappings, | |
| seniority patterns, and normalisation utilities. | |
| The scrapper uses this directly. | |
| The processor fetches it via GET /taxonomy on the scrapper API. | |
| Design notes | |
| ------------ | |
| * Aliases are deliberately global — not specialised for any single industry. | |
| Tech, healthcare, finance, legal, education, construction, hospitality, etc. | |
| all work with the same extractor; only the alias set differs per domain. | |
| * OR/slash compound expressions ("Spring Boot/Django", "React or Angular") | |
| are already handled by _normalize() which converts "/" and the word "or" | |
| into spaces, letting each token match independently. | |
| * Over-broad single-word aliases (bare "compliance", bare "prototype") have | |
| been replaced with more specific multi-word variants to prevent false | |
| positives across domains. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from datetime import datetime as _dt | |
| from typing import Any, Dict, List, Optional, Set, Tuple | |
| # --------------------------------------------------------------------------- | |
| # Universal Skill Taxonomy | |
| # --------------------------------------------------------------------------- | |
| DEFAULT_SKILL_ALIASES: Dict[str, List[str]] = { | |
| # ── Office / Admin ─────────────────────────────────────────────────────── | |
| "microsoft word": ["microsoft word", "ms word", "word processor"], | |
| "microsoft excel": [ | |
| "microsoft excel", | |
| "ms excel", | |
| "excel", | |
| "spreadsheets", | |
| "google sheets", | |
| ], | |
| "microsoft powerpoint": [ | |
| "microsoft powerpoint", | |
| "ms powerpoint", | |
| "powerpoint", | |
| "power point", | |
| "google slides", | |
| "presentations", | |
| ], | |
| "microsoft outlook": ["microsoft outlook", "ms outlook", "outlook"], | |
| "microsoft office": [ | |
| "microsoft office", | |
| "ms office", | |
| "office suite", | |
| "office 365", | |
| "microsoft 365", | |
| ], | |
| "google workspace": [ | |
| "google workspace", | |
| "google docs", | |
| "google drive", | |
| "gsuite", | |
| "g suite", | |
| ], | |
| "data entry": [ | |
| "data entry", | |
| "typing", | |
| "data input", | |
| "data capture", | |
| "data processing", | |
| ], | |
| "filing": [ | |
| "filing", | |
| "document management", | |
| "records management", | |
| "file management", | |
| "document control", | |
| "record keeping", | |
| ], | |
| "scheduling": [ | |
| "scheduling", | |
| "calendar management", | |
| "appointment setting", | |
| "diary management", | |
| "timetabling", | |
| ], | |
| "communication": [ | |
| "communication", | |
| "interpersonal", | |
| "verbal communication", | |
| "written communication", | |
| "correspondence", | |
| ], | |
| "teamwork": [ | |
| "teamwork", | |
| "team work", | |
| "team player", | |
| "collaboration", | |
| "cross-functional", | |
| ], | |
| "customer service": [ | |
| "customer service", | |
| "client service", | |
| "customer support", | |
| "client relations", | |
| "client care", | |
| ], | |
| "problem solving": [ | |
| "problem solving", | |
| "problem-solving", | |
| "critical thinking", | |
| "analytical thinking", | |
| "troubleshooting", | |
| ], | |
| "time management": [ | |
| "time management", | |
| "prioritization", | |
| "prioritisation", | |
| "multitasking", | |
| "deadline management", | |
| ], | |
| "reporting": [ | |
| "reporting", | |
| "report writing", | |
| "report generation", | |
| "management reporting", | |
| "progress reports", | |
| ], | |
| "inventory management": [ | |
| "inventory management", | |
| "stock control", | |
| "stock management", | |
| "stock checking", | |
| "inventory tracking", | |
| ], | |
| "warehouse": [ | |
| "warehouse", | |
| "stockroom", | |
| "store room", | |
| "stores", | |
| "warehouse operations", | |
| ], | |
| "leadership": [ | |
| "leadership", | |
| "team leadership", | |
| "people management", | |
| "people leader", | |
| ], | |
| "attention to detail": [ | |
| "attention to detail", | |
| "accuracy", | |
| "meticulous", | |
| "detail oriented", | |
| "detail-oriented", | |
| ], | |
| "adaptability": ["adaptability", "adaptable", "flexible", "versatile"], | |
| "stakeholder management": [ | |
| "stakeholder management", | |
| "stakeholder engagement", | |
| "stakeholder communication", | |
| "stakeholder relations", | |
| ], | |
| "public speaking": [ | |
| "public speaking", | |
| "presentation skills", | |
| "presenting", | |
| "facilitation", | |
| "keynote", | |
| ], | |
| "conflict resolution": [ | |
| "conflict resolution", | |
| "dispute management", | |
| "mediation skills", | |
| "grievance resolution", | |
| ], | |
| "decision making": [ | |
| "decision making", | |
| "decision-making", | |
| "strategic thinking", | |
| "judgement", | |
| ], | |
| "emotional intelligence": [ | |
| "emotional intelligence", | |
| "eq", | |
| "empathy", | |
| "self-awareness", | |
| ], | |
| "technical writing": [ | |
| "technical writing", | |
| "technical documentation", | |
| "user manuals", | |
| "sop writing", | |
| "standard operating procedures", | |
| ], | |
| "erp": [ | |
| "erp", | |
| "enterprise resource planning", | |
| "sap erp", | |
| "oracle erp", | |
| "dynamics 365", | |
| "netsuite", | |
| "odoo", | |
| ], | |
| "ms project": [ | |
| "ms project", | |
| "microsoft project", | |
| "project planning software", | |
| "primavera", | |
| ], | |
| "minute taking": ["minute taking", "meeting minutes", "notetaking", "secretarial"], | |
| "virtual assistant": [ | |
| "virtual assistant", | |
| "executive assistant", | |
| "pa", | |
| "personal assistant", | |
| "administrative assistant", | |
| ], | |
| # ── Finance & Accounting ───────────────────────────────────────────────── | |
| "accounting": ["accounting", "accountancy", "bookkeeping", "accounts"], | |
| "financial analysis": [ | |
| "financial analysis", | |
| "financial modelling", | |
| "financial modeling", | |
| "financial reporting", | |
| "financial planning", | |
| "fp&a", | |
| ], | |
| "auditing": [ | |
| "auditing", | |
| "internal audit", | |
| "external audit", | |
| "audit", | |
| "statutory audit", | |
| "audit trail", | |
| ], | |
| "taxation": [ | |
| "taxation", | |
| "tax", | |
| "tax compliance", | |
| "tax preparation", | |
| "tax returns", | |
| "vat", | |
| "corporation tax", | |
| "withholding tax", | |
| ], | |
| "payroll": [ | |
| "payroll", | |
| "payroll processing", | |
| "payroll management", | |
| "payroll administration", | |
| ], | |
| "budgeting": [ | |
| "budgeting", | |
| "budget management", | |
| "budget planning", | |
| "forecasting", | |
| "variance analysis", | |
| "capex", | |
| "opex", | |
| ], | |
| "accounts payable": ["accounts payable", "vendor payments", "creditors", "ap"], | |
| "accounts receivable": [ | |
| "accounts receivable", | |
| "invoicing", | |
| "debtors", | |
| "collections", | |
| "ar", | |
| ], | |
| "quickbooks": ["quickbooks", "quick books"], | |
| "sage": ["sage", "sage accounting", "sage 50", "sage 200", "sage intacct"], | |
| "sap": ["sap", "sap finance", "sap s/4hana", "sap fico", "sap hana"], | |
| "xero": ["xero"], | |
| "ifrs": ["ifrs", "international financial reporting standards"], | |
| "gaap": ["gaap", "generally accepted accounting principles", "us gaap", "uk gaap"], | |
| "reconciliation": [ | |
| "reconciliation", | |
| "bank reconciliation", | |
| "account reconciliation", | |
| ], | |
| "cash flow": ["cash flow", "cash management", "treasury", "liquidity management"], | |
| "risk management": [ | |
| "risk management", | |
| "risk assessment", | |
| "enterprise risk management", | |
| "erm", | |
| "risk framework", | |
| "risk mitigation", | |
| ], | |
| "kyc": [ | |
| "kyc", | |
| "know your customer", | |
| "customer due diligence", | |
| "cdd", | |
| "customer onboarding compliance", | |
| ], | |
| "aml": [ | |
| "aml", | |
| "anti-money laundering", | |
| "anti money laundering", | |
| "financial crime", | |
| "fraud detection", | |
| ], | |
| "core banking": [ | |
| "core banking", | |
| "banking system", | |
| "flexcube", | |
| "temenos", | |
| "finacle", | |
| "murex", | |
| "t24", | |
| ], | |
| "trade finance": [ | |
| "trade finance", | |
| "letter of credit", | |
| "documentary credit", | |
| "trade operations", | |
| ], | |
| "wealth management": [ | |
| "wealth management", | |
| "asset management", | |
| "portfolio management", | |
| "investment management", | |
| "fund management", | |
| ], | |
| "bloomberg": ["bloomberg", "bloomberg terminal", "bloomberg api"], | |
| "financial compliance": [ | |
| "financial compliance", | |
| "financial regulation", | |
| "regulatory reporting", | |
| "cbk", | |
| "sec compliance", | |
| ], | |
| "actuarial": ["actuarial", "actuary", "actuarial science", "actuarial analysis"], | |
| "cfa": ["cfa", "chartered financial analyst"], | |
| "acca": ["acca", "chartered accountant", "cpa", "cima", "icpak", "aca"], | |
| "derivatives": [ | |
| "derivatives", | |
| "futures", | |
| "options", | |
| "swaps", | |
| "structured products", | |
| ], | |
| "credit analysis": [ | |
| "credit analysis", | |
| "credit risk", | |
| "loan appraisal", | |
| "credit scoring", | |
| "underwriting", | |
| ], | |
| # ── Human Resources ────────────────────────────────────────────────────── | |
| "recruitment": [ | |
| "recruitment", | |
| "recruiting", | |
| "talent acquisition", | |
| "hiring", | |
| "staffing", | |
| "talent sourcing", | |
| "headhunting", | |
| ], | |
| "onboarding": [ | |
| "staff onboarding", | |
| "new hire orientation", | |
| "employee induction", | |
| "new employee onboarding", | |
| ], | |
| "performance management": [ | |
| "performance management", | |
| "performance review", | |
| "appraisal", | |
| "kpi management", | |
| "okr", | |
| ], | |
| "employee relations": [ | |
| "employee relations", | |
| "labour relations", | |
| "labor relations", | |
| "grievance handling", | |
| "disciplinary", | |
| ], | |
| "training and development": [ | |
| "learning and development", | |
| "l&d", | |
| "employee training", | |
| "talent development", | |
| "workforce training", | |
| "capability building", | |
| ], | |
| "hris": [ | |
| "hris", | |
| "hr information system", | |
| "workday", | |
| "bamboohr", | |
| "zoho hr", | |
| "oracle hcm", | |
| "successfactors", | |
| "peoplesoft", | |
| ], | |
| "compensation": [ | |
| "compensation", | |
| "benefits", | |
| "compensation and benefits", | |
| "remuneration", | |
| "total rewards", | |
| "salary benchmarking", | |
| ], | |
| "hr compliance": [ | |
| "hr compliance", | |
| "employment law", | |
| "labour law", | |
| "labor law", | |
| "hr policy", | |
| "hr regulation", | |
| "employment relations", | |
| ], | |
| "job analysis": [ | |
| "job analysis", | |
| "job evaluation", | |
| "job grading", | |
| "job description", | |
| ], | |
| "succession planning": [ | |
| "succession planning", | |
| "talent pipeline", | |
| "leadership development", | |
| ], | |
| "workforce planning": [ | |
| "workforce planning", | |
| "headcount planning", | |
| "org design", | |
| "organisational design", | |
| ], | |
| "dei": [ | |
| "diversity equity inclusion", | |
| "dei", | |
| "diversity and inclusion", | |
| "equal opportunity", | |
| "inclusive workplace", | |
| ], | |
| "talent management": [ | |
| "talent management", | |
| "talent strategy", | |
| "high potential", | |
| "talent review", | |
| ], | |
| "culture": [ | |
| "culture", | |
| "employee engagement", | |
| "employer branding", | |
| "employee experience", | |
| ], | |
| # ── Sales & Business Development ───────────────────────────────────────── | |
| "sales": [ | |
| "sales", | |
| "selling", | |
| "business development", | |
| "b2b sales", | |
| "b2c sales", | |
| "direct sales", | |
| "inside sales", | |
| "field sales", | |
| ], | |
| "crm": [ | |
| "crm", | |
| "salesforce", | |
| "hubspot", | |
| "zoho crm", | |
| "customer relationship management", | |
| "pipedrive", | |
| "dynamics crm", | |
| ], | |
| "negotiation": [ | |
| "negotiation", | |
| "contract negotiation", | |
| "deal closing", | |
| "deal making", | |
| ], | |
| "lead generation": [ | |
| "lead generation", | |
| "prospecting", | |
| "cold calling", | |
| "cold outreach", | |
| "demand generation", | |
| ], | |
| "account management": [ | |
| "account management", | |
| "key account management", | |
| "client management", | |
| "portfolio management", | |
| ], | |
| "retail": [ | |
| "retail", | |
| "retail sales", | |
| "merchandising", | |
| "point of sale", | |
| "pos", | |
| "fmcg", | |
| ], | |
| "business analysis": [ | |
| "business analysis", | |
| "business analyst", | |
| "requirements gathering", | |
| "process improvement", | |
| "business case", | |
| ], | |
| "partnership": [ | |
| "partnership", | |
| "channel sales", | |
| "partnership management", | |
| "alliances", | |
| "channel management", | |
| "reseller", | |
| ], | |
| "customer success": [ | |
| "customer success", | |
| "customer retention", | |
| "account growth", | |
| "upselling", | |
| "cross-selling", | |
| ], | |
| "revenue operations": [ | |
| "revenue operations", | |
| "revops", | |
| "sales operations", | |
| "go-to-market", | |
| "gtm", | |
| ], | |
| # ── Customer Support ───────────────────────────────────────────────────── | |
| "help desk": [ | |
| "help desk", | |
| "helpdesk", | |
| "it support", | |
| "technical support", | |
| "service desk", | |
| "l1 support", | |
| "l2 support", | |
| ], | |
| "ticketing systems": [ | |
| "ticketing", | |
| "zendesk", | |
| "freshdesk", | |
| "jira service desk", | |
| "servicenow", | |
| "remedy", | |
| "ivanti", | |
| ], | |
| "call centre": [ | |
| "call centre", | |
| "call center", | |
| "contact centre", | |
| "contact center", | |
| "inbound calls", | |
| "outbound calls", | |
| ], | |
| "live chat": ["live chat", "chat support", "intercom", "drift", "livechat"], | |
| "sla management": [ | |
| "sla", | |
| "sla management", | |
| "service level agreement", | |
| "service level", | |
| "response time", | |
| ], | |
| "customer satisfaction": [ | |
| "customer satisfaction", | |
| "csat", | |
| "net promoter score", | |
| "nps", | |
| "customer feedback", | |
| ], | |
| # ── Healthcare ─────────────────────────────────────────────────────────── | |
| "patient care": [ | |
| "patient care", | |
| "patient management", | |
| "bedside manner", | |
| "patient assessment", | |
| "patient monitoring", | |
| ], | |
| "nursing": [ | |
| "nursing", | |
| "registered nurse", | |
| "rn", | |
| "clinical nursing", | |
| "enrolled nurse", | |
| "bscn", | |
| ], | |
| "clinical skills": [ | |
| "clinical skills", | |
| "clinical assessment", | |
| "clinical procedures", | |
| "clinical competencies", | |
| ], | |
| "pharmacy": [ | |
| "pharmacy", | |
| "dispensing", | |
| "pharmaceutical", | |
| "pharmacology", | |
| "medication management", | |
| ], | |
| "first aid": [ | |
| "first aid", | |
| "cpr", | |
| "bls", | |
| "basic life support", | |
| "acls", | |
| "emergency response", | |
| "resuscitation", | |
| ], | |
| "medical records": [ | |
| "medical records", | |
| "electronic health records", | |
| "medical documentation", | |
| "health records", | |
| ], | |
| "infection control": [ | |
| "infection control", | |
| "infection prevention", | |
| "ips", | |
| "sterilization", | |
| "ppe", | |
| ], | |
| "midwifery": [ | |
| "midwifery", | |
| "obstetrics", | |
| "maternity", | |
| "antenatal", | |
| "postnatal", | |
| "labour ward", | |
| ], | |
| "physiotherapy": [ | |
| "physiotherapy", | |
| "physical therapy", | |
| "rehabilitation", | |
| "musculoskeletal", | |
| ], | |
| "laboratory": [ | |
| "laboratory", | |
| "lab technician", | |
| "medical laboratory", | |
| "specimen processing", | |
| "pathology", | |
| ], | |
| "ehr systems": [ | |
| "ehr", | |
| "emr", | |
| "electronic health record", | |
| "epic", | |
| "cerner", | |
| "meditech", | |
| "allscripts", | |
| "hospital information system", | |
| ], | |
| "hl7": [ | |
| "hl7", | |
| "hl7 fhir", | |
| "fhir", | |
| "healthcare interoperability", | |
| "health data exchange", | |
| ], | |
| "clinical trials": [ | |
| "clinical trials", | |
| "good clinical practice", | |
| "gcp", | |
| "clinical research", | |
| "research protocol", | |
| ], | |
| "icd coding": [ | |
| "icd", | |
| "icd-10", | |
| "icd-11", | |
| "medical coding", | |
| "cpt coding", | |
| "clinical coding", | |
| ], | |
| "telemedicine": [ | |
| "telemedicine", | |
| "telehealth", | |
| "remote patient monitoring", | |
| "virtual clinic", | |
| ], | |
| "surgical": [ | |
| "surgical", | |
| "theatre", | |
| "perioperative", | |
| "scrub nurse", | |
| "surgical technician", | |
| ], | |
| "radiology": [ | |
| "radiology", | |
| "imaging", | |
| "mri", | |
| "ct scan", | |
| "x-ray", | |
| "radiography", | |
| "ultrasound", | |
| ], | |
| "nutrition": [ | |
| "nutrition", | |
| "dietetics", | |
| "dietitian", | |
| "nutritionist", | |
| "food science", | |
| ], | |
| "mental health": [ | |
| "mental health", | |
| "psychiatry", | |
| "psychology", | |
| "counselling", | |
| "counseling", | |
| "psychotherapy", | |
| "cbt", | |
| ], | |
| # ── Legal ──────────────────────────────────────────────────────────────── | |
| "legal research": [ | |
| "legal research", | |
| "case research", | |
| "statute interpretation", | |
| "case law", | |
| ], | |
| "contract drafting": [ | |
| "contract drafting", | |
| "contract review", | |
| "drafting agreements", | |
| "legal drafting", | |
| "contract management", | |
| ], | |
| "litigation": [ | |
| "litigation", | |
| "court proceedings", | |
| "legal proceedings", | |
| "advocacy", | |
| "trial", | |
| ], | |
| "legal compliance": [ | |
| "legal compliance", | |
| "regulatory affairs", | |
| "compliance management", | |
| "regulatory framework", | |
| ], | |
| "conveyancing": [ | |
| "conveyancing", | |
| "property law", | |
| "land transactions", | |
| "title search", | |
| ], | |
| "corporate law": [ | |
| "corporate law", | |
| "company law", | |
| "corporate governance", | |
| "company secretarial", | |
| ], | |
| "legal writing": [ | |
| "legal writing", | |
| "pleadings", | |
| "legal opinions", | |
| "memoranda", | |
| "legal briefs", | |
| ], | |
| "due diligence": [ | |
| "due diligence", | |
| "legal due diligence", | |
| "commercial due diligence", | |
| ], | |
| "mergers acquisitions": [ | |
| "mergers and acquisitions", | |
| "m&a", | |
| "corporate restructuring", | |
| "merger", | |
| "acquisition", | |
| "takeover", | |
| ], | |
| "intellectual property": [ | |
| "intellectual property", | |
| "ip law", | |
| "trademark", | |
| "patent", | |
| "copyright", | |
| "ip rights", | |
| "ip management", | |
| ], | |
| "arbitration": [ | |
| "arbitration", | |
| "mediation", | |
| "dispute resolution", | |
| "adr", | |
| "alternative dispute resolution", | |
| ], | |
| "legal tech": [ | |
| "legal tech", | |
| "legaltech", | |
| "contract automation", | |
| "clm", | |
| "e-discovery", | |
| ], | |
| "employment law": [ | |
| "employment law", | |
| "labour law", | |
| "labor law", | |
| "employment tribunal", | |
| ], | |
| # ── Education & Training ───────────────────────────────────────────────── | |
| "teaching": [ | |
| "teaching", | |
| "instruction", | |
| "lecturing", | |
| "tutoring", | |
| "classroom teaching", | |
| "pedagogy", | |
| ], | |
| "curriculum development": [ | |
| "curriculum development", | |
| "curriculum design", | |
| "lesson planning", | |
| "scheme of work", | |
| "curriculum mapping", | |
| ], | |
| "classroom management": [ | |
| "classroom management", | |
| "student management", | |
| "behaviour management", | |
| "student discipline", | |
| ], | |
| "e-learning": [ | |
| "e-learning", | |
| "elearning", | |
| "lms", | |
| "moodle", | |
| "instructional design", | |
| "online course development", | |
| ], | |
| "lms": [ | |
| "learning management system", | |
| "blackboard", | |
| "canvas lms", | |
| "google classroom", | |
| "schoology", | |
| "d2l", | |
| "brightspace", | |
| ], | |
| "assessment": [ | |
| "assessment", | |
| "grading", | |
| "marking", | |
| "examination", | |
| "evaluation", | |
| "formative assessment", | |
| ], | |
| "mentoring": [ | |
| "mentoring", | |
| "mentorship", | |
| "coaching", | |
| "academic guidance", | |
| "career coaching", | |
| ], | |
| "distance learning": [ | |
| "distance learning", | |
| "online teaching", | |
| "remote teaching", | |
| "blended learning", | |
| "hybrid learning", | |
| ], | |
| "stem": ["stem", "science technology engineering mathematics", "stem education"], | |
| "research": [ | |
| "research", | |
| "academic research", | |
| "literature review", | |
| "research methodology", | |
| "data collection", | |
| ], | |
| "student counseling": [ | |
| "student counseling", | |
| "student counselling", | |
| "academic advising", | |
| "student welfare", | |
| "pastoral care", | |
| ], | |
| "special education": [ | |
| "special education", | |
| "special needs", | |
| "sen", | |
| "inclusive education", | |
| "learning disabilities", | |
| ], | |
| # ── Operations & Logistics ─────────────────────────────────────────────── | |
| "supply chain": [ | |
| "supply chain", | |
| "supply chain management", | |
| "scm", | |
| "end-to-end supply chain", | |
| ], | |
| "procurement": [ | |
| "procurement", | |
| "purchasing", | |
| "vendor management", | |
| "sourcing", | |
| "tendering", | |
| "rfq", | |
| "rfp", | |
| ], | |
| "logistics": [ | |
| "logistics", | |
| "fleet management", | |
| "transportation management", | |
| "freight", | |
| "delivery", | |
| "last mile delivery", | |
| ], | |
| "quality control": [ | |
| "quality control", | |
| "qc", | |
| "quality assurance", | |
| "qa", | |
| "iso", | |
| "quality management", | |
| "iso 9001", | |
| "total quality management", | |
| ], | |
| "project management": [ | |
| "project management", | |
| "pmp", | |
| "prince2", | |
| "agile project management", | |
| "project planning", | |
| "waterfall", | |
| "project delivery", | |
| ], | |
| "lean": [ | |
| "lean", | |
| "lean manufacturing", | |
| "lean six sigma", | |
| "continuous improvement", | |
| "kaizen", | |
| "5s", | |
| "value stream mapping", | |
| ], | |
| "six sigma": ["six sigma", "6 sigma", "dmaic", "black belt", "green belt"], | |
| "warehouse management": [ | |
| "warehouse management system", | |
| "wms", | |
| "inventory system", | |
| "warehouse operations", | |
| ], | |
| "demand planning": [ | |
| "demand planning", | |
| "demand forecasting", | |
| "s&op", | |
| "sales and operations planning", | |
| ], | |
| "customs": [ | |
| "customs", | |
| "customs clearance", | |
| "import export", | |
| "trade compliance", | |
| "incoterms", | |
| ], | |
| "3pl": [ | |
| "3pl", | |
| "third party logistics", | |
| "outsourced logistics", | |
| "logistics provider", | |
| ], | |
| "health and safety": [ | |
| "health and safety", | |
| "hse", | |
| "ohse", | |
| "occupational health", | |
| "workplace safety", | |
| "risk assessment", | |
| ], | |
| # ── Software Engineering ───────────────────────────────────────────────── | |
| "html": ["html", "html5", "semantic html"], | |
| "css": ["css", "css3", "sass", "scss", "less", "stylesheets"], | |
| "javascript": ["javascript", "js", "es6", "es2015", "ecmascript", "vanilla js"], | |
| "typescript": ["typescript", "ts"], | |
| "react": ["react", "react.js", "reactjs", "react hooks", "react native"], | |
| "next.js": ["next.js", "nextjs", "next js"], | |
| "vue": ["vue", "vue.js", "vuejs", "vue 3", "nuxt", "nuxt.js"], | |
| "angular": ["angular", "angularjs", "angular.js", "angular 2+"], | |
| "svelte": ["svelte", "sveltekit"], | |
| "tailwind css": ["tailwind", "tailwind css"], | |
| "node.js": ["node", "node.js", "nodejs", "express", "express.js"], | |
| "nestjs": ["nestjs", "nest.js", "nestjs framework"], | |
| "python": ["python"], | |
| "django": ["django", "django rest framework", "drf"], | |
| "flask": ["flask", "flask api"], | |
| "fastapi": ["fastapi", "fast api"], | |
| "java": ["java"], | |
| "spring boot": [ | |
| "spring boot", | |
| "spring", | |
| "spring framework", | |
| "spring mvc", | |
| "spring security", | |
| "spring cloud", | |
| ], | |
| "kotlin": ["kotlin", "kotlin multiplatform"], | |
| "android": ["android", "android studio", "android sdk", "android development"], | |
| "php": ["php"], | |
| "laravel": ["laravel"], | |
| "symfony": ["symfony"], | |
| "rails": ["rails", "ruby on rails", "ror"], | |
| "dotnet": [ | |
| ".net", | |
| ".net core", | |
| "dotnet", | |
| "asp.net", | |
| "asp.net core", | |
| "net core", | |
| ".net framework", | |
| ".net maui", | |
| "blazor", | |
| "wpf", | |
| "xamarin", | |
| ], | |
| "mysql": ["mysql"], | |
| "postgresql": ["postgresql", "postgres", "supabase"], | |
| "mongodb": ["mongodb", "mongo"], | |
| "sqlite": ["sqlite"], | |
| "mariadb": ["mariadb", "maria db"], | |
| "oracle db": ["oracle database", "oracle db", "oracle sql", "pl/sql"], | |
| "cassandra": ["cassandra", "apache cassandra"], | |
| "dynamodb": ["dynamodb", "dynamo db", "amazon dynamodb"], | |
| "firestore": [ | |
| "firestore", | |
| "firebase", | |
| "cloud firestore", | |
| "firebase realtime database", | |
| ], | |
| "neo4j": ["neo4j", "graph database", "graph db"], | |
| "influxdb": ["influxdb", "influx db", "time series database", "timescaledb"], | |
| "clickhouse": ["clickhouse"], | |
| "redis": ["redis", "redis cache", "redis cluster"], | |
| "elasticsearch": ["elasticsearch", "elastic search", "opensearch", "elk"], | |
| "rest api": [ | |
| "rest api", | |
| "restful api", | |
| "restful apis", | |
| "restful", | |
| "api development", | |
| "api design", | |
| "web services", | |
| "api integration", | |
| ], | |
| "graphql": ["graphql", "graph ql", "apollo", "apollo server", "apollo client"], | |
| "grpc": ["grpc", "protocol buffers", "protobuf"], | |
| "soap": ["soap", "soap api", "soap web service", "wsdl", "web service"], | |
| "openapi": [ | |
| "openapi", | |
| "swagger", | |
| "openapi spec", | |
| "swagger ui", | |
| "api spec", | |
| "api documentation", | |
| ], | |
| "git": [ | |
| "git", | |
| "github", | |
| "gitlab", | |
| "bitbucket", | |
| "version control", | |
| "source control", | |
| ], | |
| "docker": [ | |
| "docker", | |
| "docker compose", | |
| "dockerfile", | |
| "containerization", | |
| "containerisation", | |
| ], | |
| "kubernetes": ["kubernetes", "k8s", "helm", "openshift", "container orchestration"], | |
| "spring boot": [ | |
| "spring boot", | |
| "spring", | |
| "spring framework", | |
| "spring mvc", | |
| "spring security", | |
| "spring cloud", | |
| ], | |
| "ci/cd": [ | |
| "ci/cd", | |
| "ci cd", | |
| "github actions", | |
| "jenkins", | |
| "gitlab ci", | |
| "bitbucket pipelines", | |
| "circle ci", | |
| "travis ci", | |
| "argocd", | |
| "tekton", | |
| ], | |
| "aws": [ | |
| "aws", | |
| "amazon web services", | |
| "ec2", | |
| "s3", | |
| "lambda", | |
| "ecs", | |
| "eks", | |
| "rds", | |
| "cloudformation", | |
| "cdk", | |
| ], | |
| "azure": [ | |
| "azure", | |
| "microsoft azure", | |
| "azure devops", | |
| "azure functions", | |
| "azure pipelines", | |
| "arm templates", | |
| "bicep", | |
| ], | |
| "gcp": [ | |
| "gcp", | |
| "google cloud", | |
| "google cloud platform", | |
| "cloud run", | |
| "gke", | |
| "bigquery", | |
| "cloud functions", | |
| ], | |
| "terraform": [ | |
| "terraform", | |
| "infrastructure as code", | |
| "iac", | |
| "hashicorp terraform", | |
| "pulumi", | |
| ], | |
| "ansible": ["ansible", "ansible playbook", "configuration management"], | |
| "flutter": ["flutter"], | |
| "dart": ["dart"], | |
| "swift": ["swift", "swiftui", "swift ui"], | |
| "ios": ["ios", "xcode", "ios development", "iphone development"], | |
| "jetpack compose": ["jetpack compose", "android compose", "compose multiplatform"], | |
| "ionic": ["ionic", "capacitor", "cordova", "hybrid app"], | |
| "c#": ["c#", "csharp", "c sharp"], | |
| "c++": ["c++", "cpp", "c plus plus"], | |
| "c": ["c language", "c programming", "embedded c"], | |
| "rust": ["rust", "rust lang", "systems programming"], | |
| "go": ["golang", "go lang", "go programming"], | |
| "scala": ["scala"], | |
| "ruby": ["ruby"], | |
| "perl": ["perl"], | |
| "bash": [ | |
| "bash", | |
| "shell scripting", | |
| "bash scripting", | |
| "shell script", | |
| "unix scripting", | |
| ], | |
| "powershell": ["powershell", "power shell", "ps script", "windows scripting"], | |
| "lua": ["lua"], | |
| "elixir": ["elixir", "phoenix framework", "phoenix"], | |
| "groovy": ["groovy"], | |
| "haskell": ["haskell"], | |
| "f#": ["f#", "fsharp", "f sharp"], | |
| "r": ["r programming", "r language", "rstudio"], | |
| "sql": ["sql", "pl/sql", "t-sql", "structured query language"], | |
| "data analysis": [ | |
| "data analysis", | |
| "analytics", | |
| "data analytics", | |
| "business intelligence", | |
| ], | |
| "machine learning": [ | |
| "machine learning", | |
| "ml", | |
| "deep learning", | |
| "neural networks", | |
| "artificial intelligence", | |
| "ai", | |
| ], | |
| "tensorflow": ["tensorflow", "tf", "keras"], | |
| "pytorch": ["pytorch", "torch"], | |
| "scikit-learn": ["scikit-learn", "sklearn", "scikit learn"], | |
| "nlp": [ | |
| "nlp", | |
| "natural language processing", | |
| "text mining", | |
| "sentiment analysis", | |
| "text analytics", | |
| ], | |
| "computer vision": [ | |
| "computer vision", | |
| "image recognition", | |
| "object detection", | |
| "opencv", | |
| "image processing", | |
| ], | |
| "generative ai": [ | |
| "generative ai", | |
| "gen ai", | |
| "llm", | |
| "large language model", | |
| "gpt", | |
| "langchain", | |
| "hugging face", | |
| "transformers", | |
| "openai", | |
| ], | |
| "microservices": [ | |
| "microservices", | |
| "micro-services", | |
| "microservice architecture", | |
| "service-oriented", | |
| "soa", | |
| "event-driven", | |
| ], | |
| "kafka": ["kafka", "apache kafka", "kafka streams", "confluent", "event streaming"], | |
| "rabbitmq": ["rabbitmq", "rabbit mq", "amqp", "message queue"], | |
| "mqtt": ["mqtt", "hivemq", "mosquitto", "emqx", "iot messaging"], | |
| "message broker": [ | |
| "message broker", | |
| "activemq", | |
| "apache activemq", | |
| "nats", | |
| "zeromq", | |
| "pub/sub", | |
| "pubsub", | |
| "azure service bus", | |
| "aws sqs", | |
| "google pub/sub", | |
| ], | |
| "hibernate": ["hibernate", "jpa", "java persistence api", "orm"], | |
| "sequelize": ["sequelize"], | |
| "prisma": ["prisma", "prisma orm"], | |
| "typeorm": ["typeorm", "type orm"], | |
| "sqlalchemy": ["sqlalchemy", "sql alchemy"], | |
| "entity framework": ["entity framework", "ef core", "entity framework core"], | |
| "redux": ["redux", "redux toolkit", "react redux", "rtk query"], | |
| "zustand": ["zustand"], | |
| "mobx": ["mobx"], | |
| "pinia": ["pinia"], | |
| "ngrx": ["ngrx", "ngxs"], | |
| "vuex": ["vuex"], | |
| "context api": ["context api", "react context"], | |
| "jwt": ["jwt", "json web token", "json web tokens"], | |
| "oauth": ["oauth", "oauth2", "oauth 2.0", "openid connect", "oidc", "pkce"], | |
| "saml": [ | |
| "saml", | |
| "saml 2.0", | |
| "sso", | |
| "single sign-on", | |
| "single sign on", | |
| "federated identity", | |
| ], | |
| "jest": ["jest", "jest.js"], | |
| "junit": ["junit", "junit5", "junit 4", "junit jupiter"], | |
| "pytest": ["pytest", "py.test"], | |
| "mocha": ["mocha", "mocha.js"], | |
| "cypress": ["cypress", "cypress.io"], | |
| "selenium": ["selenium", "selenium webdriver", "selenium grid"], | |
| "jasmine": ["jasmine"], | |
| "testng": ["testng", "test ng"], | |
| "nunit": ["nunit"], | |
| "xunit": ["xunit", "x unit"], | |
| "robot framework": ["robot framework", "robotframework"], | |
| "cucumber": [ | |
| "cucumber", | |
| "gherkin", | |
| "bdd", | |
| "behavior driven development", | |
| "behaviour driven development", | |
| ], | |
| "tdd": [ | |
| "tdd", | |
| "test driven development", | |
| "test-driven development", | |
| "unit testing", | |
| "integration testing", | |
| "end-to-end testing", | |
| ], | |
| "jmeter": ["jmeter", "apache jmeter", "load testing", "performance testing"], | |
| "postman": ["postman", "api testing"], | |
| "agile": [ | |
| "agile", | |
| "agile methodology", | |
| "agile development", | |
| "agile framework", | |
| "scrum", | |
| "scrum master", | |
| "safe", | |
| "scaled agile", | |
| "sprint ceremonies", | |
| ], | |
| "kanban": ["kanban", "kanban board"], | |
| "jira": ["jira", "atlassian jira", "jira software"], | |
| "confluence": ["confluence", "atlassian confluence", "wiki"], | |
| # ── Infrastructure & Cloud Ops ─────────────────────────────────────────── | |
| "linux": [ | |
| "linux", | |
| "ubuntu", | |
| "centos", | |
| "rhel", | |
| "red hat", | |
| "debian", | |
| "fedora", | |
| "unix", | |
| "linux administration", | |
| ], | |
| "windows server": [ | |
| "windows server", | |
| "iis", | |
| "windows administration", | |
| "active directory", | |
| ], | |
| "active directory": [ | |
| "active directory", | |
| "ldap", | |
| "azure ad", | |
| "microsoft entra", | |
| "entra id", | |
| "domain services", | |
| ], | |
| "vmware": ["vmware", "vsphere", "vcenter", "esxi", "vsan", "vmware workstation"], | |
| "hyper-v": ["hyper-v", "hyperv", "hyper v"], | |
| "virtualization": [ | |
| "virtualization", | |
| "virtualisation", | |
| "virtual machine", | |
| "vm management", | |
| "kvm", | |
| "proxmox", | |
| ], | |
| "itil": ["itil", "it service management", "itsm", "itil v4", "service lifecycle"], | |
| "sre": [ | |
| "sre", | |
| "site reliability engineering", | |
| "site reliability", | |
| "reliability engineering", | |
| ], | |
| "high availability": [ | |
| "high availability", | |
| "ha cluster", | |
| "failover", | |
| "load balancing", | |
| "disaster recovery", | |
| "rto", | |
| "rpo", | |
| "bcp", | |
| "business continuity", | |
| "fault tolerance", | |
| ], | |
| "networking": [ | |
| "networking", | |
| "network administration", | |
| "network engineering", | |
| "tcp/ip", | |
| "dns", | |
| "dhcp", | |
| "vpn", | |
| "lan", | |
| "wan", | |
| "sd-wan", | |
| "sdwan", | |
| "firewall", | |
| "routing", | |
| "switching", | |
| "vlan", | |
| "mpls", | |
| ], | |
| "cisco": ["cisco", "ccna", "ccnp", "ccie", "cisco ios", "cisco networking"], | |
| "puppet": ["puppet", "puppet enterprise"], | |
| "chef": ["chef", "chef infra"], | |
| "vagrant": ["vagrant"], | |
| "prometheus": ["prometheus", "prometheus monitoring", "alertmanager"], | |
| "grafana": ["grafana", "grafana dashboard"], | |
| "datadog": ["datadog", "data dog"], | |
| "elk stack": ["elk stack", "logstash", "kibana", "elastic stack", "fluentd"], | |
| "splunk": ["splunk", "splunk siem"], | |
| "cloudwatch": ["cloudwatch", "aws cloudwatch"], | |
| "new relic": ["new relic", "newrelic"], | |
| "dynatrace": ["dynatrace"], | |
| "opentelemetry": [ | |
| "opentelemetry", | |
| "open telemetry", | |
| "distributed tracing", | |
| "jaeger", | |
| "zipkin", | |
| "observability", | |
| ], | |
| "storage": [ | |
| "storage", | |
| "nas", | |
| "san", | |
| "object storage", | |
| "block storage", | |
| "aws s3", | |
| "azure blob", | |
| "gcs", | |
| ], | |
| "backup recovery": [ | |
| "backup", | |
| "backup and recovery", | |
| "backup strategy", | |
| "data backup", | |
| "veeam", | |
| "commvault", | |
| ], | |
| # ── Cybersecurity ──────────────────────────────────────────────────────── | |
| "penetration testing": [ | |
| "penetration testing", | |
| "pen testing", | |
| "pentesting", | |
| "ethical hacking", | |
| "red team", | |
| "blue team", | |
| "purple team", | |
| ], | |
| "vulnerability management": [ | |
| "vulnerability management", | |
| "vulnerability assessment", | |
| "vulnerability scanning", | |
| "nessus", | |
| "qualys", | |
| ], | |
| "siem": [ | |
| "siem", | |
| "security information and event management", | |
| "soc analyst", | |
| "security operations center", | |
| "soc", | |
| ], | |
| "iso 27001": ["iso 27001", "iso27001", "information security management", "isms"], | |
| "soc 2": ["soc 2", "soc2", "aicpa soc"], | |
| "gdpr": ["gdpr", "data protection regulation", "ccpa", "data privacy law"], | |
| "owasp": ["owasp", "owasp top 10", "web application security", "appsec"], | |
| "pci dss": ["pci dss", "pci", "payment card industry"], | |
| "nist": ["nist", "nist framework", "nist cybersecurity"], | |
| "zero trust": ["zero trust", "zero trust network", "ztna"], | |
| "ssl tls": [ | |
| "ssl", | |
| "tls", | |
| "ssl/tls", | |
| "certificates", | |
| "pki", | |
| "public key infrastructure", | |
| ], | |
| "devsecops": [ | |
| "devsecops", | |
| "security as code", | |
| "shift left security", | |
| "sast", | |
| "dast", | |
| ], | |
| "threat intelligence": [ | |
| "threat intelligence", | |
| "threat hunting", | |
| "cyber threat", | |
| "ioc", | |
| "indicators of compromise", | |
| ], | |
| "cloud security": ["cloud security", "aws security", "azure security", "cspm"], | |
| # ── Data & Analytics ───────────────────────────────────────────────────── | |
| "power bi": ["power bi", "powerbi", "power bi desktop", "dax"], | |
| "tableau": ["tableau", "tableau desktop"], | |
| "looker": ["looker", "looker studio", "google data studio"], | |
| "qlik": ["qlik", "qlikview", "qliksense"], | |
| "data science": ["data science", "data scientist"], | |
| "statistics": ["statistics", "statistical analysis", "spss", "stata", "minitab"], | |
| "data visualization": [ | |
| "data visualization", | |
| "data visualisation", | |
| "data viz", | |
| "dashboarding", | |
| ], | |
| "excel analytics": [ | |
| "pivot tables", | |
| "advanced excel", | |
| "excel analytics", | |
| "vlookup", | |
| "xlookup", | |
| ], | |
| # ── Data Engineering ───────────────────────────────────────────────────── | |
| "apache spark": ["apache spark", "pyspark", "spark streaming", "spark sql"], | |
| "apache hadoop": ["apache hadoop", "hadoop", "hdfs", "hive", "hbase"], | |
| "apache airflow": ["apache airflow", "airflow", "workflow orchestration", "dag"], | |
| "dbt": ["dbt", "data build tool", "analytics engineering"], | |
| "snowflake": ["snowflake", "snowflake data warehouse"], | |
| "databricks": ["databricks", "lakehouse"], | |
| "data pipeline": [ | |
| "data pipeline", | |
| "etl", | |
| "elt", | |
| "data integration", | |
| "data ingestion", | |
| "data warehouse", | |
| "data lake", | |
| "data lakehouse", | |
| ], | |
| "data modeling": [ | |
| "data modeling", | |
| "data modelling", | |
| "star schema", | |
| "dimensional modeling", | |
| "entity relationship", | |
| ], | |
| "data governance": [ | |
| "data governance", | |
| "data quality", | |
| "data catalog", | |
| "metadata management", | |
| "data stewardship", | |
| ], | |
| "streaming": [ | |
| "real-time streaming", | |
| "stream processing", | |
| "event-driven architecture", | |
| "cdc", | |
| "change data capture", | |
| ], | |
| # ── Design & Creative ──────────────────────────────────────────────────── | |
| "ui design": ["ui design", "user interface design", "interface design"], | |
| "ux design": [ | |
| "ux design", | |
| "user experience design", | |
| "ux research", | |
| "usability", | |
| "ux writing", | |
| ], | |
| "figma": ["figma"], | |
| "wireframing": ["wireframe", "wireframing", "low-fidelity"], | |
| "prototyping": [ | |
| "prototyping", | |
| "rapid prototyping", | |
| "interactive prototype", | |
| "high-fidelity prototype", | |
| ], | |
| "adobe photoshop": ["photoshop", "adobe photoshop"], | |
| "adobe illustrator": ["illustrator", "adobe illustrator", "vector graphics"], | |
| "adobe xd": ["adobe xd", "xd"], | |
| "adobe premiere": ["adobe premiere", "premiere pro", "video editing"], | |
| "adobe after effects": ["after effects", "adobe after effects", "motion graphics"], | |
| "graphic design": ["graphic design", "graphics", "visual design", "print design"], | |
| "video editing": [ | |
| "video editing", | |
| "video production", | |
| "final cut pro", | |
| "davinci resolve", | |
| ], | |
| "photography": ["photography", "photo editing", "lightroom", "photo retouching"], | |
| "canva": ["canva"], | |
| "sketch": ["sketch", "sketch app"], | |
| "invision": ["invision", "invision studio"], | |
| "miro": ["miro", "miroboard", "whiteboarding", "collaborative design"], | |
| "3d design": [ | |
| "3d design", | |
| "blender", | |
| "cinema 4d", | |
| "3d modeling", | |
| "3d rendering", | |
| "maya", | |
| ], | |
| "brand design": ["brand design", "branding", "visual identity", "brand guidelines"], | |
| # ── Marketing ──────────────────────────────────────────────────────────── | |
| "seo": [ | |
| "seo", | |
| "search engine optimization", | |
| "search engine optimisation", | |
| "on-page seo", | |
| "off-page seo", | |
| "technical seo", | |
| ], | |
| "content writing": [ | |
| "content writing", | |
| "copywriting", | |
| "content creation", | |
| "blog writing", | |
| "content strategy", | |
| "editorial", | |
| ], | |
| "digital marketing": [ | |
| "digital marketing", | |
| "online marketing", | |
| "marketing campaigns", | |
| "marketing strategy", | |
| "performance marketing", | |
| ], | |
| "social media": [ | |
| "social media", | |
| "social media management", | |
| "instagram", | |
| "facebook marketing", | |
| "tiktok", | |
| "linkedin marketing", | |
| "twitter", | |
| ], | |
| "email marketing": [ | |
| "email marketing", | |
| "mailchimp", | |
| "email campaigns", | |
| "newsletter", | |
| "klaviyo", | |
| "sendgrid", | |
| ], | |
| "google analytics": [ | |
| "google analytics", | |
| "ga4", | |
| "web analytics", | |
| "google tag manager", | |
| "gtm", | |
| ], | |
| "google ads": [ | |
| "google ads", | |
| "google adwords", | |
| "ppc", | |
| "pay per click", | |
| "sem", | |
| "paid search", | |
| ], | |
| "facebook ads": [ | |
| "facebook ads", | |
| "meta ads", | |
| "social media advertising", | |
| "paid social", | |
| ], | |
| "brand management": ["brand management", "brand strategy"], | |
| "marketing automation": [ | |
| "marketing automation", | |
| "hubspot marketing", | |
| "marketo", | |
| "pardot", | |
| "salesforce marketing cloud", | |
| ], | |
| "affiliate marketing": [ | |
| "affiliate marketing", | |
| "performance marketing", | |
| "influencer marketing", | |
| "partnership marketing", | |
| ], | |
| "cro": [ | |
| "cro", | |
| "conversion rate optimization", | |
| "conversion optimisation", | |
| "a/b testing", | |
| "landing page optimization", | |
| ], | |
| "pr": [ | |
| "pr", | |
| "public relations", | |
| "media relations", | |
| "press release", | |
| "communications", | |
| ], | |
| # ── Construction & Engineering ─────────────────────────────────────────── | |
| "autocad": ["autocad", "auto cad", "cad", "computer aided design", "drafting"], | |
| "solidworks": ["solidworks", "solid works", "parametric design"], | |
| "revit": [ | |
| "revit", | |
| "bim", | |
| "building information modeling", | |
| "autodesk revit", | |
| "building information modelling", | |
| ], | |
| "civil engineering": [ | |
| "civil engineering", | |
| "structural engineering", | |
| "geotechnical", | |
| "quantity surveying", | |
| "qs", | |
| ], | |
| "primavera": [ | |
| "primavera", | |
| "oracle primavera", | |
| "p6", | |
| "primavera p6", | |
| "project scheduling", | |
| ], | |
| "civil 3d": ["civil 3d", "autocad civil 3d", "road design", "drainage design"], | |
| "surveying": [ | |
| "surveying", | |
| "land surveying", | |
| "total station", | |
| "gps surveying", | |
| "topographic", | |
| ], | |
| "electrical engineering": [ | |
| "electrical engineering", | |
| "power systems", | |
| "plc", | |
| "scada", | |
| "instrumentation", | |
| "hv", | |
| "lv", | |
| ], | |
| "mechanical engineering": [ | |
| "mechanical engineering", | |
| "hvac", | |
| "fluid mechanics", | |
| "thermodynamics", | |
| "piping", | |
| ], | |
| # ── Hospitality & Property ─────────────────────────────────────────────── | |
| "hospitality management": [ | |
| "hospitality management", | |
| "hotel management", | |
| "f&b", | |
| "food and beverage", | |
| "front office", | |
| ], | |
| "property management": [ | |
| "property management", | |
| "pms", | |
| "property management system", | |
| "opera pms", | |
| "real estate management", | |
| ], | |
| "revenue management": [ | |
| "revenue management", | |
| "yield management", | |
| "revenue optimization", | |
| "pricing strategy", | |
| ], | |
| "food safety": [ | |
| "food safety", | |
| "haccp", | |
| "food hygiene", | |
| "food handling", | |
| "food service", | |
| ], | |
| "housekeeping": [ | |
| "housekeeping", | |
| "rooms division", | |
| "facilities management", | |
| "janitorial", | |
| ], | |
| "real estate": [ | |
| "real estate", | |
| "property valuation", | |
| "mortgage", | |
| "property development", | |
| "estate agency", | |
| "letting", | |
| ], | |
| "event management": [ | |
| "event management", | |
| "events coordination", | |
| "venue management", | |
| "conference management", | |
| ], | |
| # ── Cross-domain Agile & Process ───────────────────────────────────────── | |
| "agile": [ | |
| "agile", | |
| "agile methodology", | |
| "agile development", | |
| "agile framework", | |
| "scrum", | |
| "scrum master", | |
| "safe", | |
| "scaled agile", | |
| ], | |
| "kanban": ["kanban", "kanban board"], | |
| "jira": ["jira", "atlassian jira"], | |
| "confluence": ["confluence", "atlassian confluence"], | |
| "business process": [ | |
| "business process", | |
| "bpm", | |
| "business process management", | |
| "process mapping", | |
| "process documentation", | |
| "sop", | |
| ], | |
| "change management": [ | |
| "change management", | |
| "organisational change", | |
| "change leadership", | |
| "transformation", | |
| ], | |
| "program management": [ | |
| "program management", | |
| "programme management", | |
| "portfolio management", | |
| "pmo", | |
| "project portfolio", | |
| ], | |
| } | |
| DEFAULT_CATEGORY_SKILLS: Dict[str, Set[str]] = { | |
| "Admin & Office": { | |
| "microsoft word", | |
| "microsoft excel", | |
| "microsoft powerpoint", | |
| "microsoft office", | |
| "google workspace", | |
| "data entry", | |
| "filing", | |
| "scheduling", | |
| "communication", | |
| "teamwork", | |
| "customer service", | |
| "reporting", | |
| "inventory management", | |
| "warehouse", | |
| "time management", | |
| "attention to detail", | |
| "erp", | |
| "minute taking", | |
| "virtual assistant", | |
| "adaptability", | |
| }, | |
| "Software Engineering": { | |
| "html", | |
| "css", | |
| "javascript", | |
| "typescript", | |
| "react", | |
| "next.js", | |
| "vue", | |
| "angular", | |
| "svelte", | |
| "tailwind css", | |
| "node.js", | |
| "nestjs", | |
| "python", | |
| "django", | |
| "flask", | |
| "fastapi", | |
| "java", | |
| "spring boot", | |
| "kotlin", | |
| "android", | |
| "php", | |
| "laravel", | |
| "symfony", | |
| "rails", | |
| "dotnet", | |
| "mysql", | |
| "postgresql", | |
| "mongodb", | |
| "sqlite", | |
| "mariadb", | |
| "oracle db", | |
| "cassandra", | |
| "dynamodb", | |
| "firestore", | |
| "neo4j", | |
| "redis", | |
| "elasticsearch", | |
| "rest api", | |
| "graphql", | |
| "grpc", | |
| "soap", | |
| "openapi", | |
| "git", | |
| "docker", | |
| "kubernetes", | |
| "ci/cd", | |
| "aws", | |
| "azure", | |
| "gcp", | |
| "terraform", | |
| "ansible", | |
| "flutter", | |
| "dart", | |
| "swift", | |
| "ios", | |
| "jetpack compose", | |
| "ionic", | |
| "c#", | |
| "c++", | |
| "c", | |
| "rust", | |
| "go", | |
| "scala", | |
| "ruby", | |
| "bash", | |
| "powershell", | |
| "elixir", | |
| "groovy", | |
| "haskell", | |
| "f#", | |
| "sql", | |
| "machine learning", | |
| "tensorflow", | |
| "pytorch", | |
| "scikit-learn", | |
| "nlp", | |
| "computer vision", | |
| "generative ai", | |
| "microservices", | |
| "kafka", | |
| "rabbitmq", | |
| "mqtt", | |
| "message broker", | |
| "hibernate", | |
| "sequelize", | |
| "prisma", | |
| "typeorm", | |
| "sqlalchemy", | |
| "entity framework", | |
| "redux", | |
| "zustand", | |
| "mobx", | |
| "pinia", | |
| "ngrx", | |
| "vuex", | |
| "context api", | |
| "jwt", | |
| "oauth", | |
| "saml", | |
| "jest", | |
| "junit", | |
| "pytest", | |
| "mocha", | |
| "cypress", | |
| "selenium", | |
| "jasmine", | |
| "testng", | |
| "nunit", | |
| "xunit", | |
| "robot framework", | |
| "cucumber", | |
| "tdd", | |
| "jmeter", | |
| "postman", | |
| "agile", | |
| "kanban", | |
| "jira", | |
| "confluence", | |
| "influxdb", | |
| "clickhouse", | |
| }, | |
| "Infrastructure & Cloud": { | |
| "linux", | |
| "windows server", | |
| "active directory", | |
| "vmware", | |
| "hyper-v", | |
| "virtualization", | |
| "itil", | |
| "sre", | |
| "high availability", | |
| "networking", | |
| "cisco", | |
| "puppet", | |
| "chef", | |
| "vagrant", | |
| "terraform", | |
| "ansible", | |
| "docker", | |
| "kubernetes", | |
| "aws", | |
| "azure", | |
| "gcp", | |
| "prometheus", | |
| "grafana", | |
| "datadog", | |
| "elk stack", | |
| "splunk", | |
| "cloudwatch", | |
| "new relic", | |
| "dynatrace", | |
| "opentelemetry", | |
| "storage", | |
| "backup recovery", | |
| "ci/cd", | |
| "git", | |
| "bash", | |
| "powershell", | |
| }, | |
| "Cybersecurity": { | |
| "penetration testing", | |
| "vulnerability management", | |
| "siem", | |
| "iso 27001", | |
| "soc 2", | |
| "gdpr", | |
| "owasp", | |
| "pci dss", | |
| "nist", | |
| "zero trust", | |
| "ssl tls", | |
| "devsecops", | |
| "threat intelligence", | |
| "cloud security", | |
| "networking", | |
| "linux", | |
| "python", | |
| "bash", | |
| }, | |
| "Design & Creative": { | |
| "ui design", | |
| "ux design", | |
| "figma", | |
| "wireframing", | |
| "prototyping", | |
| "adobe photoshop", | |
| "adobe illustrator", | |
| "adobe xd", | |
| "graphic design", | |
| "video editing", | |
| "photography", | |
| "canva", | |
| "sketch", | |
| "invision", | |
| "miro", | |
| "3d design", | |
| "brand design", | |
| "adobe premiere", | |
| "adobe after effects", | |
| }, | |
| "Marketing & Growth": { | |
| "seo", | |
| "content writing", | |
| "digital marketing", | |
| "social media", | |
| "email marketing", | |
| "google analytics", | |
| "google ads", | |
| "facebook ads", | |
| "brand management", | |
| "marketing automation", | |
| "affiliate marketing", | |
| "cro", | |
| "pr", | |
| "crm", | |
| }, | |
| "Data & Analytics": { | |
| "sql", | |
| "python", | |
| "machine learning", | |
| "data analysis", | |
| "microsoft excel", | |
| "power bi", | |
| "tableau", | |
| "looker", | |
| "qlik", | |
| "data science", | |
| "statistics", | |
| "data visualization", | |
| "r", | |
| "excel analytics", | |
| "elasticsearch", | |
| "tensorflow", | |
| "pytorch", | |
| "scikit-learn", | |
| "nlp", | |
| "computer vision", | |
| "generative ai", | |
| }, | |
| "Data Engineering": { | |
| "apache spark", | |
| "apache hadoop", | |
| "apache airflow", | |
| "dbt", | |
| "snowflake", | |
| "databricks", | |
| "data pipeline", | |
| "data modeling", | |
| "data governance", | |
| "streaming", | |
| "kafka", | |
| "python", | |
| "sql", | |
| "aws", | |
| "azure", | |
| "gcp", | |
| "postgresql", | |
| "mongodb", | |
| "elasticsearch", | |
| "redis", | |
| }, | |
| "Finance & Accounting": { | |
| "accounting", | |
| "financial analysis", | |
| "auditing", | |
| "taxation", | |
| "payroll", | |
| "budgeting", | |
| "accounts payable", | |
| "accounts receivable", | |
| "quickbooks", | |
| "sage", | |
| "sap", | |
| "xero", | |
| "ifrs", | |
| "gaap", | |
| "reconciliation", | |
| "cash flow", | |
| "microsoft excel", | |
| "risk management", | |
| "kyc", | |
| "aml", | |
| "core banking", | |
| "trade finance", | |
| "wealth management", | |
| "bloomberg", | |
| "financial compliance", | |
| "actuarial", | |
| "cfa", | |
| "acca", | |
| "derivatives", | |
| "credit analysis", | |
| }, | |
| "Human Resources": { | |
| "recruitment", | |
| "onboarding", | |
| "performance management", | |
| "employee relations", | |
| "training and development", | |
| "hris", | |
| "compensation", | |
| "hr compliance", | |
| "job analysis", | |
| "communication", | |
| "microsoft excel", | |
| "succession planning", | |
| "workforce planning", | |
| "dei", | |
| "talent management", | |
| "culture", | |
| }, | |
| "Sales & Business Dev": { | |
| "sales", | |
| "crm", | |
| "negotiation", | |
| "lead generation", | |
| "account management", | |
| "retail", | |
| "communication", | |
| "customer service", | |
| "partnership", | |
| "customer success", | |
| "revenue operations", | |
| "business analysis", | |
| }, | |
| "Healthcare": { | |
| "patient care", | |
| "nursing", | |
| "clinical skills", | |
| "pharmacy", | |
| "first aid", | |
| "medical records", | |
| "infection control", | |
| "midwifery", | |
| "physiotherapy", | |
| "laboratory", | |
| "ehr systems", | |
| "hl7", | |
| "clinical trials", | |
| "icd coding", | |
| "telemedicine", | |
| "surgical", | |
| "radiology", | |
| "nutrition", | |
| "mental health", | |
| }, | |
| "Legal": { | |
| "legal research", | |
| "contract drafting", | |
| "litigation", | |
| "legal compliance", | |
| "conveyancing", | |
| "corporate law", | |
| "legal writing", | |
| "due diligence", | |
| "mergers acquisitions", | |
| "intellectual property", | |
| "arbitration", | |
| "legal tech", | |
| "employment law", | |
| }, | |
| "Education & Training": { | |
| "teaching", | |
| "curriculum development", | |
| "classroom management", | |
| "e-learning", | |
| "assessment", | |
| "mentoring", | |
| "communication", | |
| "lms", | |
| "distance learning", | |
| "stem", | |
| "research", | |
| "student counseling", | |
| "special education", | |
| }, | |
| "Operations & Logistics": { | |
| "supply chain", | |
| "procurement", | |
| "logistics", | |
| "quality control", | |
| "project management", | |
| "lean", | |
| "six sigma", | |
| "inventory management", | |
| "reporting", | |
| "warehouse management", | |
| "demand planning", | |
| "customs", | |
| "3pl", | |
| "health and safety", | |
| "erp", | |
| }, | |
| "Customer Support": { | |
| "customer service", | |
| "help desk", | |
| "ticketing systems", | |
| "call centre", | |
| "communication", | |
| "crm", | |
| "reporting", | |
| "live chat", | |
| "sla management", | |
| "customer satisfaction", | |
| }, | |
| "Construction & Engineering": { | |
| "autocad", | |
| "solidworks", | |
| "revit", | |
| "civil engineering", | |
| "primavera", | |
| "civil 3d", | |
| "surveying", | |
| "electrical engineering", | |
| "mechanical engineering", | |
| "ms project", | |
| "health and safety", | |
| }, | |
| "Hospitality & Property": { | |
| "hospitality management", | |
| "property management", | |
| "revenue management", | |
| "food safety", | |
| "housekeeping", | |
| "real estate", | |
| "event management", | |
| "customer service", | |
| "communication", | |
| }, | |
| } | |
| SENIORITY_PATTERNS: Dict[str, List[str]] = { | |
| "intern": [ | |
| "intern", | |
| "internship", | |
| "trainee", | |
| "industrial attachment", | |
| "attachment student", | |
| "graduate trainee", | |
| "pupil", | |
| "cadet", | |
| ], | |
| "junior": [ | |
| "junior", | |
| "entry level", | |
| "entry-level", | |
| "assistant", | |
| "fresh graduate", | |
| "graduate", | |
| "associate", | |
| "junior officer", | |
| "junior analyst", | |
| "junior developer", | |
| "junior engineer", | |
| ], | |
| "mid": [ | |
| "mid", | |
| "middle", | |
| "officer", | |
| "specialist", | |
| "developer", | |
| "designer", | |
| "engineer", | |
| "analyst", | |
| "coordinator", | |
| "technician", | |
| "executive", | |
| "consultant", | |
| "representative", | |
| ], | |
| "senior": [ | |
| "senior", | |
| "lead", | |
| "manager", | |
| "head", | |
| "principal", | |
| "architect", | |
| "director", | |
| "vp", | |
| "vice president", | |
| "chief", | |
| "cto", | |
| "ceo", | |
| "coo", | |
| "cfo", | |
| "superintendent", | |
| "supervisor", | |
| "managing", | |
| "staff engineer", | |
| "distinguished", | |
| "fellow", | |
| ], | |
| } | |
| SENIORITY_ORDER: Dict[str, int] = {"intern": 0, "junior": 1, "mid": 2, "senior": 3} | |
| # Words that look like "City, Country" but are actually tech terms — kept in sync | |
| # with the skill list above so location parsing doesn't mistake skill names for places. | |
| _TECH_LOC_BLACKLIST: Set[str] = { | |
| "java", | |
| "spring", | |
| "boot", | |
| "sql", | |
| "python", | |
| "node", | |
| "react", | |
| "angular", | |
| "vue", | |
| "docker", | |
| "linux", | |
| "windows", | |
| "android", | |
| "swift", | |
| "kotlin", | |
| "scala", | |
| "ruby", | |
| "rails", | |
| "django", | |
| "flask", | |
| "express", | |
| "mongo", | |
| "postgres", | |
| "redis", | |
| "kafka", | |
| "hadoop", | |
| "spark", | |
| "airflow", | |
| "jenkins", | |
| "gitlab", | |
| "github", | |
| "bitbucket", | |
| "jira", | |
| "confluence", | |
| "slack", | |
| "figma", | |
| "oracle", | |
| "mysql", | |
| "azure", | |
| "aws", | |
| "gcp", | |
| "rust", | |
| "golang", | |
| "flutter", | |
| "dart", | |
| "ionic", | |
| "svelte", | |
| "nextjs", | |
| "nestjs", | |
| "laravel", | |
| "symfony", | |
| "grafana", | |
| "kibana", | |
| "splunk", | |
| "terraform", | |
| "ansible", | |
| "puppet", | |
| "kubernetes", | |
| "helm", | |
| "istio", | |
| "nginx", | |
| "apache", | |
| } | |
| # --------------------------------------------------------------------------- | |
| # Soft-skill keys (used by chunker to split canonical list) | |
| # --------------------------------------------------------------------------- | |
| SOFT_SKILL_KEYS: Set[str] = { | |
| "communication", | |
| "teamwork", | |
| "problem solving", | |
| "time management", | |
| "customer service", | |
| "mentoring", | |
| "negotiation", | |
| "leadership", | |
| "reporting", | |
| "scheduling", | |
| "filing", | |
| "adaptability", | |
| "attention to detail", | |
| "onboarding", | |
| "training and development", | |
| "stakeholder management", | |
| "public speaking", | |
| "conflict resolution", | |
| "decision making", | |
| "emotional intelligence", | |
| "customer satisfaction", | |
| } | |
| # --------------------------------------------------------------------------- | |
| # Title role words & phrase regex (universal) | |
| # --------------------------------------------------------------------------- | |
| TITLE_ROLE_WORDS: List[str] = [ | |
| # Tech | |
| "developer", | |
| "engineer", | |
| "programmer", | |
| "architect", | |
| "devops", | |
| # General | |
| "officer", | |
| "designer", | |
| "assistant", | |
| "accountant", | |
| "manager", | |
| "analyst", | |
| "specialist", | |
| "coordinator", | |
| "director", | |
| "executive", | |
| "lead", | |
| "scientist", | |
| "strategist", | |
| "advisor", | |
| "trainer", | |
| "consultant", | |
| "researcher", | |
| "technician", | |
| "supervisor", | |
| "associate", | |
| "administrator", | |
| # Healthcare | |
| "nurse", | |
| "doctor", | |
| "physician", | |
| "pharmacist", | |
| "therapist", | |
| "clinician", | |
| "midwife", | |
| "radiographer", | |
| "physiotherapist", | |
| # Finance | |
| "auditor", | |
| "bookkeeper", | |
| "controller", | |
| "treasurer", | |
| "actuary", | |
| # HR | |
| "recruiter", | |
| # Sales | |
| "salesperson", | |
| "representative", | |
| "agent", | |
| "broker", | |
| # Education | |
| "teacher", | |
| "instructor", | |
| "lecturer", | |
| "professor", | |
| "tutor", | |
| # Other | |
| "admin", | |
| "intern", | |
| "student", | |
| "cashier", | |
| "marketing", | |
| "procurement", | |
| "buyer", | |
| "dispatcher", | |
| "operator", | |
| "superintendent", | |
| ] | |
| TITLE_PHRASE_RE = re.compile( | |
| r"\b((?:(?:full[\s\-]?stack|front[\s\-]?end|back[\s\-]?end|senior|junior|lead|" | |
| r"mid[\s\-]?level|entry[\s\-]?level|chief|head\s+of|staff|principal)?\s+)?(?:[\w\-]+\s){0,3}" | |
| r"(?:developer|engineer|designer|analyst|manager|specialist|consultant|architect|" | |
| r"programmer|researcher|officer|director|executive|scientist|trainer|accountant|" | |
| r"nurse|doctor|pharmacist|therapist|teacher|instructor|lecturer|recruiter|" | |
| r"coordinator|supervisor|administrator|technician|advisor|auditor|bookkeeper|" | |
| r"physiotherapist|midwife|clinician|representative|salesperson|buyer|dispatcher|" | |
| r"actuary|superintendent|operator))\b", | |
| re.IGNORECASE, | |
| ) | |
| # --------------------------------------------------------------------------- | |
| # Normalisation helpers | |
| # --------------------------------------------------------------------------- | |
| def _normalize(text: str) -> str: | |
| text = (text or "").lower() | |
| # Expand slash-separated compound skills: "Spring Boot/Django/.NET" → tokens | |
| text = text.replace("/", " ") | |
| text = text.replace("_", " ") | |
| text = re.sub(r"[^a-z0-9+.#\s-]", " ", text) | |
| return re.sub(r"\s+", " ", text).strip() | |
| _ALIAS_REGEX_CACHE = {} | |
| def _has_alias(text_norm: str, alias: str) -> bool: | |
| alias_norm = _normalize(alias) | |
| if not alias_norm: | |
| return False | |
| pattern = _ALIAS_REGEX_CACHE.get(alias_norm) | |
| if pattern is None: | |
| pattern = re.compile(rf"(?<![a-z0-9]){re.escape(alias_norm)}(?![a-z0-9])") | |
| _ALIAS_REGEX_CACHE[alias_norm] = pattern | |
| return pattern.search(text_norm) is not None | |
| # --------------------------------------------------------------------------- | |
| # Skill extraction | |
| # --------------------------------------------------------------------------- | |
| _SKILL_PATTERN = None | |
| _ALIAS_TO_CANONICAL = {} | |
| def _get_skill_pattern(): | |
| global _SKILL_PATTERN, _ALIAS_TO_CANONICAL | |
| if _SKILL_PATTERN is not None: | |
| return _SKILL_PATTERN, _ALIAS_TO_CANONICAL | |
| _ALIAS_TO_CANONICAL = {} | |
| alias_list = [] | |
| for canon, ali_list in DEFAULT_SKILL_ALIASES.items(): | |
| for a in ali_list: | |
| a_norm = _normalize(a) | |
| if a_norm: | |
| if a_norm not in _ALIAS_TO_CANONICAL: | |
| _ALIAS_TO_CANONICAL[a_norm] = canon | |
| alias_list.append(a_norm) | |
| alias_list.sort(key=len, reverse=True) | |
| pattern_str = "|".join(map(re.escape, alias_list)) | |
| _SKILL_PATTERN = re.compile(rf"(?<![a-z0-9])({pattern_str})(?![a-z0-9])") | |
| return _SKILL_PATTERN, _ALIAS_TO_CANONICAL | |
| def _extract_skills( | |
| text: str, | |
| aliases: Optional[Dict[str, List[str]]] = None, | |
| ) -> Set[str]: | |
| text_norm = _normalize(text) | |
| if aliases is None or aliases is DEFAULT_SKILL_ALIASES: | |
| pattern, alias_map = _get_skill_pattern() | |
| return {alias_map[match.group(1)] for match in pattern.finditer(text_norm)} | |
| return { | |
| canon | |
| for canon, ali_list in aliases.items() | |
| if any(_has_alias(text_norm, a) for a in ali_list) | |
| } | |
| # --------------------------------------------------------------------------- | |
| # Category inference (universal) | |
| # --------------------------------------------------------------------------- | |
| _CATEGORY_TITLE_KEYWORDS: Dict[str, List[str]] = { | |
| "Admin & Office": [ | |
| "admin", | |
| "office", | |
| "stock", | |
| "inventory", | |
| "warehouse", | |
| "cashier", | |
| "receptionist", | |
| "clerk", | |
| "secretary", | |
| ], | |
| "Software Engineering": [ | |
| "developer", | |
| "engineer", | |
| "programmer", | |
| "frontend", | |
| "backend", | |
| "full stack", | |
| "mobile", | |
| "fullstack", | |
| "software", | |
| "devops", | |
| ], | |
| "Infrastructure & Cloud": [ | |
| "infrastructure", | |
| "cloud", | |
| "sre", | |
| "network", | |
| "system administrator", | |
| "sysadmin", | |
| "it administrator", | |
| "cloud engineer", | |
| "platform engineer", | |
| ], | |
| "Cybersecurity": [ | |
| "security", | |
| "cybersecurity", | |
| "cyber", | |
| "infosec", | |
| "soc analyst", | |
| "penetration tester", | |
| "ethical hacker", | |
| "information security", | |
| ], | |
| "Design & Creative": [ | |
| "designer", | |
| "ui", | |
| "ux", | |
| "creative", | |
| "graphic", | |
| "visual", | |
| "illustrator", | |
| "photographer", | |
| "art director", | |
| ], | |
| "Marketing & Growth": [ | |
| "marketing", | |
| "seo", | |
| "content", | |
| "social media", | |
| "growth", | |
| "digital", | |
| "brand", | |
| "communications", | |
| ], | |
| "Data & Analytics": [ | |
| "data analyst", | |
| "analytics", | |
| "machine learning", | |
| "ai", | |
| "scientist", | |
| "bi analyst", | |
| "business intelligence", | |
| ], | |
| "Data Engineering": [ | |
| "data engineer", | |
| "etl", | |
| "data pipeline", | |
| "data architect", | |
| "analytics engineer", | |
| "data platform", | |
| ], | |
| "Finance & Accounting": [ | |
| "accountant", | |
| "finance", | |
| "accounting", | |
| "auditor", | |
| "bookkeeper", | |
| "treasurer", | |
| "payroll", | |
| "tax", | |
| "financial", | |
| ], | |
| "Human Resources": [ | |
| "hr", | |
| "human resource", | |
| "recruitment", | |
| "recruiter", | |
| "talent", | |
| "people", | |
| "hris", | |
| ], | |
| "Sales & Business Dev": [ | |
| "sales", | |
| "business development", | |
| "account manager", | |
| "sales executive", | |
| "representative", | |
| "business dev", | |
| ], | |
| "Healthcare": [ | |
| "nurse", | |
| "doctor", | |
| "clinical", | |
| "medical", | |
| "pharmacy", | |
| "patient", | |
| "health", | |
| "therapist", | |
| "midwife", | |
| "radiographer", | |
| ], | |
| "Legal": [ | |
| "legal", | |
| "lawyer", | |
| "attorney", | |
| "advocate", | |
| "counsel", | |
| "paralegal", | |
| "solicitor", | |
| ], | |
| "Education & Training": [ | |
| "teacher", | |
| "lecturer", | |
| "tutor", | |
| "instructor", | |
| "educator", | |
| "academic", | |
| "trainer", | |
| "professor", | |
| ], | |
| "Operations & Logistics": [ | |
| "logistics", | |
| "supply chain", | |
| "procurement", | |
| "operations", | |
| "fleet", | |
| "warehouse manager", | |
| "quality", | |
| "planner", | |
| ], | |
| "Customer Support": [ | |
| "customer support", | |
| "help desk", | |
| "call centre", | |
| "contact centre", | |
| "customer care", | |
| "service desk", | |
| ], | |
| "Construction & Engineering": [ | |
| "civil", | |
| "structural", | |
| "mechanical", | |
| "electrical", | |
| "quantity surveyor", | |
| "site engineer", | |
| "construction", | |
| "autocad", | |
| ], | |
| "Hospitality & Property": [ | |
| "hotel", | |
| "hospitality", | |
| "property", | |
| "real estate", | |
| "housekeeping", | |
| "f&b", | |
| "restaurant", | |
| "events", | |
| ], | |
| } | |
| def _infer_category( | |
| text: str, | |
| skills: Set[str], | |
| category_skills: Optional[Dict[str, Set[str]]] = None, | |
| ) -> str: | |
| if category_skills is None: | |
| category_skills = DEFAULT_CATEGORY_SKILLS | |
| text_norm = _normalize(text) | |
| best, best_score = "Other", 0.0 | |
| for cat, cat_skills in category_skills.items(): | |
| skill_overlap = len(skills & cat_skills) | |
| kw_hits = sum( | |
| 1 for kw in _CATEGORY_TITLE_KEYWORDS.get(cat, []) if kw in text_norm | |
| ) | |
| score = skill_overlap * 2.0 + kw_hits * 1.25 | |
| if score > best_score: | |
| best_score, best = score, cat | |
| return best | |
| # --------------------------------------------------------------------------- | |
| # Years-of-experience extraction (text mention) | |
| # --------------------------------------------------------------------------- | |
| def _extract_years(text: str) -> int: | |
| text_norm = _normalize(text) | |
| patterns = [ | |
| r"(\d+)\+?\s*(?:years|year|yrs|yr)\s*(?:of)?\s*(?:experience|exp)", | |
| r"experience\s*(?:of)?\s*(\d+)\+?\s*(?:years|year|yrs|yr)", | |
| r"(\d+)\+?\s*(?:years|year|yrs|yr)\s+(?:in\s+)?(?:the\s+)?(?:industry|field|software|development|practice|profession)", | |
| ] | |
| years = [int(m.group(1)) for p in patterns for m in re.finditer(p, text_norm)] | |
| return max(years) if years else 0 | |
| # --------------------------------------------------------------------------- | |
| # Years computed from parsed experience date ranges (more accurate) | |
| # --------------------------------------------------------------------------- | |
| _MONTH_SHORT: Dict[str, int] = { | |
| "jan": 1, | |
| "feb": 2, | |
| "mar": 3, | |
| "apr": 4, | |
| "may": 5, | |
| "jun": 6, | |
| "jul": 7, | |
| "aug": 8, | |
| "sep": 9, | |
| "oct": 10, | |
| "nov": 11, | |
| "dec": 12, | |
| } | |
| def _parse_date_token(token: str) -> Optional[_dt]: | |
| token = token.strip().lower() | |
| if re.match(r"present|current|now|ongoing|till\s*date|to\s*date", token): | |
| return _dt.now() | |
| m = re.match(r"([a-z]+)\s+(\d{4})", token) | |
| if m: | |
| month = _MONTH_SHORT.get(m.group(1)[:3], 1) | |
| try: | |
| return _dt(int(m.group(2)), month, 1) | |
| except ValueError: | |
| return None | |
| m = re.match(r"(\d{4})", token) | |
| if m: | |
| return _dt(int(m.group(1)), 6, 1) # mid-year when month unknown | |
| return None | |
| def compute_years_from_experience(entries: List[Dict[str, Any]]) -> int: | |
| """Sum date-range durations across all experience entries → total years.""" | |
| total_months = 0 | |
| for entry in entries: | |
| period = (entry.get("period") or "").strip() | |
| if not period: | |
| continue | |
| parts = re.split(r"\s*[-–—]\s*", period, maxsplit=1) | |
| if len(parts) != 2: | |
| continue | |
| start = _parse_date_token(parts[0]) | |
| end = _parse_date_token(parts[1]) | |
| if start and end and end > start: | |
| months = (end.year - start.year) * 12 + (end.month - start.month) | |
| total_months += max(0, months) | |
| return total_months // 12 | |
| # --------------------------------------------------------------------------- | |
| # Seniority detection | |
| # --------------------------------------------------------------------------- | |
| def _detect_seniority(text: str, *, is_cv: bool = False) -> str: | |
| """Detect seniority level from title-zone first, then body text. | |
| For jobs: checks the first 300 chars (title/header area) with higher | |
| priority before scanning the full body. This prevents stray mentions | |
| like 'for senior roles, consider...' in advice sections from inflating | |
| a mid-level job to senior. | |
| """ | |
| title_zone = text[:300] | |
| title_norm = _normalize(title_zone) | |
| text_norm = _normalize(text) | |
| order = ( | |
| ["senior", "junior", "intern", "mid"] | |
| if is_cv | |
| else ["senior", "intern", "junior", "mid"] | |
| ) | |
| # 1. Title zone has highest priority | |
| for level in order: | |
| if any(_has_alias(title_norm, term) for term in SENIORITY_PATTERNS[level]): | |
| return level | |
| # 2. Full body — but skip "senior" re-check for jobs to avoid advice-section pollution | |
| for level in order: | |
| if level == "senior" and not is_cv: | |
| continue | |
| if any(_has_alias(text_norm, term) for term in SENIORITY_PATTERNS[level]): | |
| return level | |
| years = _extract_years(text) | |
| if years >= 7: | |
| return "senior" | |
| if years >= 3: | |
| return "mid" | |
| return "junior" if is_cv else "mid" | |
| def refine_seniority_with_years(detected: str, years: int) -> str: | |
| """ | |
| Override a weakly-detected seniority using computed years. | |
| 'mid' is the weakest keyword signal (matches many generic job titles). | |
| 'intern' can appear from a past role and should not dominate once the | |
| candidate has accumulated meaningful professional experience. | |
| """ | |
| if detected == "mid": | |
| if years >= 7: | |
| return "senior" | |
| if years >= 3: | |
| return "mid" | |
| if 0 < years < 2: | |
| return "junior" | |
| return detected | |
| if detected == "intern" and years >= 2: | |
| if years >= 7: | |
| return "senior" | |
| if years >= 3: | |
| return "mid" | |
| return "junior" | |
| return detected | |
| # --------------------------------------------------------------------------- | |
| # CV title extractor (universal, scans more lines) | |
| # --------------------------------------------------------------------------- | |
| def _extract_cv_title(cv_text: str, clean_line_fn=None) -> str: | |
| """ | |
| Extract the candidate's professional title from the top of the CV. | |
| Parameters | |
| ---------- | |
| cv_text : str | |
| Raw markdown string. | |
| clean_line_fn : callable, optional | |
| A function(raw_line) -> str that strips markdown / HTML. | |
| Falls back to a simple regex strip if not provided. | |
| """ | |
| def _simple_clean(raw: str) -> str: | |
| line = re.sub(r"^#+\s*", "", raw) | |
| line = re.sub(r"\*{1,3}|\_{1,2}|`", "", line) | |
| return re.sub(r"\s+", " ", line).strip() | |
| clean = clean_line_fn or _simple_clean | |
| clean_lines = [clean(x) for x in cv_text.splitlines() if x.strip()] | |
| _role_wb_re = re.compile( | |
| r"\b(" + "|".join(re.escape(w) for w in TITLE_ROLE_WORDS) + r")\b", | |
| re.IGNORECASE, | |
| ) | |
| for line in clean_lines[1:30]: | |
| stripped = line.strip("| \t") | |
| if ( | |
| len(stripped) <= 80 | |
| and bool(_role_wb_re.search(stripped)) | |
| and "|" not in stripped | |
| and not re.search(r"[@http]", stripped) | |
| and not re.search( | |
| r"\d{4}\s*[-–]\s*(?:\d{4}|present)", stripped, re.IGNORECASE | |
| ) | |
| ): | |
| return stripped.title() | |
| _SECTION_HDR_RE = re.compile( | |
| r"^(career\s*summary|professional\s*summary|executive\s*summary|" | |
| r"personal\s*statement|career\s*objective|professional\s*profile|" | |
| r"personal\s*profile|about\s*me|work\s*experience|" | |
| r"professional\s*experience|technical\s*skills?|core\s*skills?|" | |
| r"key\s*skills?|educational?\s*background|academic\s*background|" | |
| r"employment\s*history|career\s*history|skills?\s*&?\s*tools?|" | |
| r"skills?|summary|profile|experience|education|projects?|awards?|" | |
| r"achievements?|contact|links?|certifications?)$", | |
| re.IGNORECASE, | |
| ) | |
| non_header = [ | |
| ln | |
| for ln in clean_lines[:40] | |
| if not _SECTION_HDR_RE.match(re.sub(r"[^a-zA-Z\s&]", " ", ln).strip()) | |
| ] | |
| head = ". ".join(non_header)[:1000] | |
| m = TITLE_PHRASE_RE.search(head) | |
| if m: | |
| return m.group(1).strip().title() | |
| return "Unknown" | |