88 lines
4.1 KiB
Python
88 lines
4.1 KiB
Python
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
|