[WIP] mappings

This commit is contained in:
Eliyan
2025-10-15 11:28:10 +02:00
parent 9ed28595e2
commit 7bccdb711d
6 changed files with 1128 additions and 0 deletions

View File

@@ -0,0 +1,209 @@
// Base mapping structure for all ODMDB schemas
export const createSchemaMapping = (schemaData, objectName) => {
if (!schemaData || !schemaData.properties) {
return {
objectName,
available: false,
error: "Schema not found or invalid",
properties: {},
synonyms: {},
indexes: [],
};
}
const properties = schemaData.properties;
const synonyms = {};
const fieldMappings = {};
// Generate comprehensive synonyms for each field
Object.entries(properties).forEach(([fieldName, fieldDef]) => {
const fieldSynonyms = generateFieldSynonyms(
fieldName,
fieldDef,
objectName
);
fieldMappings[fieldName] = {
field: fieldName,
title: fieldDef.title?.toLowerCase(),
description: fieldDef.description?.toLowerCase(),
type: fieldDef.type,
synonyms: fieldSynonyms,
};
// Index by synonyms
fieldSynonyms.forEach((synonym) => {
synonyms[synonym.toLowerCase()] = fieldName;
});
// Index by title
if (fieldDef.title) {
synonyms[fieldDef.title.toLowerCase()] = fieldName;
}
});
// Extract indexes if available
const indexes = schemaData.apxidx
? schemaData.apxidx.map((idx) => ({
name: idx.name,
type: idx.type,
keyval: idx.keyval,
}))
: [];
// Extract access rights if available
const accessRights = schemaData.apxaccessrights || {};
return {
objectName,
available: true,
propertyCount: Object.keys(properties).length,
properties: fieldMappings,
synonyms,
indexes,
accessRights,
rawSchema: schemaData,
};
};
// Generate field-specific synonyms based on field name and context
const generateFieldSynonyms = (fieldName, fieldDef, objectName) => {
const synonyms = [];
// Add the field name itself
synonyms.push(fieldName);
// Add title if available
if (fieldDef.title) {
synonyms.push(fieldDef.title.toLowerCase());
}
// Common patterns across all objects
const commonPatterns = {
// Identity & References
alias: ["id", "identifier", "username", "user id"],
owner: ["owner", "belongs to", "owned by"],
// Dates & Timestamps
dt_create: [
"created",
"creation date",
"new",
"recent",
"since",
"registration date",
],
dt_update: ["updated", "last update", "modified", "last modified"],
dt_publish: ["published", "publication date", "went live"],
dt_close: ["closed", "closing date", "ended"],
// Contact Information
email: ["contact", "mail", "contact email", "e-mail"],
phone: ["telephone", "phone number", "contact number"],
// Status & State
state: ["status", "condition", "current state"],
status: ["state", "condition", "current status"],
// Location
location: ["where", "place", "address", "position"],
// Descriptions
description: ["desc", "details", "info", "about"],
shortdescription: ["short desc", "summary", "brief", "overview"],
// Common business fields
siret: ["company id", "business id", "organization id"],
sirets: ["companies", "businesses", "organizations"],
};
// Object-specific patterns
const objectSpecificPatterns = {
seekers: {
seekstatus: [
"status",
"availability",
"looking",
"job search status",
"urgency",
],
seekworkingyear: [
"experience",
"years of experience",
"work experience",
"career length",
],
seekjobtitleexperience: [
"job titles",
"positions",
"roles",
"work history",
],
salaryexpectation: [
"salary",
"pay",
"compensation",
"wage",
"expected salary",
],
seeklocation: [
"location",
"where",
"work location",
"preferred location",
],
skills: ["competencies", "abilities", "technical skills"],
mbti: ["personality", "personality type", "MBTI", "profile"],
},
jobads: {
jobadid: ["job id", "ad id", "posting id"],
jobtitle: ["job title", "position", "role", "job name"],
salary: ["pay", "compensation", "wage", "remuneration"],
joblocation: ["job location", "work location", "where"],
description: ["job description", "details", "requirements"],
state: ["status", "publication status", "availability"],
},
recruiters: {
sirets: ["companies", "businesses", "clients", "employers"],
tipsadvice: ["tips", "advice", "articles", "guidance"],
},
persons: {
firstname: ["first name", "given name", "name"],
lastname: ["last name", "family name", "surname"],
dt_birth: ["birth date", "birthday", "date of birth", "age"],
},
};
// Apply common patterns
if (commonPatterns[fieldName]) {
synonyms.push(...commonPatterns[fieldName]);
}
// Apply object-specific patterns
if (
objectSpecificPatterns[objectName] &&
objectSpecificPatterns[objectName][fieldName]
) {
synonyms.push(...objectSpecificPatterns[objectName][fieldName]);
}
// Generate semantic synonyms based on field name patterns
if (fieldName.includes("salary")) {
synonyms.push("pay", "compensation", "wage", "remuneration");
}
if (fieldName.includes("location")) {
synonyms.push("where", "place", "address", "position");
}
if (fieldName.includes("experience")) {
synonyms.push("background", "history", "expertise");
}
if (fieldName.includes("skill")) {
synonyms.push("competencies", "abilities", "talents");
}
if (fieldName.includes("date") || fieldName.startsWith("dt_")) {
synonyms.push("when", "time", "timestamp");
}
return [...new Set(synonyms)]; // Remove duplicates
};
export default createSchemaMapping;

