TalentVision — Documentation
Documentation technique de la plateforme Sodexo Ma Carrière,
déployée sur sodexo.coconutservices.fr.
Gestion des talents, compétences, évolutions de carrière,
et 3 bots IA connectés à Langflow.
Backend : Cloudflare Pages Functions (Workers)
Base de données : Cloudflare D1 (SQLite)
IA / Bots : Langflow sur
flow.coconutservices.fr
Architecture
Arborescence du projet
Base de données — Cloudflare D1
La base sodexo-talent utilise Cloudflare D1 (SQLite distribué).
Le schéma est défini dans schema.sql et les données initiales dans seed.sql.
Tables
| Table | Description | Clé primaire | FK |
|---|---|---|---|
employees | Collaborateurs (infos, scores, badges) | id TEXT | — |
skills | Compétences par employé (%) | id INTEGER | employee_id |
gaps | Gaps de compétences identifiés | id INTEGER | employee_id |
career_path | Parcours carrière (timeline) | id INTEGER | employee_id |
turnover_factors | Facteurs de risque turnover | id INTEGER | employee_id |
evaluations | Évaluations (manager, auto-éval) | id INTEGER | employee_id |
notifications | Notifications globales | id INTEGER | — |
context_signals | Signaux contextuels (RH/manager) | id INTEGER | employee_id |
stats | KPI globaux (clé/valeur) | key TEXT | — |
Table employees — Colonnes principales
| Colonne | Type | Description |
|---|---|---|
id | TEXT PK | Identifiant unique (ex: alexandre-esteves) |
first_name, last_name | TEXT | Prénom et nom |
job_title | TEXT | Poste actuel |
affiliate | TEXT | Filiale Sodexo |
site | TEXT | Site géographique |
evolution_score | INTEGER | Score d'évolution (0-100) |
risk_level | TEXT | low / medium / high |
turnover_risk_pct | INTEGER | Risque de turnover (%) |
engagement_pct | INTEGER | Engagement (%) |
badge_label | TEXT | Badge (Haut Potentiel, etc.) |
profile_page | TEXT | URL de la page profil |
Déploiement de la base
# Créer la base D1
npx wrangler d1 create sodexo-talent
# Appliquer le schéma
npx wrangler d1 execute sodexo-talent --file=schema.sql
# Insérer les données initiales
npx wrangler d1 execute sodexo-talent --file=seed.sql
API — Employees
GET /api/employees
Liste paginable et filtrable de tous les collaborateurs.
| Paramètre | Type | Description |
|---|---|---|
search | string | Recherche nom/prénom/poste (LIKE) |
affiliate | string | Filtre par filiale |
site | string | Filtre par site |
department | string | Filtre par département |
risk | string | Filtre par niveau de risque |
score_min | integer | Score d'évolution minimum |
score_max | integer | Score d'évolution maximum |
sort | string | Tri : name, score, risk, tenure |
Réponse :
{
"employees": [
{
"id": "alexandre-esteves",
"first_name": "Alexandre",
"last_name": "Esteves",
"job_title": "Chef de projet digital",
"evolution_score": 82,
"risk_level": "low",
"badge_label": "Haut Potentiel",
...
}
]
}
API — Employee Detail
GET /api/employees/:id
Profil complet d'un collaborateur avec toutes ses données associées.
Réponse :
{
"employee": { ... },
"skills": [
{ "name": "Leadership", "percentage": 88, "category": "soft" }
],
"gaps": [
{ "competence": "Anglais C1", "gap_level": "moyen", "training_recommendation": "..." }
],
"career_path": [
{ "title": "...", "company": "Sodexo", "date_range": "2022-...", "status": "current" }
],
"turnover_factors": [ ... ],
"evaluations": [ ... ],
"context_signals": [ ... ]
}
API — Stats
GET /api/stats
KPI globaux du dashboard.
{
"stats": [
{ "key": "total_employees", "value": "847", "change_label": "+12", "change_direction": "up" },
{ "key": "avg_evolution_score", "value": "72", ... },
{ "key": "turnover_risk", "value": "8.2%", ... },
{ "key": "high_potential", "value": "23", ... }
]
}
API — Notifications
GET /api/notifications
Liste des notifications, triées par date décroissante.
{
"notifications": [
{
"id": 1,
"title": "Nouvelle évaluation",
"message": "Antoine Moreau a complété son auto-évaluation",
"timestamp": "2025-01-15T10:30:00Z",
"is_read": 0,
"icon": "eval",
"target_page": "/BackOffice/antoine-moreau.html"
}
]
}
POST /api/notifications/read
Marque toutes les notifications comme lues. Body vide.
// Response
{ "success": true }
API — Search
GET /api/search?q=...
Proxy vers l'API Brave Search. Utilisé pour la recherche contextuelle.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
q | string | oui | Terme de recherche |
BRAVE_SEARCH_API_KEY configurée dans Cloudflare.
Langflow — ChatbotFAQ
POST /api/chat
Proxy vers le flow Langflow ChatbotFAQ. Répond aux questions RH des collaborateurs.
| Champ body | Type | Requis | Description |
|---|---|---|---|
message | string | oui | Message de l'utilisateur |
conversationId | string | non | ID session pour continuité |
// Request
{ "message": "Combien de jours de congés me reste-t-il ?" }
// Response
{ "response": "Selon votre solde actuel, il vous reste..." }
https://flow.coconutservices.frRoute interne :
/api/v1/run/{FLOW_ID}Variable :
LANGFLOW_CHAT_FLOW_ID (default: chatbot-faq)
Langflow — Extraction CV
POST /api/extract-cv
Upload de CV (PDF/DOCX) pour extraction automatique des compétences via Langflow.
| Champ | Type | Description |
|---|---|---|
files | FormData | Un ou plusieurs fichiers CV |
// Response
{
"results": [
{ "file": "cv-moreau.pdf", "result": "Compétences extraites : ..." }
]
}
tweaks.file_content du payload Langflow.
Variable : LANGFLOW_CV_FLOW_ID (default: extraction-cv)
Langflow — Matching Évolution
POST /api/matching
Déclenche le pipeline de matching candidat/poste via Langflow.
| Champ body | Type | Description |
|---|---|---|
employeeId | string | ID de l'employé (optionnel, sinon tous) |
action | string | start = pipeline global |
// Request
{ "action": "start" }
// Response
{ "status": "running", "result": "Pipeline démarré pour 847 collaborateurs..." }
Mode DEMO / PROD / DOC
Un toggle 3 boutons est présent dans la topbar de toutes les pages.
Le mode est persisté via localStorage('sodexo_mode').
| Mode | Comportement | Couleur |
|---|---|---|
| DEMO | Données hardcodées en HTML (aucun appel réseau) | Orange |
| PROD | Données chargées depuis D1 via fetch(/api/...) | Vert |
| DOC | Redirige vers /docs/ (cette page) | Bleu Sodexo |
JavaScript (/shared/mode.js)
var SODEXO_MODE = localStorage.getItem('sodexo_mode') || 'demo';
function setMode(mode) {
SODEXO_MODE = mode;
localStorage.setItem('sodexo_mode', mode);
// Met à jour les boutons + appelle onModeChange() si défini
}
function apiFetch(endpoint) {
return fetch('/api' + endpoint).then(function(r) { return r.json(); });
}
function apiPost(endpoint, data) {
return fetch('/api' + endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}).then(function(r) { return r.json(); });
}
onModeChange(mode) qui sera appelée automatiquement quand l'utilisateur change de mode. En mode PROD, cette fonction déclenche les appels API pour remplacer les données hardcodées.
Design Tokens
Variables CSS définies dans /shared/dashboard.css :
| Variable | Valeur | Usage |
|---|---|---|
--sodexo-primary | #283897 | Bleu Sodexo principal |
--sodexo-primary-light | #E7E9F7 | Fond hover / sélection |
--sodexo-primary-dark | #2A295C | Titres, texte fort |
--sodexo-accent | #DA2020 | Rouge alerte / badge |
--sodexo-green | #2ecc71 | Succès, mode PROD |
--sodexo-orange | #f39c12 | Warning, mode DEMO |
--sodexo-bg | #f4f5f7 | Fond de page |
--sodexo-border | #e8e8e8 | Bordures, séparateurs |
Vues par rôle
Les pages profils disposent de 3 vues avec des informations différentes selon le rôle :
| Rôle | Classe CSS | Visibilité |
|---|---|---|
| RH | .view-rh | Tout : scores, signaux, turnover, gaps, évaluations |
| Manager | .view-manager | Compétences, évaluations, gaps (sans signaux sensibles) |
| Collaborateur | .view-collab | Vue personnelle : compétences propres, carrière, formations |
Le toggle de rôle est dans la topbar des pages profils. Il ajoute la classe role-{role}
sur <body> et le CSS masque les sections non autorisées.
Variables d'environnement
| Variable | Requis | Description | Default |
|---|---|---|---|
DB | oui | Binding D1 (auto via wrangler.toml) | — |
LANGFLOW_CHAT_FLOW_ID | non | Flow ID pour ChatbotFAQ | chatbot-faq |
LANGFLOW_CV_FLOW_ID | non | Flow ID pour ExtractionCV | extraction-cv |
LANGFLOW_MATCHING_FLOW_ID | non | Flow ID pour Matching | matching-evolution |
BRAVE_SEARCH_API_KEY | oui* | Clé API Brave Search | — |
wrangler.toml.
Déploiement
wrangler.toml
name = "sodexo"
compatibility_date = "2024-01-01"
pages_build_output_dir = "."
[[d1_databases]]
binding = "DB"
database_name = "sodexo-talent"
database_id = "<ID>"
Commandes
# Déploiement via GitHub (auto)
git add . && git commit -m "deploy" && git push
# Ou déploiement direct
npx wrangler pages deploy .
# Migration DB
npx wrangler d1 execute sodexo-talent --file=schema.sql
npx wrangler d1 execute sodexo-talent --file=seed.sql
main déclenche un build et un déploiement.
Les Pages Functions dans /functions/ sont détectées automatiquement.
TalentVision Documentation — Sodexo Ma Carrière — Généré par Claude Code