feat: personalize scoring and add skills radar
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from apps.jobs.services.normalization import normalize_token
|
||||
|
||||
SKILL_ALIASES: dict[str, tuple[str, ...]] = {
|
||||
"microsoft 365": ("m365", "office 365", "o365"),
|
||||
"microsoft teams": ("ms teams",),
|
||||
"entra id": ("azure active directory", "azure ad"),
|
||||
"intune": ("microsoft intune", "endpoint manager"),
|
||||
"autopilot": ("windows autopilot",),
|
||||
"group policy": ("group policy object", "gpo"),
|
||||
"dynamics 365": ("microsoft dynamics 365", "d365"),
|
||||
"microsoft copilot": ("copilot for microsoft 365", "m365 copilot"),
|
||||
"microsoft defender": ("defender for endpoint", "microsoft defender for endpoint"),
|
||||
"microsoft sentinel": ("azure sentinel", "sentinel siem"),
|
||||
"conditional access": ("voorwaardelijke toegang",),
|
||||
"networking": ("network", "netwerk", "lan", "wan"),
|
||||
"routing": ("routering",),
|
||||
"switching": ("network switches", "switches"),
|
||||
"sd-wan": ("sd wan",),
|
||||
"firewalls": ("firewall",),
|
||||
"fortinet": ("fortigate",),
|
||||
"palo alto": ("palo alto networks",),
|
||||
"wi-fi": ("wifi", "wireless"),
|
||||
"backup and restore": ("backup", "back-up", "restore"),
|
||||
"disaster recovery": ("business continuity", "bcp", "dr plan"),
|
||||
"monitoring": ("infrastructure monitoring", "system monitoring"),
|
||||
"observability": ("telemetry", "tracing"),
|
||||
"high availability": ("hoogbeschikbaarheid", "ha architecture"),
|
||||
"vmware": ("vsphere", "esxi"),
|
||||
"ci/cd": ("continuous integration", "continuous delivery", "ci cd"),
|
||||
"deployment": ("deployments", "software deployment", "uitrol"),
|
||||
"reliability": ("platform reliability", "site reliability", "sre"),
|
||||
"scalability": ("scalable", "schaalbaarheid"),
|
||||
"voip": ("voice over ip", "telefonie", "telephony", "3cx", "innovaphone"),
|
||||
"teams telephony": ("teams phone", "teams telefonie", "teams voice"),
|
||||
"onsite support": ("on-site support", "support op locatie", "field support"),
|
||||
"second line support": ("second-line support", "2nd line", "tweedelijnssupport"),
|
||||
"installations": ("installatie", "installaties", "roll-out", "rollout"),
|
||||
"migrations": ("migratie", "migraties"),
|
||||
"technical documentation": ("technische documentatie",),
|
||||
"customer support": ("klantondersteuning", "user support"),
|
||||
"incident management": ("incidentbeheer", "incident response", "escalations"),
|
||||
"problem management": ("probleembeheer", "root cause analysis"),
|
||||
"change management": ("wijzigingsbeheer", "organizational change"),
|
||||
"itil": ("itil 4", "it service management"),
|
||||
"servicenow": ("service now",),
|
||||
"jira service management": ("jira service desk", "jsm"),
|
||||
"digital workplace": ("digitale werkplek",),
|
||||
"m365 governance": ("microsoft 365 governance", "office 365 governance"),
|
||||
"document management": ("documentbeheer", "document management system", "dms"),
|
||||
"data governance": ("data governance", "datagovernance"),
|
||||
"user adoption": ("gebruikersadoptie", "technology adoption"),
|
||||
"training and workshops": ("user training", "workshops", "training geven"),
|
||||
"customer experience": ("customer satisfaction", "csat", "nps"),
|
||||
}
|
||||
|
||||
|
||||
def contains_term(text: str, term: str, *, allow_plural: bool = False) -> bool:
|
||||
normalized_term = normalize_token(term)
|
||||
if not normalized_term:
|
||||
return False
|
||||
pattern = re.escape(normalized_term).replace(r"\ ", r"[\s/_-]+")
|
||||
if allow_plural and normalized_term[-1].isalpha() and not normalized_term.endswith("s"):
|
||||
pattern += "s?"
|
||||
return re.search(rf"(?<!\w){pattern}(?!\w)", text, re.IGNORECASE) is not None
|
||||
|
||||
|
||||
def skill_terms(skill: str) -> tuple[str, ...]:
|
||||
normalized = normalize_token(skill)
|
||||
return (normalized, *SKILL_ALIASES.get(normalized, ()))
|
||||
|
||||
|
||||
def skill_is_present(skill: str, text: str) -> bool:
|
||||
return any(contains_term(text, candidate) for candidate in skill_terms(skill))
|
||||
|
||||
|
||||
def canonical_skill_key(value: str, catalog_keys: set[str]) -> str | None:
|
||||
normalized = normalize_token(value)
|
||||
if normalized in catalog_keys:
|
||||
return normalized
|
||||
for key in catalog_keys:
|
||||
if normalized in {normalize_token(term) for term in SKILL_ALIASES.get(key, ())}:
|
||||
return key
|
||||
return None
|
||||
Reference in New Issue
Block a user