View File

@@ -0,0 +1,151 @@
// JobAds schema mapping - job posting natural language support
import { createSchemaMapping } from "./base-mapping.js";
import fs from "node:fs";
const SCHEMA_PATH = "../smatchitObjectOdmdb/schema/jobads.json";
let jobadsSchema = null;
try {
if (fs.existsSync(SCHEMA_PATH)) {
jobadsSchema = JSON.parse(fs.readFileSync(SCHEMA_PATH, "utf-8"));
}
} catch (error) {
console.warn(`Warning: Could not load jobads schema: ${error.message}`);
}
export const jobadsMapping = createSchemaMapping(jobadsSchema, "jobads");
// Additional jobads-specific enhancements
if (jobadsMapping.available) {
const jobadsEnhancements = {
// Job Identification
"job id": "jobadid",
"posting id": "jobadid",
"ad id": "jobadid",
"advertisement id": "jobadid",
"job posting": "jobadid",
// Job Details
"job title": "jobtitle",
position: "jobtitle",
role: "jobtitle",
"job name": "jobtitle",
"position title": "jobtitle",
"job role": "jobtitle",
// Job Status & State
"job status": "state",
"posting status": "state",
"publication status": "state",
availability: "state",
"job state": "state",
active: "state",
published: "state",
draft: "state",
archived: "state",
// Company & Organization
company: "siret",
employer: "siret",
organization: "siret",
business: "siret",
firm: "siret",
// Job Compensation
salary: "salary",
pay: "salary",
compensation: "salary",
wage: "salary",
remuneration: "salary",
payment: "salary",
// Job Location
"job location": "joblocation",
"work location": "joblocation",
workplace: "joblocation",
"office location": "joblocation",
where: "joblocation",
place: "joblocation",
// Job Description & Requirements
"job description": "description",
"job details": "description",
requirements: "description",
responsibilities: "description",
duties: "description",
"job requirements": "description",
"role description": "description",
// Job Type & Contract
"employment type": "jobtype",
"contract type": "jobtype",
"job type": "jobtype",
"work type": "jobtype",
"position type": "jobtype",
// Remote Work
"remote work": "remote",
"work from home": "remote",
telecommute: "remote",
"remote job": "remote",
"home office": "remote",
// Dates & Timeline
"published date": "dt_publish",
"posting date": "dt_publish",
"publication date": "dt_publish",
"went live": "dt_publish",
"closing date": "dt_close",
deadline: "dt_close",
"application deadline": "dt_close",
expires: "dt_close",
// Skills & Qualifications
"required skills": "skills",
qualifications: "skills",
competencies: "skills",
"abilities required": "skills",
"expertise needed": "skills",
// Experience Requirements
"experience required": "experiencerequired",
"years of experience": "experiencerequired",
"work experience": "experiencerequired",
"professional experience": "experiencerequired",
// Education Requirements
"education required": "education",
"degree required": "education",
"qualification needed": "education",
"educational background": "education",
};
// Merge enhancements into synonyms
Object.entries(jobadsEnhancements).forEach(([synonym, fieldName]) => {
jobadsMapping.synonyms[synonym.toLowerCase()] = fieldName;
});
// Add state value mappings
jobadsMapping.statusValues = {
state: {
active: "publish",
published: "publish",
live: "publish",
online: "publish",
available: "publish",
draft: "draft",
unpublished: "draft",
"in progress": "draft",
ready: "ready",
pending: "ready",
waiting: "ready",
closed: "archive",
archived: "archive",
expired: "archive",
inactive: "archive",
ended: "archive",
},
};
}
export default jobadsMapping;

