Auto-deploy: 2026-08-05 16:17:53

This commit is contained in:
Hamza-Ayed
2026-08-05 16:17:53 +03:00
parent 83506f00a2
commit 731ced99d1
20 changed files with 1772 additions and 1150 deletions
+298 -93
View File
@@ -1,38 +1,134 @@
// prompts.js — All AI prompts v3
// LANGUAGE RULES: Analysis = match job language. Everything else = ENGLISH ALWAYS.
// prompts.js — All AI prompts v4 (ATS-engineered)
// ============================================================================
// LANGUAGE RULES: Analysis = Arabic. Everything else = ENGLISH ALWAYS.
//
// All identity facts come from PROFILE_DATA (profile_data.js). Nothing in this
// file may hardcode a job title, a metric, a date or a contact detail.
// ============================================================================
// ─── ATS methodology block ──────────────────────────────────────────────────
// This is the part that actually moves the needle with parsers and recruiters.
// It is injected into every CV/keyword-facing prompt.
const ATS_METHOD = `
ATS METHODOLOGY — APPLY ALL OF THIS:
1. EXACT-TERM MIRRORING (most important rule)
ATS matching is literal, not semantic. If the job says "React Native", writing
"cross-platform mobile" scores ZERO. Copy the job posting's EXACT wording for
any skill I genuinely have. Do not paraphrase, do not use a synonym, do not
pluralise differently.
2. DUAL FORM FOR ACRONYMS
Write both forms on first use so either query matches:
"Continuous Integration / Continuous Deployment (CI/CD)", "Application
Programming Interface (API)", "Know Your Customer (KYC)".
3. TITLE ALIGNMENT
The CV headline should closely mirror the job's title when that title is an
honest description of my record. Recruiters and ATS both weight title match
heavily. Never invent seniority.
4. KEYWORD FREQUENCY
A critical keyword should appear 2-3 times across the document (summary,
skills, and at least one experience bullet) — never stuffed, always inside a
real sentence that describes something I actually did.
5. BULLET FORMULA (XYZ)
Every bullet: "Accomplished [X] as measured by [Y] by doing [Z]."
Start with a strong past-tense verb. Lead with the outcome, not the task.
Prefer a real number over an adjective every single time.
6. HARD SKILLS BEAT SOFT SKILLS
Prioritise tools, languages, frameworks, protocols and platforms. Soft skills
("team player", "communicator") are near-worthless to an ATS — include only
where the job explicitly names them as a requirement.
7. PARSER SAFETY
No tables, no columns, no text boxes, no graphics, no headers/footers, no
icons or symbols in place of words. Standard section headings only
("Professional Summary", "Technical Skills", "Professional Experience",
"Education"). Dates as "MMM YYYY – MMM YYYY".
8. HONEST GAP HANDLING
If the job requires something I do not have, do NOT insert it. Instead find
the closest genuine adjacent experience and name it accurately.`;
// ─── Integrity rules, generated from the profile ────────────────────────────
function buildIntegrityRules(P) {
const b = P.boundaries;
return `
STRICT INTEGRITY RULES — VIOLATING ANY OF THESE INVALIDATES THE OUTPUT:
1. NEVER invent a skill, tool, framework, employer, metric or certification that
is not present in MY PROFESSIONAL PROFILE below.
2. NEVER use these titles: ${P.forbiddenTitles.join(', ')}.
Allowed titles only: ${P.allowedTitles.join(', ')}.
3. NEVER claim any of the following — I have no production experience with them:
${b.neverClaim.join(', ')}.
4. MY GENUINE STRENGTHS (lead with these):
${b.strongIn.map(s => ' • ' + s).join('\n')}
5. MY HONEST LIMITS (acknowledge, never paper over):
${b.limitedIn.map(s => ' • ' + s).join('\n')}
6. Every number I use must be one of the real metrics in my profile. Do not
round up, do not extrapolate, do not invent new ones.
7. Do not mention: ${P.voice.neverMention.join('; ')}.
8. Banned phrasing (reads as AI-generated or as filler):
${P.voice.banned.join(' / ')}.`;
}
function buildPromptV2(tab, job, userProfile, language) {
// Force Arabic for the analysis tab to ensure full comprehension
const analysisLang = 'Respond ENTIRELY in Arabic. All headings, explanations, and bullets MUST be in Arabic. and RTL';
const P = (typeof PROFILE_DATA !== 'undefined') ? PROFILE_DATA : null;
if (!P) {
console.error('[LJA] profile_data.js not loaded — prompts will be degraded.');
}
const id = P ? P.identity : {};
const analysisLang =
'Respond ENTIRELY in Arabic. All headings, explanations and bullets MUST be in Arabic, and RTL.';
// Cap the description here rather than letting the transport truncate the
// whole prompt. Truncation at the transport layer cuts from the END, which is
// exactly where the job posting and the required output format live.
const MAX_DESCRIPTION_CHARS = 7000;
const rawDescription = job.description || 'No description available';
const description = rawDescription.length > MAX_DESCRIPTION_CHARS
? rawDescription.slice(0, MAX_DESCRIPTION_CHARS) + '\n[description truncated]'
: rawDescription;
const ctx = [
'Job Title: ' + (job.jobTitle || 'Not specified'),
'Company: ' + (job.company || 'Not specified'),
'Location: ' + (job.location || 'Not specified'),
'Type: ' + (job.jobType || 'Not specified'),
'Description:\n' + (job.description || 'No description available'),
job.skills.length ? 'Required Skills: ' + job.skills.join(', ') : ''
'Description:\n' + description,
(job.skills && job.skills.length) ? 'Required Skills: ' + job.skills.join(', ') : ''
].filter(Boolean).join('\n');
const prof = 'MY PROFESSIONAL PROFILE:\n' + userProfile;
// Prefer the stored/edited profile; fall back to the rendered source of truth.
const profileText = (userProfile && userProfile.trim())
? userProfile
: (typeof renderProfileText === 'function' ? renderProfileText() : '');
const prof = 'MY PROFESSIONAL PROFILE:\n' + profileText;
const co = job.company || 'this company';
const loc = job.location || 'Middle East';
const STRICT_RULES = P ? buildIntegrityRules(P) : '';
const STRICT_RULES = `
STRICT INTEGRITY RULES — VIOLATING THESE IS FORBIDDEN:
1. NEVER invent skills, tools, frameworks, or certifications not explicitly listed in MY PROFESSIONAL PROFILE.
2. If the job requires a skill I do not have (e.g., TensorFlow, PyTorch, Scikit-learn, Spark, Hadoop, Kubernetes, deep NLP, generative AI model training), ACKNOWLEDGE THE GAP honestly. Do NOT fabricate experience.
3. My AI experience is LIMITED to: AI vision models for document processing (Musadaq), AI smart responder (Nabih), Gemini API integration (LinkedIn extension), and Python backend automation. I do NOT have MLOps pipeline experience, model training, or deep learning research.
4. My TRUE core stack is: PHP (Workerman), Node.js, NestJS, Python (FastAPI/Flask), PostgreSQL/PostGIS, Docker, Flutter — NOT data science or ML engineering.
5. Always prioritize my REAL architecture achievements (IntaleqMaps, Tripz, 25+ apps, $10K/month savings) over generic AI buzzwords.`;
const Pr = {};
const P = {};
// ── TAB: Analysis (Arabic) ────────────────────────────────────────────────
Pr.analysis = `You are an elite career strategist and a hiring manager who has
screened thousands of engineering CVs. Evaluate this job against my profile with
brutal honesty and EXTREME brevity.
P.analysis = `You are an elite career strategist.
${analysisLang}
Evaluate this job against my profile with brutal honesty and EXTREME brevity.
DO NOT recount my history, military background, or summarize my profile. Keep it actionable and short.
CRITICAL RULE: The user is a Senior Backend Engineer and Technical Lead who built and scaled production systems from zero. Position his 0-to-1, hands-on delivery experience as a massive advantage for any engineering team. Do NOT downgrade his technical leadership.
CRITICAL FRAMING: I am a Senior Mobile Architect and Founding Engineer who has
taken two ride-hailing platforms from zero to live operations, owning mobile,
backend, geo-infrastructure, security and DevOps. Position that end-to-end 0-to-1
ownership as the core advantage. Do NOT downgrade it to "just a Flutter developer".
Equally: do NOT inflate it into architecture-astronaut or CTO language.
DO NOT recount my history or summarise my profile back to me. Be actionable.
${STRICT_RULES}
@@ -41,25 +137,32 @@ ${prof}
JOB POSTING:
${ctx}
Respond in this EXACT concise structure:
Respond in this EXACT structure:
## 🎯 VERDICT: [YES - APPLY / NO - SKIP]
[One short sentence explaining why]
## 🎯 القرار: [تقدّم / لا تتقدّم]
[سطر واحد قصير يشرح السبب]
## ✅ WHY IT FITS (If Yes)
- [Bullet point 1]
- [Bullet point 2]
- [Bullet point 3]
## 📊 نسبة المطابقة التقديرية: X%
[سطر واحد: على أي أساس حسبتها]
## ❌ WHY IT MIGHT NOT FIT (If No or Maybe)
- [Bullet point 1 - e.g. location, specific missing skill]
- [Bullet point 2]
## ✅ نقاط القوة هنا
- [نقطة 1 — اربطها بمتطلب محدد من الإعلان]
- [نقطة 2]
- [نقطة 3]
## 📝 CV TWEAKS (If Yes)
- [What to emphasize in the CV]
- [What to de-emphasize]`;
## ❌ الفجوات الحقيقية
- [فجوة 1 — ومدى خطورتها: قاتلة / قابلة للمعالجة / شكلية]
- [فجوة 2]
P.coverletter = `You are an expert career writer. Write a COMPLETE, READY-TO-SEND cover letter.
## 📝 تعديلات السيفي المطلوبة
- [ما الذي يجب إبرازه]
- [ما الذي يجب تقليصه]
## 🔑 كلمات مفتاحية ناقصة يجب إضافتها حرفياً
- [4-6 كلمات منسوخة حرفياً من الإعلان]`;
// ── TAB: Cover letter ─────────────────────────────────────────────────────
Pr.coverletter = `You are an expert career writer. Write a COMPLETE, READY-TO-SEND cover letter.
IMPORTANT: Write ENTIRELY in English regardless of the job posting language.
${STRICT_RULES}
@@ -73,27 +176,36 @@ FORMAT — follow EXACTLY:
Dear ${co} Team,
[PARAGRAPH 1 — HOOK (3 sentences max): Compelling connection between my background and this role. Mention the company by name. NO generic "I am writing to apply" openers.]
[PARAGRAPH 1 — HOOK (3 sentences max): A specific connection between my record and
this role. Name the company. Open with something I BUILT, not with an intention to
apply.]
[PARAGRAPH 2 — PROOF (4-5 sentences): Match 3-4 job requirements to my REAL achievements with NUMBERS. Use "At Intaleq, I..." or "When building Tripz, I..." Be concrete.]
[PARAGRAPH 2 — PROOF (4-5 sentences): Match 3-4 of this job's stated requirements
to my REAL achievements, each with a number. Use "At Intaleq, I..." / "Building
Tripz, I...". Mirror the job's exact technical vocabulary where it matches my real
skills.]
[PARAGRAPH 3 — CLOSE (2-3 sentences): Enthusiasm for THIS company. Confident call to action requesting an interview.]
[PARAGRAPH 3 — CLOSE (2-3 sentences): Why THIS company specifically. Confident,
non-needy call to action requesting a conversation.]
Best regards,
Hamza Ayed
hamzaayed.dev@gmail.com
+962 79 858 3052
${id.fullName}
${id.email}
${id.phone}
CRITICAL RULES:
- MUST be in English
- NO brackets or placeholders — use ACTUAL names and data
- Every sentence specific to THIS job at ${co}
- NO brackets or placeholders in the final output — use ACTUAL names and data
- Every sentence must be unusable for any other job posting
- Under 300 words total
- Tone MUST be professional, direct, and confident. Focus on delivery, impact, and hands-on engineering. DO NOT mention military history. DO NOT use buzzwords like "sanctioned markets", "serving millions", "disruptive".`;
- Tone: ${P ? P.voice.tone : 'direct and evidence-first'}`;
P.cvtips = `You are a LinkedIn optimization expert and ATS specialist.
// ── TAB: CV tips / LinkedIn optimisation ──────────────────────────────────
Pr.cvtips = `You are an ATS specialist and LinkedIn optimisation expert.
IMPORTANT: Respond ENTIRELY in English regardless of the job posting language.
${ATS_METHOD}
${STRICT_RULES}
${prof}
@@ -104,53 +216,126 @@ ${ctx}
Respond EXACTLY:
## LINKEDIN HEADLINE
[One headline, EXACTLY under 80 characters, ATS-optimized. Format like: Senior Backend Engineer & Technical Lead | PHP, NestJS, Docker | Building for Scale]
[One headline, UNDER 220 characters (LinkedIn's real limit — use the room).
Format: <Title mirroring the job> | <3-4 exact hard skills from the posting that I
genuinely have> | <one proof point with a number>]
## PROFESSIONAL SUMMARY
[3-4 sentences tailored summary ready to paste — in English. CRITICAL: Focus on delivery, cost optimization, and hands-on engineering. Use a professional, direct, no-fluff tone. Emphasize impact: what you built, numbers you achieved, problems you solved. DO NOT use academic or AI-generated phrases like 'I leverage my expertise'. DO NOT invent industries like 'banking' unless they are in MY PROFILE.]
[3-4 sentences, ready to paste. Lead with what I built and the numbers. Mirror the
job's exact terminology. No academic phrasing, no "I leverage my expertise".]
## ATS KEYWORDS TO ADD
- [10-15 specific keywords from this job that MUST appear in CV]
## ATS KEYWORDS — EXACT MATCH REQUIRED
[Table-free list of 12-15 keywords copied VERBATIM from the job posting that I can
honestly claim. Mark each: (HAVE) if already in my CV, (ADD) if missing.]
## KEYWORDS I CANNOT HONESTLY CLAIM
[Anything the job wants that I genuinely lack — with the nearest adjacent real
experience I can offer instead. Be blunt.]
## EXPERIENCE TO LEAD WITH
- [Which role first and which 3-4 bullet points to highlight]
- [Which role first, and the 3-4 exact bullets to surface — quote them from my profile]
## REMOVE OR MINIMIZE
- [What to de-emphasize for this application]
## REMOVE OR MINIMISE
- [What to cut for this specific application and why]
## SKILLS SECTION (priority order)
1. [Most important skill]
## SKILLS SECTION (priority order, exact job wording)
1. [Most important]
2. [Second]
3. [Continue 8-10 skills]
3. [Continue to 10]
## NEW BULLET POINTS TO ADD
- [2-3 new achievement bullets ready to paste into CV — in English]`;
- [2-3 new bullets in XYZ format, built ONLY from real achievements in my profile,
rewritten to carry this job's exact keywords]`;
const dynamicQuestions = job.questions && job.questions.length > 0
// ── TAB: ATS match report (new) ───────────────────────────────────────────
Pr.ats = `You are an ATS simulation engine. Score my CV against this job the way
a real applicant tracking system would, then tell me exactly how to close the gap.
Respond ENTIRELY in English.
${ATS_METHOD}
${STRICT_RULES}
${prof}
JOB:
${ctx}
Respond EXACTLY:
## OVERALL ATS SCORE: X/100
[One line on how that breaks down]
## SCORE BREAKDOWN
- Hard skill match: X/40
- Title / seniority match: X/20
- Domain & industry match: X/15
- Years of experience match: X/15
- Education & certification match: X/10
## MUST-HAVE REQUIREMENTS — VERDICT PER ITEM
[For every hard requirement in the posting: | Requirement | MET / PARTIAL / MISSING | Evidence from my profile |
Write as plain lines, not a markdown table — tables break ATS parsing when copied.]
## EXACT PHRASES TO INSERT
[5-8 lines, each one a sentence I can paste verbatim into my CV. Each must be
TRUE per my profile and carry a keyword copied exactly from the posting.]
## DISQUALIFIERS
[Anything that would auto-reject me: location, work authorisation, hard years
requirement, mandatory certification. If none, say "None detected".]
## VERDICT
[APPLY AS-IS / APPLY AFTER EDITS / SKIP] — one sentence of reasoning.`;
// ── TAB: Application form Q&A ─────────────────────────────────────────────
const dynamicQuestions = (job.questions && job.questions.length > 0)
? job.questions.map((q, i) => `${i + 1}. "${q.question}" [type: ${q.type}]`).join('\n')
: '1. "Why are you interested in this role?" [type: text]\n2. "What is your relevant experience?" [type: text]\n3. "What are your salary expectations?" [type: text]\n4. "When can you start?" [type: text]\n5. "Do you require visa sponsorship?" [type: text]';
: '1. "Why are you interested in this role?" [type: text]\n' +
'2. "What is your relevant experience?" [type: text]\n' +
'3. "What are your salary expectations?" [type: text]\n' +
'4. "When can you start?" [type: text]\n' +
'5. "Do you require visa sponsorship?" [type: text]';
P.qa = `You are a form-filling assistant. Your ONLY job is to answer application form questions.
Pr.qa = `You are a form-filling assistant. Your ONLY job is to answer application
form questions accurately.
STRICT RULES:
- Return ONLY a raw JSON object. Nothing else.
- Do NOT write cover letters, introductions, paragraphs, or markdown.
- Do NOT use headers like "###" or "##".
- Do NOT use code blocks like \`\`\`json.
- For number/numeric questions: answer with JUST a number (e.g. "6").
- For yes/no or select questions: answer with JUST "Yes" or "No".
- For salary questions: Output ONLY a number. IMPORTANT: Adapt the number intelligently to the job's likely currency (e.g., if UAE/Saudi: ~30000 AED/SAR. If remote USD: ~6000 USD).
- For text questions: answer in 1 short sentence max.
- Keys must be the EXACT question text.
STRICT OUTPUT RULES:
- Return ONLY a raw JSON object. Nothing else. No markdown, no code fences, no prose.
- Keys must be the EXACT question text as given.
- Numeric questions: answer with JUST a number (e.g. "8").
- Yes/No or select questions: answer with JUST "Yes" or "No".
- Text questions: 1 short sentence, maximum.
MY PERSONAL DETAILS & PREFERENCES (Use these for answers):
- Location: Amman, Jordan
- Phone / Country Code: +962
- Notice Period / Start Date: Available Immediately
- Salary Expectations: Competitive / Negotiable (If forced to give a number, calculate based on the job's currency as instructed above).
YEARS-OF-EXPERIENCE RULES (compute, do not guess):
- Total professional software experience: since Jan 2017.
- Flutter / mobile: since Jan 2017 (Flutter-primary since ~2019).
- Ride-hailing / real-time mobility systems: since Jan 2024.
- Payment / fintech integration: since Jan 2024.
- If asked about a technology I do NOT have (see NEVER CLAIM), answer "0".
SALARY RULES:
- Output ONLY a number, matching the job's likely currency:
UAE → AED monthly, Saudi → SAR monthly, Jordan → JOD monthly,
Egypt → EGP monthly, remote/international → USD monthly.
- Anchor on senior mobile architect market rate for that location. Do not lowball,
do not fantasise. If the field allows text, prefer "Negotiable".
MY PERSONAL DETAILS:
- Full name: ${id.fullName}
- Location: ${id.location}
- Phone: ${id.phone}
- Email: ${id.email}
- LinkedIn: ${id.linkedin}
- Notice period / start date: Available immediately
- Work authorisation: Jordanian citizen, valid passport. Requires sponsorship for
GCC/EU roles. Fully authorised for remote contract work.
- Willing to relocate: Yes (GCC / MENA / Europe)
${STRICT_RULES}
MY PROFILE:
${userProfile}
${profileText}
JOB:
${ctx}
@@ -158,14 +343,15 @@ ${ctx}
QUESTIONS TO ANSWER:
${dynamicQuestions}
RESPOND WITH ONLY THIS FORMAT (raw JSON, no wrapping, answering ONLY the questions listed above):
RESPOND WITH ONLY THIS FORMAT (raw JSON, answering ONLY the questions listed above):
{
"question 1 text here": "concise answer",
"question 2 text here": "concise answer"
}`;
P.benefits = `You are a career analyst specializing in tech compensation in MENA.
IMPORTANT: Respond ENTIRELY in English regardless of the job posting language.
// ── TAB: Benefits / compensation ──────────────────────────────────────────
Pr.benefits = `You are a career analyst specialising in tech compensation across
MENA and the GCC. Respond ENTIRELY in English.
${prof}
@@ -176,41 +362,60 @@ Respond EXACTLY:
## COMPENSATION ESTIMATE
- **Mentioned salary:** [exact text or "Not disclosed"]
- **Market estimate:** [realistic range in USD based on role, seniority, location]
- **Benefits listed:** [bonuses, equity, insurance]
- **Market estimate:** [realistic monthly range in LOCAL currency + USD equivalent,
for MY seniority in THIS location]
- **My realistic ask:** [a specific number to open with, and my walk-away floor]
- **Benefits listed:** [bonuses, equity, insurance, relocation]
## WORK SETUP
- **Type:** [Remote / Hybrid / On-site]
- **Location:** [where + relocation support]
- **Location & relocation:** [where + whether sponsorship/relocation is offered]
- **Visa reality:** [as a Jordanian citizen — what this role actually requires]
## CAREER VALUE
- **Growth potential:** [what this leads to in 2-3 years]
- **Skills I will gain:** [new skills/tech]
- **Resume value:** [how it improves my CV]
- **Skills I would gain:** [specifically what is new versus my current stack]
- **CV value:** [does this brand/domain strengthen my next move]
## WHAT IS ATTRACTIVE
- [3-5 appealing aspects for MY profile]
- [3-5 points specific to MY profile]
## RED FLAGS
- [Concerning requirements or red flags]
- [Concerning requirements, vague scope, unrealistic stack breadth, salary
omission, churn signals. If none, say so.]
## OVERALL RATING: X/10
**Worth applying?** [YES / MAYBE / NO]
[2-3 sentence honest assessment]`;
P.list_analysis = `You are an AI pre-screening jobs.
I will give you a JSON array of jobs (Title, Company).
My stack: Flutter, Python (FastAPI), PHP, Node.js, GIS, Technical Architect.
I am actively seeking Senior Engineer, Tech Lead, or Architect roles.
Reject Java, C#, C++, .NET, or pure Product Management roles.
// ── TAB: Bulk list pre-screen ─────────────────────────────────────────────
const targetRoles = P ? P.targetRoles.join(', ') : 'Senior/Lead Mobile Engineer';
const coreStack = P ? Object.values(P.skills).flat().slice(0, 18).join(', ') : '';
Pr.list_analysis = `You are pre-screening a list of jobs on my behalf.
MY PROFILE IN ONE LINE: ${P ? P.identity.primaryTitle : 'Senior Mobile Architect'} — ${P ? P.identity.positioningLine : ''}
MY CORE STACK: ${coreStack}
ROLES I WANT: ${targetRoles}
SCORING RULES:
- YES → mobile/Flutter-centric, or real-time/mobility/fintech systems at senior level.
- MAYBE → adjacent (general senior software, backend-heavy with a mobile component,
or a strong company where the stack is learnable).
- NO → primarily Java/C#/C++/.NET/Go backend, pure data science or ML, native
iOS-only (Swift) or Android-only (Kotlin) requirements, pure product management,
QA, or junior/mid-level roles.
I will give you a JSON array of jobs (Title, Company).
JOBS LIST:
${job.listData}
Respond ONLY with a raw JSON array of objects, one for each job, containing:
Respond ONLY with a raw JSON array, one object per job:
[
{ "index": number, "verdict": "YES" | "NO" | "MAYBE", "reason": "Short reason" }
{ "index": number, "verdict": "YES" | "NO" | "MAYBE", "reason": "Short reason, max 8 words" }
]
Do not wrap in markdown \`\`\`json blocks.`;
Do not wrap in markdown code fences.`;
return P[tab] || P.analysis;
return Pr[tab] || Pr.analysis;
}