${tabIcon(tab)}
@@ -388,7 +390,7 @@
}
function tabIcon(tab) {
- const icons = { analysis: '๐', coverletter: 'โ๏ธ', cvtips: '๐', qa: 'โ', benefits: 'โญ' };
+ const icons = { analysis: '๐', ats: '๐ฏ', coverletter: 'โ๏ธ', cvtips: '๐', qa: 'โ', benefits: 'โญ' };
return icons[tab] || '๐';
}
@@ -536,7 +538,11 @@
jobDescription: jobData.description,
jobTitle: jobData.jobTitle || 'Job',
action: 'generatePdf',
- template: 'amman'
+ // Jordan-based postings get the conservative local framing;
+ // everything else gets the GCC/international framing.
+ template: /jordan|amman|ุงูุฃุฑุฏู|ุนู
ูุงู|ุนู
ุงู/i.test(jobData.location || '')
+ ? 'amman'
+ : 'default'
}
}, resolve);
});
@@ -558,8 +564,20 @@
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
-
- showPanelToast(root, 'โ
PDF Downloaded Successfully!', 'success');
+
+ // Surface what the tailoring actually achieved, and warn loudly if
+ // the server had to fall back because the model tried to fabricate.
+ const ats = response.data.ats || {};
+ let msg = 'โ
PDF downloaded';
+ if (ats.score) msg += ` โ est. ATS match ${ats.score}%`;
+ if (ats.tailored === false) msg += ' (untailored fallback)';
+ if (ats.violations && ats.violations.length) {
+ msg += ` โ ๏ธ blocked fabricated claims: ${ats.violations.join(', ')}`;
+ }
+ if (ats.missing && ats.missing.length) {
+ console.warn('[LJA] Job requirements not claimable from profile:', ats.missing);
+ }
+ showPanelToast(root, msg, 'success');
} else {
throw new Error(response?.error || 'Failed to generate PDF from server');
}
@@ -588,6 +606,7 @@
const loadingMsgs = {
analysis: 'Analyzing job fit...',
coverletter: 'Writing cover letter...',
+ ats: 'Scoring CV against ATS...',
cvtips: 'Generating CV tips...',
qa: 'Preparing Q&A answers...',
benefits: 'Summarizing benefits...'
@@ -669,142 +688,6 @@
}
}
- // โโโ Prompt Builder โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-
- function buildPrompt(tab, job, userProfile, language) {
- const langInstruction = language === 'arabic'
- ? 'Respond entirely in Arabic.'
- : language === 'english'
- ? 'Respond entirely in English.'
- : 'Respond in the same language as the job posting (Arabic or English).';
-
- const jobContext = `
-Job Title: ${job.jobTitle || 'Not specified'}
-Company: ${job.company || 'Not specified'}
-Location: ${job.location || 'Not specified'}
-Description:
-${job.description || 'No description available'}
-${job.skills.length ? `\nRequired Skills: ${job.skills.join(', ')}` : ''}`.trim();
-
- const profileBlock = `MY PROFILE:\n${userProfile}`;
-
- const prompts = {
- analysis: `You are a senior career advisor specializing in tech roles in the Middle East.
-${langInstruction}
-Analyze this job posting against my profile. Be direct and honest.
-
-${profileBlock}
-
-JOB POSTING:
-${jobContext}
-
-Provide in this exact format:
-## MATCH SCORE: X/100
-Brief explanation.
-
-## โ
STRONG MATCHES
-- bullet points of matching skills/experience
-
-## โ ๏ธ GAPS
-- bullet points of missing requirements or weak areas
-
-## ๐ฏ RECOMMENDATION
-Apply / Apply with preparation / Skip โ with clear reason
-
-## ๐ก KEY SELLING POINTS
-- what to emphasize when applying
-
-## ๐ท๏ธ BEST CV VARIANT
-Which of my CV variants (Solutions Architect / Flutter Developer / GIS Developer / FinTech Engineer) best fits and why`,
-
- coverletter: `Write a compelling, personalized cover letter for this position.
-${langInstruction}
-
-${profileBlock}
-
-JOB:
-${jobContext}
-
-Requirements:
-- 3 paragraphs maximum
-- Reference specific requirements from the job description
-- Highlight my most relevant achievements with numbers
-- Professional but confident tone โ not generic
-- End with a strong call to action
-- Do NOT use placeholder brackets โ write a complete ready-to-send letter
-- Address to "Hiring Team" if no specific name is available
-- Sign as "Hamza Ayed"`,
-
- cvtips: `Based on this job posting, provide specific CV optimization advice.
-${langInstruction}
-
-${profileBlock}
-
-JOB:
-${jobContext}
-
-Provide:
-## ๐ SUGGESTED HEADLINE
-A LinkedIn-style headline optimized for this specific role (max 120 characters)
-
-## ๐ SUGGESTED SUMMARY
-3-4 sentence professional summary tailored for this role
-
-## ๐ KEYWORDS TO ADD
-- specific keywords from the job to add to CV
-
-## โฌ๏ธ EXPERIENCE TO PRIORITIZE
-- which of my experiences to move to top or emphasize
-
-## โ๏ธ WHAT TO DE-EMPHASIZE
-- what to remove or minimize for this application
-
-## ๐ฏ SKILLS SECTION
-- specific skills to list for this role`,
-
- qa: `I am applying for this job and need to answer application questions.
-${langInstruction}
-Answer each question based on my profile. Be specific, professional, and concise.
-
-${profileBlock}
-
-JOB:
-${jobContext}
-
-${job.questions.length > 0
- ? 'QUESTIONS TO ANSWER:\n' + job.questions.map((q, i) => `${i + 1}. [${q.type}] ${q.question}`).join('\n')
- : 'Generate answers for these common application questions:\n1. Why are you interested in this role?\n2. What is your relevant experience?\n3. What are your salary expectations?\n4. When can you start?\n5. Do you require visa sponsorship?\n6. What is your current notice period?'}
-
-For each question provide a clear, professional answer ready to paste. Keep answers concise (2-4 sentences for text fields).`,
-
- benefits: `Analyze this job posting and extract all benefits and advantages.
-${langInstruction}
-
-JOB:
-${jobContext}
-
-Provide:
-## ๐ฐ COMPENSATION & BENEFITS
-- salary, bonuses, equity if mentioned; otherwise state "Not specified"
-
-## ๐ข WORK ARRANGEMENT
-- remote/hybrid/onsite, flexibility, hours
-
-## ๐ GROWTH OPPORTUNITIES
-- career development, training, advancement potential
-
-## ๐ COMPANY PERKS
-- insurance, vacation, equipment, culture perks etc.
-
-## โ ๏ธ POTENTIAL CONCERNS
-- red flags, very demanding requirements, unclear aspects
-
-## ๐ OVERALL ATTRACTIVENESS: X/10
-Brief honest assessment of this opportunity for my profile`
- };
-
- return prompts[tab] || prompts.analysis;
- }
// โโโ Markdown Renderer โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
@@ -933,14 +816,28 @@ Brief honest assessment of this opportunity for my profile`
// โโโ Utilities โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ // Markers that identify a profile saved before the CV was rewritten around
+ // the Senior Mobile Architect positioning. A profile containing any of these
+ // is describing a person who no longer matches the master CV, so every prompt
+ // built from it would contradict the PDF that actually gets sent.
+ const STALE_PROFILE_MARKERS = [
+ 'CTO & Technical Architect',
+ 'Senior Backend Engineer & Systems Architect',
+ 'IntaleqMaps',
+ 'hamzaayed.dev@gmail.com'
+ ];
+
+ function isStaleProfile(text) {
+ if (!text) return true;
+ return STALE_PROFILE_MARKERS.some(marker => text.includes(marker));
+ }
+
function getSettings() {
return new Promise(resolve => {
chrome.storage.sync.get(['apiKey', 'userProfile', 'language'], (data) => {
- if (data.userProfile && (data.userProfile.includes('hamzaayed@intaleqapp.com') || data.userProfile.includes('hamzaayedflutter@gmail.com') || data.userProfile.includes('hamzaayed@tripz-egypt.com'))) {
- data.userProfile = data.userProfile
- .replace(/hamzaayed@intaleqapp\.com/g, 'hamzaayed.dev@gmail.com')
- .replace(/hamzaayedflutter@gmail\.com/g, 'hamzaayed.dev@gmail.com')
- .replace(/hamzaayed@tripz-egypt\.com/g, 'hamzaayed.dev@gmail.com');
+ if (isStaleProfile(data.userProfile) && typeof renderProfileText === 'function') {
+ console.warn('[LJA] Stored profile is out of date with the master CV โ migrating to profile_data.js.');
+ data.userProfile = renderProfileText();
chrome.storage.sync.set({ userProfile: data.userProfile });
}
resolve(data);
diff --git a/cv_template.html b/cv_template.html
deleted file mode 100644
index 0827364..0000000
--- a/cv_template.html
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
Professional Summary
-
-
{{TAILORED_SUMMARY}}
-
-
-
-
Technical Skills
-
-
Core Focus: {{DYNAMIC_SKILLS}}
-
Backend & Architecture: PHP (Workerman), Node.js, NestJS, Python (FastAPI/Flask), REST APIs, WebSockets, Event-Driven Architecture
-
Infrastructure & Cloud: Docker, Linux, Nginx, Redis, CI/CD (GitHub Actions), AWS
-
Databases & Geospatial: PostgreSQL/PostGIS, MySQL, OpenStreetMap (OSM), GraphHopper, MapLibre GL, Spatial Queries
-
Mobile: Flutter/Dart, GetX, BLoC/Cubit
-
-
Selected Technical Highlights
-
- - Built proprietary OSM-based mapping infrastructure replacing Google Maps APIs
- - Engineered WebSocket-based real-time ride tracking systems
- - Developed offline-first mapping SDKs published on pub.dev and npm
- - Designed async AI document-processing pipelines using vision models
- - Optimized routing infrastructure using GraphHopper and PostGIS
-
-
-
Professional Experience
-
-
-
-
- - Led the full-stack architecture of a smart transportation ecosystem supporting 1,800+ drivers and 2,500+ riders, building the core backend with PHP/Workerman.
- - Architected the proprietary mapping platform (IntaleqMaps), orchestrating GraphHopper routing, OSM tile serving, and PostGIS spatial queries via a NestJS API layer, saving $10,000+/month in operational costs.
-
-
-
-
-
-
- - Co-founded and architected Egypt's homegrown ride-hailing platform, managing the entire distributed ecosystem with real-time tracking for 4,318 drivers and 2,464 riders.
- - Implemented robust event-driven architecture for real-time driver/rider matching and WebSockets-based route optimization.
- - Integrated local digital payment gateways and driver payout systems, supporting an 8% commission structure that drove a $0.78 Customer Acquisition Cost.
-
-
-
-
-
-
- - Delivered 25+ production enterprise applications across GIS, FinTech, and utilities, leading full lifecycle architecture for clients in the MENA region.
- - Developed Nabih (AI Smart Responder): designed and built an intelligent virtual assistant system connecting a Flutter mobile application (GetX/Cubit) with custom PHP backend APIs.
- - Developed Musadaq (AI-Powered Invoice Processing): engineered an automated KYC and invoice document processor using AI vision models and asynchronous processing pipelines.
-
-
-
-
Notable Projects
-
- - IntaleqMaps Engine: Engineered a proprietary mapping platform orchestrating GraphHopper routing, OSM tile serving, and PostGIS spatial queries via a NestJS API layer, replacing Google Maps API across the MENA region.
- - Nabih AI Virtual Assistant: Architected an automated customer support solution connecting a Flutter application (GetX/Cubit) to custom high-concurrency PHP backend APIs.
- - Musadaq AI Document Processor: Engineered an automated KYC and invoice document processing platform utilizing AI vision models and async processing pipelines.
- - Meta Ads Manager & SaaS Gateways: Deployed multi-tenant platforms using NestJS/React (Meta Ads Manager) and high-concurrency Node.js (WhatsApp bridge managing headless Puppeteer sessions in Docker) to automate operations.
-
-
-
Open Source Contributions
-
- - intaleq_maps (Flutter SDK): Published on pub.dev/packages/intaleq_maps. Custom map rendering, offline caching, and route plotting package optimized for low-bandwidth environments.
- - intaleq-maps-gl (NPM Library): Published on npmjs.com/package/intaleq-maps-gl. Web-based Mapbox GL compatible library optimized for custom OSM tiles and routing integration.
-
-
-
Education & Certifications
-
- - BS Mathematics (Applied Computing & Algorithms), Mutah University (2003โ2007)
- - Google Data Analytics Professional Certificate (Coursera)
- - IBM Data Analyst Professional Certificate (Coursera)
- - Meta APIs & Django Web Framework Course Certificates (Coursera)
- - AWS Cloud Practitioner & Cloud Architecture Fundamentals
-
-
-
Languages
-
Arabic: Native | English: Professional Working Proficiency | Turkish: Limited Working Proficiency
-
-
Availability & Work Authorization
-
- Available Immediately | Open to Remote, Hybrid & Relocation (GCC/Europe/MENA) | Valid Passport
-
-
-
-
diff --git a/deploy.sh b/deploy.sh
index 14b21d6..d4d6bf3 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -2,6 +2,15 @@
echo "๐ Starting Deployment..."
+# Keep the backend's copy of the profile in sync with profile_data.js.
+# Skipping this ships a CV built from stale facts.
+if command -v node >/dev/null 2>&1; then
+ echo "๐ Syncing profile.json from profile_data.js..."
+ node sync_profile.js || { echo "โ Profile sync failed โ aborting deploy."; exit 1; }
+else
+ echo "โ ๏ธ node not found โ skipping profile sync. Verify server/profile.json is current."
+fi
+
# Add all changes
git add .
diff --git a/manifest.json b/manifest.json
index 6d9427e..78945d6 100644
--- a/manifest.json
+++ b/manifest.json
@@ -22,6 +22,7 @@
"https://www.linkedin.com/jobs/*"
],
"js": [
+ "profile_data.js",
"prompts.js",
"content.js"
],
@@ -50,6 +51,7 @@
"https://www.linkedin.com/search/results/all/*"
],
"js": [
+ "profile_data.js",
"search_analyzer.js"
],
"css": [
diff --git a/popup.html b/popup.html
index a1d57e2..6b36b9a 100644
--- a/popup.html
+++ b/popup.html
@@ -527,6 +527,7 @@
+