View File

@@ -0,0 +1,412 @@
// Comprehensive ODMDB Schema Mapping Manager
// Handles all objects, detects data availability, and provides intelligent query routing
import fs from "node:fs";
import { seekersMapping } from "./seekers-mapping.js";
import { jobadsMapping } from "./jobads-mapping.js";
import { recruitersMapping } from "./recruiters-mapping.js";
import { personsMapping } from "./persons-mapping.js";
import { createSchemaMapping } from "./base-mapping.js";
const SCHEMA_BASE_PATH = "../smatchitObjectOdmdb/schema";
const OBJECTS_BASE_PATH = "../smatchitObjectOdmdb/objects";
class ODMDBMappingManager {
constructor() {
this.mappings = new Map();
this.dataAvailability = new Map();
this.loadAllMappings();
this.checkDataAvailability();
}
loadAllMappings() {
// Load primary mappings (with custom enhancements)
this.mappings.set("seekers", seekersMapping);
this.mappings.set("jobads", jobadsMapping);
this.mappings.set("recruiters", recruitersMapping);
this.mappings.set("persons", personsMapping);
// Load remaining schemas dynamically
const remainingSchemas = [
"jobsteps",
"jobtitles",
"quizz",
"screens",
"sirets",
"trainingprovider",
"trainings",
];
remainingSchemas.forEach((schemaName) => {
const schemaPath = `${SCHEMA_BASE_PATH}/${schemaName}.json`;
try {
if (fs.existsSync(schemaPath)) {
const schemaData = JSON.parse(fs.readFileSync(schemaPath, "utf-8"));
const mapping = createSchemaMapping(schemaData, schemaName);
this.mappings.set(schemaName, mapping);
}
} catch (error) {
console.warn(
`Warning: Could not load ${schemaName} schema: ${error.message}`
);
this.mappings.set(schemaName, {
objectName: schemaName,
available: false,
error: error.message,
properties: {},
synonyms: {},
});
}
});
console.log(`🗺️ Loaded ${this.mappings.size} object mappings`);
}
checkDataAvailability() {
// Check which objects have actual data files
this.mappings.forEach((mapping, objectName) => {
const objectPath = `${OBJECTS_BASE_PATH}/${objectName}`;
const itemsPath = `${objectPath}/itm`;
let availability = {
schemaAvailable: mapping.available,
dataAvailable: false,
dataPath: itemsPath,
fileCount: 0,
sampleFiles: [],
};
try {
if (fs.existsSync(itemsPath)) {
const files = fs
.readdirSync(itemsPath)
.filter((f) => f.endsWith(".json") && f !== "backup")
.filter((f) => !fs.statSync(`${itemsPath}/${f}`).isDirectory());
availability.dataAvailable = files.length > 0;
availability.fileCount = files.length;
availability.sampleFiles = files.slice(0, 3); // First 3 files as samples
}
} catch (error) {
console.warn(
`Warning: Could not check data for ${objectName}: ${error.message}`
);
}
this.dataAvailability.set(objectName, availability);
});
// Log availability summary
const availableObjects = Array.from(this.dataAvailability.entries())
.filter(([_, availability]) => availability.dataAvailable)
.map(
([objectName, availability]) =>
`${objectName}(${availability.fileCount})`
)
.join(", ");
console.log(`📊 Data available for: ${availableObjects}`);
}
// Intelligent object detection from natural language
detectObjectFromQuery(nlQuery) {
const query = nlQuery.toLowerCase();
const detectedObjects = [];
// Direct object name mentions
this.mappings.forEach((mapping, objectName) => {
if (
query.includes(objectName) ||
query.includes(objectName.slice(0, -1))
) {
// singular form
detectedObjects.push({
object: objectName,
confidence: 0.9,
reason: `Direct mention of '${objectName}'`,
});
}
});
// Semantic object detection
const objectIndicators = {
seekers: [
"seekers",
"seeker",
"job seekers",
"candidates",
"applicants",
"people looking for jobs",
"job hunters",
"looking for work",
"experience",
"skills",
"salary expectation",
"availability",
],
jobads: [
"jobs",
"job postings",
"job ads",
"positions",
"openings",
"vacancies",
"employment opportunities",
"job offers",
"job description",
"job requirements",
"salary range",
],
recruiters: [
"recruiters",
"recruiter",
"hiring managers",
"hr",
"employers",
"hiring",
"recruitment",
"talent acquisition",
"headhunters",
],
persons: [
"people",
"users",
"profiles",
"personal information",
"contact details",
"names",
"demographics",
"biography",
],
sirets: [
"companies",
"businesses",
"organizations",
"employers",
"firms",
"corporations",
"enterprises",
],
};
Object.entries(objectIndicators).forEach(([objectName, indicators]) => {
const matches = indicators.filter((indicator) =>
query.includes(indicator)
);
if (matches.length > 0) {
const confidence = Math.min(0.8, matches.length * 0.3);
detectedObjects.push({
object: objectName,
confidence,
reason: `Semantic match: ${matches.join(", ")}`,
});
}
});
// Sort by confidence and remove duplicates
const uniqueObjects = detectedObjects.reduce((acc, current) => {
const existing = acc.find((item) => item.object === current.object);
if (!existing || current.confidence > existing.confidence) {
acc = acc.filter((item) => item.object !== current.object);
acc.push(current);
}
return acc;
}, []);
return uniqueObjects.sort((a, b) => b.confidence - a.confidence);
}
// Get data availability statistics
getDataAvailabilityStats() {
const availableObjects = [];
const objectStats = {};
for (const [objectType, mapping] of Object.entries(this.mappings)) {
if (mapping.available) {
availableObjects.push(objectType);
objectStats[objectType] = mapping.dataStats.fileCount;
}
}
const summary = availableObjects
.map((obj) => `${obj}(${objectStats[obj]})`)
.join(", ");
return {
availableObjects,
objectStats,
summary,
totalObjects: availableObjects.length,
};
}
// Check if a query is feasible given available data
validateQueryFeasibility(nlQuery, suggestedObject = null) {
const detectedObjects = suggestedObject
? [
{
object: suggestedObject,
confidence: 1.0,
reason: "Explicitly specified",
},
]
: this.detectObjectFromQuery(nlQuery);
if (detectedObjects.length === 0) {
return {
feasible: false,
reason: "Cannot determine which object type this query refers to",
suggestion:
"Please specify if you're looking for seekers, jobs, recruiters, or companies",
availableObjects: Array.from(this.dataAvailability.keys()).filter(
(obj) => this.dataAvailability.get(obj).dataAvailable
),
};
}
const primaryObject = detectedObjects[0];
const availability = this.dataAvailability.get(primaryObject.object);
if (!availability) {
return {
feasible: false,
reason: `Unknown object type: ${primaryObject.object}`,
suggestion: `Available objects: ${Array.from(this.mappings.keys()).join(
", "
)}`,
};
}
if (!availability.schemaAvailable) {
return {
feasible: false,
reason: `Schema not available for ${primaryObject.object}`,
suggestion: `Cannot process queries for ${primaryObject.object} - schema missing`,
};
}
if (!availability.dataAvailable) {
return {
feasible: false,
reason: `No data available for ${primaryObject.object}`,
suggestion: `${
primaryObject.object
} schema exists but no data files found. Available data: ${Array.from(
this.dataAvailability.entries()
)
.filter(([_, avail]) => avail.dataAvailable)
.map(([name, avail]) => `${name}(${avail.fileCount})`)
.join(", ")}`,
};
}
// Check if requested fields exist
const mapping = this.mappings.get(primaryObject.object);
const queryWords = nlQuery.toLowerCase().split(/\s+/);
const unmappedWords = [];
queryWords.forEach((word) => {
if (
word.length > 2 && // Skip short words
!mapping.synonyms[word] &&
!Object.keys(mapping.properties).includes(word) &&
![
"show",
"get",
"find",
"with",
"their",
"and",
"the",
"me",
"all",
].includes(word)
) {
unmappedWords.push(word);
}
});
return {
feasible: true,
primaryObject,
detectedObjects,
dataStats: {
fileCount: availability.fileCount,
sampleFiles: availability.sampleFiles,
},
fieldWarnings:
unmappedWords.length > 0
? `Some terms might not map to fields: ${unmappedWords.join(", ")}`
: null,
};
}
// Get mapping for a specific object
getMapping(objectName) {
return this.mappings.get(objectName);
}
// Get all available objects with data
getAvailableObjects() {
return Array.from(this.dataAvailability.entries())
.filter(
([_, availability]) =>
availability.dataAvailable && availability.schemaAvailable
)
.map(([objectName, availability]) => ({
object: objectName,
fileCount: availability.fileCount,
propertyCount: this.mappings.get(objectName)?.propertyCount || 0,
}));
}
// Get comprehensive field suggestions for an object
getFieldSuggestions(objectName, queryTerms = []) {
const mapping = this.getMapping(objectName);
if (!mapping || !mapping.available) return [];
const suggestions = [];
// Find fields that match query terms
queryTerms.forEach((term) => {
const field = mapping.synonyms[term.toLowerCase()];
if (field) {
const fieldInfo = mapping.properties[field];
suggestions.push({
field,
matchedTerm: term,
title: fieldInfo.title,
type: fieldInfo.type,
synonyms: fieldInfo.synonyms.slice(0, 3), // Top 3 synonyms
});
}
});
return suggestions;
}
// Generate intelligent error messages with suggestions
generateErrorMessage(nlQuery, error) {
const feasibility = this.validateQueryFeasibility(nlQuery);
if (!feasibility.feasible) {
return {
error: feasibility.reason,
suggestion: feasibility.suggestion,
availableObjects:
feasibility.availableObjects || this.getAvailableObjects(),
};
}
return {
error: error.message || "Unknown error",
suggestion: "Query seems valid but processing failed",
queryAnalysis: feasibility,
};
}
}
// Export class and singleton instance
export { ODMDBMappingManager };
export const odmdbMappingManager = new ODMDBMappingManager();
export default ODMDBMappingManager;

