Dev · LLM guide
Rendu lisible de /api/llm-guide (source Markdown servie aux agents).
# CV Dynamique -- Guide LLM
> Document auto-genere. Point d'entree pour les agents LLM : decrit tous les
> endpoints publics et les parametres URL pour personnaliser le CV.
## Points d'entree
| Endpoint | Methode | Description |
| -------- | ------- | ----------- |
| `/api/llm-guide` | GET | Ce guide (Markdown). Point d'entree recommande pour tout agent LLM. |
| `/api/profile` | GET | Donnees structurees JSON du profil + catalogue techno complet. |
| `/api/openapi.yaml` | GET | Specification OpenAPI 3.1 de l'API `/api/profile`. |
| `/{lang}` | GET | CV HTML complet. FR: `/fr`, EN: `/en`. |
| `/{lang}/short` | GET | CV HTML court (1 page). |
| `/` | GET | Redirige vers `/{lang}` selon la locale du navigateur. |
Base URL production : `https://www.elzinko.fr`
---
## API Profile (`/api/profile`)
Endpoint JSON en lecture seule, sans authentification (CORS ouvert).
Retourne le snapshot complet du profil : identite, contact, experiences,
etudes, projets, competences, et le catalogue canonique des technologies
(`techCatalog` avec ids + noms + liens).
```
GET /api/profile?lang=fr|en
```
| Parametre | Requis | Description |
| --------- | ------ | ----------- |
| `lang` | non | `fr` (defaut) ou `en`. |
Toutes les sections sont toujours presentes : `profile`, `about`, `domains`,
`jobs`, `studies`, `projects`, `hobbies`, `learnings`, `skills`,
`techCatalog`.
### Specification OpenAPI
La spec formelle de cette API est disponible a `/api/openapi.yaml`
(OpenAPI 3.1, YAML). Elle decrit le schema complet de la reponse JSON, les
codes d'erreur et les types de chaque champ.
### Recuperer les ids du catalogue techno
Le parametre `requirement` (voir plus bas) accepte `@id` pour referencer une
techno precise. Les ids sont disponibles dans `techCatalog.skills` et
`techCatalog.domains[].competencies` de la reponse `/api/profile`.
> Le matching texte (mots-cles separes par des virgules) fonctionne aussi
> sans avoir a charger le catalogue. Le passage par id n'est utile que pour
> de la desambiguisation (ex. distinguer `Vue` de `Vue.js`).
---
## CV HTML -- Formats disponibles
| Format | URL | Description |
| ------ | --- | ----------- |
| CV complet | `/{lang}` | FR: `/fr`, EN: `/en` -- toutes les sections |
| CV court | `/{lang}/short` | 1 page -- profil, domaines, experience recente |
## CV HTML -- Parametres de personnalisation
```
GET /{lang}?company=<nom>&requirement=<Label:kw1,kw2>[&...]
```
| Parametre | Requis | Description |
| --------- | ------ | ----------- |
| `company` | **oui** | Nom de l'entreprise |
| `title` | non | Intitule du poste (FR et EN si seul titre fourni) |
| `title_fr` | non | Titre affiche cote francais |
| `title_en` | non | Titre affiche cote anglais |
| `subtitle` | non | Sous-titre / role affiche sous le nom (FR et EN si seul subtitle fourni) |
| `subtitle_fr` | non | Sous-titre affiche cote francais (ex. "Chef de Projet Java Full Stack") |
| `subtitle_en` | non | Sous-titre affiche cote anglais (ex. "Java Full Stack Project Manager") |
| `requirement` | **oui** (1+) | Repetable. Format : `Label:keyword1,keyword2` |
| `req` | alias | Alias court pour `requirement` |
| `reqY` | non | Annees d'experience affichees pour le i-eme requirement (remplace le calcul auto) |
| `edu` | non | `1` ou `true` → affiche la pastille de niveau de formation (« Bac+5 » FR / « Master's-level » EN). Masquee par defaut. |
| `contract` | non | `cdi` ou `freelance` -- adapte textes profil/domaines, masque Malt en CDI |
| `detail` | non | Niveau de detail des experiences : `full` (defaut), `summary` (accroche seule, sans les details), `minimal` (aucune description). Pilote l'ecran ET le PDF. |
| `photo` | non | Affiche la photo de profil (avatar a gauche du nom). `1` pour afficher (masquee par defaut). |
| `age` | non | Affiche l'age sous le role (calcule depuis la date de naissance). `0` pour masquer (affiche par defaut). |
| `job` | non | Repetable. Slug d'une mission a mettre en avant sur le CV court. **L'ordre des `job` = ordre d'affichage** du bloc "mises en avant" (voir liste ci-dessous) |
| `workAddress` | non | Adresse complete du lieu de travail. Active l'itineraire Google Maps gare -> bureau sur le pictogramme localisation. |
| `clientAddress` | alias | Alias court de `workAddress`. |
| `commuteLabel` | non | Libelle court affiche pres du lieu (ex. "~45 min"). Ignore sans `workAddress`. |
| `commuteMinutes` | non | Minutes de trajet (numerique). Si fourni sans `commuteLabel`, genere "~N min". |
| `spec` | non | JSON base64url (remplace les autres params d'offre si present) |
| `id` | non | Identifiant interne optionnel |
### Format d'une exigence (`requirement`)
Chaque valeur suit le pattern `Label:keyword1,keyword2` :
- **Label** (avant `:`) : affiche dans le tableau d'adequation.
- **Keywords** (apres `:`, separes par des virgules) : matches contre le catalogue du CV.
- **Reference par id** : prefixer par `@` un id du catalogue techno.
Ids disponibles via `/api/profile` -> `techCatalog`.
Exemple : `requirement=Vue.js:@an8YW0VVTf2JuZZZo1W0pw`
Les mots-cles texte fonctionnent aussi (matching insensible a la
ponctuation) et suffisent dans la plupart des cas.
### Calcul automatique des annees d'experience
Pour chaque requirement, le systeme cherche les missions dont les frameworks,
role, description ou puces contiennent un des keywords (matching insensible
a la casse et a la ponctuation : "vuejs" matche "Vue.js").
Les annees affichees = somme des durees des missions matchees (deduplication
par client). Pour maximiser la precision, inclure tous les mots-cles
pertinents (ex : pour Frontend, inclure react,angular,vuejs,ionic,gwt,jsf,
javascript,typescript plutot que juste react).
Si le calcul auto ne convient pas, utiliser `reqY` pour forcer une valeur.
### Type de contrat
- `contract=cdi` : textes profil et domaines adaptes pour un poste permanent, lien Malt masque.
- `contract=freelance` : textes freelance (comportement par defaut).
### Presentation du CV (photo, age, niveau de detail)
Ces parametres controlent la mise en forme, independamment de l'offre. Ils
s'appliquent a l'ecran **et** au PDF imprime (le rendu PDF suit le choix).
- `detail` : densite des experiences.
- `full` (defaut) : accroche + description detaillee + puces.
- `summary` : accroche seule -- utile pour un CV synthetique tenant sur moins de pages.
- `minimal` : titre / poste / dates / technos uniquement, sans aucune description.
- `photo=1` : affiche la photo de profil (masquee par defaut). A eviter pour les
candidatures passant par un ATS (parsing), a privilegier pour un envoi direct.
- `age=0` : masque l'age (affiche par defaut sous le role).
### Ordre des requirements
**L'ordre des parametres `requirement` dans l'URL determine l'ordre d'affichage
dans la section "Adequation poste".** Le LLM doit ordonner les requirements
par pertinence vis-a-vis de l'offre : placer les competences les plus
importantes ou les plus demandees en premier. En mode short (CV court),
seules les **3 premieres** sont affichees.
Conseil : placer en premier les competences coeur de l'offre (ex. Java pour
un poste Java), puis les competences secondaires (SQL, Docker, etc.).
### Sous-titre du CV
Par defaut, le sous-titre affiche "Developpeur fullstack Senior" (FR) /
"Senior Fullstack Developer" (EN). Pour l'adapter a l'offre, utiliser
`subtitle_fr` et/ou `subtitle_en` (ou `subtitle` pour les deux langues).
Exemple : `subtitle_fr=Chef+de+Projet+Java+Full+Stack&subtitle_en=Java+Full+Stack+Project+Manager`
## Vignettes adequation poste
- 1 vignette education **optionnelle** (opt-in via `edu=1` ou `showEducation: true` dans le spec JSON) : "Bac+5" (FR) / "Master's-level" (EN).
- Max **3** vignettes technologiques en mode short.
- Pas de limite en mode full (CV complet).
- En mode short, chaque vignette indique le nombre de clients (missions).
- En mode full, la liste detaillee des clients est affichee sous chaque vignette.
## Slugs de missions (parametre `job`)
> 24 missions disponibles. Utiliser le slug dans le parametre
> `job` (repetable) pour mettre en avant une mission sur le CV court.
`iut-senart-fontainebleau`, `cours-particuliers-maths-physique`, `solopreneur`, `jpb-systeme`, `matiere-web`, `blablacar`, `smartch`, `sncf-reseaux-dgex-solutions`, `leboncoin`, `celsius-energy`, `relevanc`, `ecocea`, `edelia`, `jcdecaux`, `lotsys-filiale-fdj`, `mediametrie`, `thales-communications`, `mediapost`, `sfr`, `dgfip`, `la-compagnie-1818`, `bnp-paribas`, `renault-sa`, `cfa-sup-2000`
> Details complets de chaque mission (client, role, dates, frameworks) :
> `/api/profile?lang=fr` -> tableau `jobs`.
### Mise en avant de missions (parametre `job`)
Sur le **CV court** (`/{lang}/short`), les missions listees via `job` sont affichees en detail
(description, puces, frameworks) **dans l'ordre fourni** -- pas forcement chronologique. Toutes les
autres missions visibles sont regroupees sous une rubrique **"Autres experiences"** compressee
(client, role, periode).
#### Adapter la mise en avant a l'offre (instruction agent)
Comme pour l'ordre des `requirement`, **c'est a l'agent de choisir QUELLES missions mettre en avant
et DANS QUEL ORDRE, en fonction de l'offre a laquelle il repond.** Le CV ne reordonne rien tout seul :
il respecte strictement l'ordre des `job` recus.
1. Lire l'offre : intitule, missions, competences cles, secteur, seniorite.
2. Selectionner les 2 a 4 missions les plus probantes pour CETTE offre (slugs dans
`jobs[].slug` de `/api/profile`, ou liste ci-dessus).
3. Les passer en parametres `job` **par pertinence decroissante** : la mission la plus convaincante
en premier. **Cet ordre = ordre d'affichage** du bloc "mises en avant".
4. Ne rien faire pour le reste : les missions non listees basculent automatiquement sous
"Autres experiences".
Exemples d'ordre selon le poste vise (memes slugs, ordre different) :
| Offre visee | Ordre `job` suggere |
| ----------- | ------------------- |
| Engineering Manager / management | `job=matiere-web` (direction d'agence, encadrement) en tete |
| Backend / Java | une mission backend en tete (`job=jpb-systeme`, `job=sncf-reseaux-dgex-solutions`...) |
| Freelance React / frontend | une mission front en tete (`job=blablacar`, `job=smartch`...) |
Regles complementaires :
- Identifiant accepte : le `slug` (`jobs[].slug`), le slug prefixe `mission-...`, ou le nom brut du client.
- `highlightedJobs` dans le `spec` suit la meme semantique d'ordre ; les `job` de l'URL priment.
- Sans aucun `job` (ni `highlightedJobs`), le CV court garde son comportement par defaut
(missions recentes en chronologique).
Exemple (poste de management -> Matiere Web en tete, ordre non chronologique) :
```
/fr/short?company=Acme&title=Engineering+Manager&requirement=Management:management,leadership&job=matiere-web&job=jpb-systeme&job=blablacar
```
## Exemples d'URLs
### CV adapte poste CDI Java/Cloud
```
/fr?company=Entreprise&title=Developpeur+Java+Senior&subtitle_fr=Developpeur+Java+Senior&requirement=Java:java,spring&requirement=Cloud:aws,docker&contract=cdi
```
### CV adapte mission freelance React
```
/fr?company=Client&title=Dev+Frontend&requirement=React:react,nextjs&requirement=TypeScript:typescript&contract=freelance
```
### CV synthetique avec photo (envoi direct)
```
/fr?company=Entreprise&requirement=Java:java,spring&detail=summary&photo=1
```
### CV court avec parametres
```
/fr/short?company=Entreprise&requirement=Java:java&requirement=SQL:sql&contract=cdi
```
### Reference par id catalogue
```
/fr?company=Padoa&title=Dev&requirement=Vue.js:%40an8YW0VVTf2JuZZZo1W0pw
```
## Format compact base64
Pour les offres complexes, encoder le JSON en base64url et passer via `spec` :
```
GET /{lang}?spec=<base64url>
```
Schema JSON decode :
```json
{
"company": "string (requis)",
"title": "string | { fr: string, en: string } (requis)",
"requirements": [{ "label": "string", "keywords": ["string"], "experienceYearsOverride?": "number" }],
"contract": "cdi | freelance (optionnel)",
"workAddress": "string (optionnel) -- itineraire Google Maps gare -> bureau",
"commuteLabel": "string (optionnel) -- libelle court affiche pres du lieu",
"commuteMinutes": "number (optionnel) -- si pas de commuteLabel, genere '~N min'",
"highlightedJobs": ["slug1", "slug2"],
"showEducation": "boolean (optionnel) -- affiche la pastille « Bac+5 / Master's-level »",
"id": "string (optionnel)",
"url": "string (optionnel)"
}
```
> `highlightedJobs` suit la **meme semantique d'ordre** que le parametre `job` repete :
> l'ordre du tableau = ordre d'affichage des missions mises en avant sur le CV court, le
> reste etant regroupe sous "Autres experiences". Si des parametres `job` sont aussi
> presents dans l'URL, ils ont la priorite sur `highlightedJobs` du `spec`.
> Aliases snake_case acceptes dans le spec JSON : `experience_years_override`,
> `highlighted_jobs`, `commute_minutes`, `show_education`.
## Prompt rapide (generation d'URL de CV personnalise)
> Construis une URL GET vers `/{fr|en}` avec `company`, `title` (optionnel),
> et pour chaque competence un parametre `requirement=Label:keyword1,keyword2`
> (repeter `requirement`). Les mots-cles texte suffisent dans la plupart des
> cas (matching insensible a la ponctuation). Pour la desambiguisation, fetch
> `/api/profile` pour obtenir les ids et utiliser `requirement=Label:@id`.
> Ajoute `contract=cdi` pour un poste permanent.
## Recapitulatif pour agents LLM
1. **Decouverte** : commence par `/api/llm-guide` (ce document).
2. **Donnees structurees** : utilise `/api/profile?lang=fr` pour lire le profil complet en JSON (incluant le catalogue techno avec ids).
3. **Spec formelle** : consulte `/api/openapi.yaml` pour le schema de la reponse JSON.
4. **Personnalisation du CV** : construis une URL `/{lang}?company=...&requirement=...` en suivant les sections ci-dessus.