View File

@@ -0,0 +1,104 @@
// Persons schema mapping - person profile natural language support
import { createSchemaMapping } from "./base-mapping.js";
import fs from "node:fs";
const SCHEMA_PATH = "../smatchitObjectOdmdb/schema/persons.json";
let personsSchema = null;
try {
if (fs.existsSync(SCHEMA_PATH)) {
personsSchema = JSON.parse(fs.readFileSync(SCHEMA_PATH, "utf-8"));
}
} catch (error) {
console.warn(`Warning: Could not load persons schema: ${error.message}`);
}
export const personsMapping = createSchemaMapping(personsSchema, "persons");
// Additional persons-specific enhancements
if (personsMapping.available) {
const personsEnhancements = {
// Personal Information
"first name": "firstname",
"given name": "firstname",
name: "firstname",
"last name": "lastname",
"family name": "lastname",
surname: "lastname",
"full name": "fullname",
"display name": "fullname",
// Demographics
"birth date": "dt_birth",
birthday: "dt_birth",
"date of birth": "dt_birth",
age: "dt_birth",
born: "dt_birth",
gender: "pronom",
pronouns: "pronom",
// Contact & Communication
"personal email": "emailcom",
"communication email": "emailcom",
"contact email": "emailcom",
"email address": "emailcom",
// Profile Information
biography: "biography",
bio: "biography",
about: "biography",
description: "biography",
"personal story": "biography",
background: "biography",
hobbies: "hobbies",
interests: "hobbies",
activities: "hobbies",
pastimes: "hobbies",
leisure: "hobbies",
// Visual Profile
"profile picture": "imgavatar",
avatar: "imgavatar",
photo: "imgavatar",
image: "imgavatar",
picture: "imgavatar",
// Access & Privacy
"profile access": "profilaccess",
"privacy settings": "profilaccess",
visibility: "profilaccess",
"profile visibility": "profilaccess",
// Activity & Status
"last login": "last_login",
"last active": "last_login",
"last seen": "last_login",
"login time": "last_login",
// Account Information
"account created": "dt_create",
registration: "dt_create",
joined: "dt_create",
"sign up": "dt_create",
"profile updated": "dt_update",
"last modified": "dt_update",
};
// Merge enhancements into synonyms
Object.entries(personsEnhancements).forEach(([synonym, fieldName]) => {
personsMapping.synonyms[synonym.toLowerCase()] = fieldName;
});
// Add persons-specific context
personsMapping.context = {
description: "Personal profile information for users in the system",
primaryData: ["identity", "contact", "demographics", "profile"],
relationships: {
seekers: "Person who is seeking employment",
recruiters: "Person who is recruiting for companies",
},
};
}
export default personsMapping;

View File

@@ -0,0 +1,118 @@
// Recruiters schema mapping - recruiter natural language support
import { createSchemaMapping } from "./base-mapping.js";
import fs from "node:fs";
const SCHEMA_PATH = "../smatchitObjectOdmdb/schema/recruiters.json";
let recruitersSchema = null;
try {
if (fs.existsSync(SCHEMA_PATH)) {
recruitersSchema = JSON.parse(fs.readFileSync(SCHEMA_PATH, "utf-8"));
}
} catch (error) {
console.warn(`Warning: Could not load recruiters schema: ${error.message}`);
}
export const recruitersMapping = createSchemaMapping(
recruitersSchema,
"recruiters"
);
// Additional recruiters-specific enhancements
if (recruitersMapping.available) {
const recruitersEnhancements = {
// Identity & Contact
"recruiter id": "alias",
"recruiter name": "alias",
"hr id": "alias",
"hiring manager": "alias",
// Contact Information
"contact email": "email",
"recruiter email": "email",
"hiring email": "email",
"hr email": "email",
"contact phone": "phone",
"recruiter phone": "phone",
telephone: "phone",
"phone number": "phone",
// Company Associations
companies: "sirets",
employers: "sirets",
clients: "sirets",
businesses: "sirets",
organizations: "sirets",
"company list": "sirets",
"employer list": "sirets",
// Professional Information
tips: "tipsadvice",
advice: "tipsadvice",
articles: "tipsadvice",
guidance: "tipsadvice",
recommendations: "tipsadvice",
"help articles": "tipsadvice",
// Activity & Dates
joined: "dt_create",
registration: "dt_create",
"sign up": "dt_create",
"account created": "dt_create",
"last updated": "dt_update",
"profile updated": "dt_update",
modified: "dt_update",
// Status & Activity
"active recruiter": "status",
"recruiter status": "status",
"hiring status": "status",
availability: "status",
// Job Management
"job postings": "jobads",
"job ads": "jobads",
postings: "jobads",
advertisements: "jobads",
vacancies: "jobads",
openings: "jobads",
// Recruitment Activity
candidates: "candidates",
applicants: "applicants",
seekers: "seekers",
prospects: "prospects",
"talent pool": "candidates",
// Performance & Metrics
placements: "placements",
hires: "hires",
"successful hires": "placements",
"recruitment success": "placements",
};
// Merge enhancements into synonyms
Object.entries(recruitersEnhancements).forEach(([synonym, fieldName]) => {
recruitersMapping.synonyms[synonym.toLowerCase()] = fieldName;
});
// Add recruiter-specific context
recruitersMapping.context = {
description:
"Recruiters create and manage job postings, recruit for companies (sirets), and manage the hiring process",
primaryActions: [
"create jobads",
"manage candidates",
"process applications",
"schedule interviews",
],
relationships: {
sirets: "Companies the recruiter works for",
jobads: "Job postings created by this recruiter",
candidates: "People being recruited",
seekers: "Job seekers in recruitment process",
},
};
}
export default recruitersMapping;

View File

@@ -0,0 +1,134 @@
// Seekers schema mapping - comprehensive natural language support
import { createSchemaMapping } from "./base-mapping.js";
import fs from "node:fs";
const SCHEMA_PATH = "../smatchitObjectOdmdb/schema/seekers.json";
let seekersSchema = null;
try {
if (fs.existsSync(SCHEMA_PATH)) {
seekersSchema = JSON.parse(fs.readFileSync(SCHEMA_PATH, "utf-8"));
}
} catch (error) {
console.warn(`Warning: Could not load seekers schema: ${error.message}`);
}
export const seekersMapping = createSchemaMapping(seekersSchema, "seekers");
// Additional seeker-specific enhancements
if (seekersMapping.available) {
// Add seeker-specific synonym enhancements
const seekerEnhancements = {
// Work & Career
"work experience": "seekworkingyear",
"career experience": "seekworkingyear",
"professional experience": "seekworkingyear",
"years working": "seekworkingyear",
"job experience": "seekjobtitleexperience",
"previous jobs": "seekjobtitleexperience",
"work history": "seekjobtitleexperience",
"positions held": "seekjobtitleexperience",
// Job Search Status
urgency: "seekstatus",
"how fast": "seekstatus",
"job urgency": "seekstatus",
"looking urgently": "seekstatus",
"need job quickly": "seekstatus",
// Compensation
"expected salary": "salaryexpectation",
"salary expectation": "salaryexpectation",
"desired salary": "salaryexpectation",
"target salary": "salaryexpectation",
"pay expectation": "salaryexpectation",
"wage expectation": "salaryexpectation",
// Location preferences
"work location": "seeklocation",
"job location": "seeklocation",
"where to work": "seeklocation",
"preferred location": "seeklocation",
"work geography": "seeklocation",
// Skills & Abilities
"technical skills": "skills",
"professional skills": "skills",
competencies: "skills",
abilities: "skills",
expertise: "skills",
languages: "languageskills",
"language abilities": "languageskills",
"linguistic skills": "languageskills",
// Personality & Profile
"personality type": "mbti",
"personality profile": "mbti",
"MBTI type": "mbti",
"psychological profile": "mbti",
// Job Preferences
"job type": "seekjobtype",
"employment type": "seekjobtype",
"contract type": "seekjobtype",
"work type": "seekjobtype",
// Availability & Schedule
"working hours": "preferedworkinghours",
"work schedule": "preferedworkinghours",
"preferred hours": "preferedworkinghours",
"schedule preference": "preferedworkinghours",
"not available": "notavailabletowork",
unavailable: "notavailabletowork",
"blocked times": "notavailabletowork",
// Job Search Activity
"job applications": "jobadapply",
"applied jobs": "jobadapply",
"applications sent": "jobadapply",
"bookmarked jobs": "jobadsaved",
"saved jobs": "jobadsaved",
"favorite jobs": "jobadsaved",
"job invitations": "jobadinvitedtoapply",
"invited to apply": "jobadinvitedtoapply",
// Education & Training
education: "educations",
degree: "educations",
qualifications: "educations",
diploma: "educations",
studies: "educations",
// Communication preferences
notifications: "notificationformatches",
alerts: "notificationformatches",
"email preferences": "emailactivityreportweekly",
newsletter: "emailnewsletter",
};
// Merge enhancements into synonyms
Object.entries(seekerEnhancements).forEach(([synonym, fieldName]) => {
seekersMapping.synonyms[synonym.toLowerCase()] = fieldName;
});
// Add status value mappings
seekersMapping.statusValues = {
seekstatus: {
urgent: "startasap",
urgently: "startasap",
asap: "startasap",
quickly: "startasap",
immediately: "startasap",
fast: "startasap",
"no rush": "norush",
"taking time": "norush",
leisurely: "norush",
"not urgent": "norush",
"not looking": "notlooking",
"not active": "notlooking",
inactive: "notlooking",
},
};
}
export default seekersMapping;