All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m22s
- Add RUBRICS_V2 with improved rubrics for prompts, conception, iteration,
evaluation, alignment and cost_control dimensions
- Add "Full - 15 dimensions (V2)" template using RUBRICS_V2; V1 unchanged
- Set V2 as default template by ordering templates by id desc in getTemplates
- Point demo seed evaluations to full-15-v2
- Remove `export type { ActionResult }` from "use server" files (evaluations,
admin, share) — Turbopack treats all exports as server actions, causing a
runtime ReferenceError when the type is erased at compile time
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
664 lines
32 KiB
TypeScript
664 lines
32 KiB
TypeScript
import { PrismaClient } from "@prisma/client";
|
|
import bcrypt from "bcryptjs";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
const SUGGESTED_QUESTIONS: Record<string, string[]> = {
|
|
tools: [
|
|
"Quels outils IA utilisez-vous au quotidien ?",
|
|
"Comment les avez-vous choisis et intégrés à votre workflow personnel ?",
|
|
"Utilisez-vous des rules, skills ou agents (Cursor, etc.) pour configurer vos outils ?",
|
|
"Comment avez-vous personnalisé votre setup pour l'adapter à vos usages ?",
|
|
],
|
|
prompts: [
|
|
"Comment structurez-vous vos prompts pour des tâches complexes ?",
|
|
"Utilisez-vous des templates ou des patterns réutilisables ?",
|
|
"Comment gérez-vous les cas limites et les outputs inattendus ?",
|
|
],
|
|
context: [
|
|
"Quels fichiers ou parties du codebase incluez-vous typiquement dans le contexte (selon l'outil : @, #, fichiers ouverts...) ?",
|
|
"Comment choisissez-vous ce qui mérite d'être inclus vs laissé hors du contexte ?",
|
|
"Comment choisissez-vous le modèle (selon la tâche, la taille du contexte, le coût) ?",
|
|
"Utilisez-vous des règles pré-chargées (rules, .cursorrules, config projet) pour fournir du contexte ?",
|
|
"Avez-vous des stratégies pour limiter la taille du contexte tout en restant pertinent ?",
|
|
],
|
|
iteration: [
|
|
"Comment itérez-vous quand la première réponse ne convient pas ?",
|
|
"Décomposez-vous les tâches complexes en sous-étapes ou sous-agents ?",
|
|
"Utilisez-vous l'IA comme sparring partner pour réfléchir ?",
|
|
"Avez-vous des workflows agentiques (agents, sous-agents) ?",
|
|
],
|
|
evaluation: [
|
|
"Comment vérifiez-vous les sorties de l'IA avant de les utiliser ?",
|
|
"Avez-vous des critères explicites de qualité ?",
|
|
"Repérez-vous les générations excessives ou les infos dupliquées dans les sorties IA ?",
|
|
"Comment gérez-vous les hallucinations ou erreurs subtiles ?",
|
|
],
|
|
integration: [
|
|
"Comment l'IA est-elle discutée et partagée dans l'équipe ?",
|
|
"Y a-t-il des pratiques formalisées ou documentées ?",
|
|
"Comment les nouveaux arrivants sont-ils onboardés sur ces usages ?",
|
|
],
|
|
conception: [
|
|
"Utilisez-vous l'IA en mode plan / conception avant de coder (SDD, design, architecture) ?",
|
|
"Comment structurez-vous la phase de conception (documents, schémas, décisions) ?",
|
|
"L'IA vous aide-t-elle à explorer des options de design ou à challenger vos choix ?",
|
|
"Comment validez-vous la cohérence architecturale des propositions IA ?",
|
|
],
|
|
exploration: [
|
|
"Testez-vous régulièrement de nouveaux workflows ou techniques trouvés (web, communautés, docs) ?",
|
|
"Comment identifiez-vous ce qui améliore le contexte ou la pertinence des sorties IA ?",
|
|
"Avez-vous des exemples de techniques découvertes en ligne qui ont changé votre façon de travailler ?",
|
|
"Comment validez-vous qu'une nouvelle pratique vaut le coup avant de l'adopter ?",
|
|
],
|
|
impact: [
|
|
"Quel impact mesurable l'IA a-t-elle sur votre delivery ?",
|
|
"Comment le quantifiez-vous (temps, qualité, vélocité) ?",
|
|
"L'IA est-elle un levier stratégique pour l'équipe ?",
|
|
],
|
|
alignment: [
|
|
"Comment vous assurez-vous que le code généré respecte vos standards ?",
|
|
"Comment intégrez-vous les NFR (perf, sécurité, observabilité...) dans le contexte pour l'IA ?",
|
|
"Avez-vous des garde-fous pour l'alignement archi ?",
|
|
"Comment gérez-vous le rework quand l'IA sort du cadre ?",
|
|
],
|
|
quality_usage: [
|
|
"Utilisez-vous l'IA pour les tests ? Comment ?",
|
|
"Et pour la revue de code ou le refactoring ?",
|
|
"L'IA est-elle un levier pour améliorer la qualité globale ?",
|
|
],
|
|
learning: [
|
|
"Comment l'IA vous aide-t-elle à monter en compétence ?",
|
|
"Utilisez-vous l'IA pour comprendre des patterns ou concepts ?",
|
|
"Évitez-vous la dépendance passive (copier-coller sans comprendre) ?",
|
|
],
|
|
cost_control: [
|
|
"Suivez-vous les coûts d'usage IA (tokens, API, abonnements) ?",
|
|
"Avez-vous des budgets ou limites par équipe/projet ?",
|
|
"Comment optimisez-vous (choix de modèles, taille du contexte, batch) ?",
|
|
"Comment arbitrez-vous coût vs qualité dans vos usages ?",
|
|
],
|
|
accompagnement: [
|
|
"Y a-t-il quelque chose sur lequel vous souhaitez être aidé ou accompagné aujourd'hui ?",
|
|
"La Flash Team peut vous aider sur des sujets comme le prompt engineering, la gestion du contexte, ou la mise en place de workflows agentiques — est-ce que l'un de ces axes vous parle ?",
|
|
],
|
|
scaling: [
|
|
"Selon toi, comment pourrais-tu contribuer à mettre à l'échelle tes compétences IA et les outils que tu produis au sein de l'équipe ?",
|
|
],
|
|
};
|
|
|
|
const RUBRICS: Record<string, string> = {
|
|
tools:
|
|
"1:Usage ponctuel — utilisation occasionnelle, sans réelle stratégie ni critères de choix;2:Outil identifié — un outil principal utilisé, choix fait de manière informelle;3:Usage raisonné — comparaison de plusieurs outils, critères explicites (coût, latence, qualité), intégration dans son workflow;4:Maîtrise personnelle — outils bien configurés (rules, skills), usage fluide et efficace;5:Expertise — maîtrise des fonctionnalités avancées (agents, customisation), optimisation continue de son setup",
|
|
prompts:
|
|
"1:Vague — prompts improvisés, peu de structure, résultats aléatoires;2:Simple — prompts basiques avec instructions claires mais sans systématisation;3:Structuré — format cohérent (rôle, contexte, tâche, format attendu), testés manuellement;4:Templates — sait trouver des prompts réutilisables (ex. how to Peaksys) et s'en sert;5:Prompt engineering maîtrisé — techniques avancées (chain-of-thought, few-shot), optimisation continue, validation des outputs",
|
|
context:
|
|
"1:Peu — contexte minimal (peu ou pas de fichiers inclus), l'IA manque de code/archi pour bien répondre;2:Partiel — quelques fichiers inclus ou ouverts, parfois pertinent, parfois manquant;3:Suffisant — fichiers pertinents inclus systématiquement, choix du modèle adapté à la tâche;4:Structuré — règles pré-chargées, stratégie de sélection, choix du modèle selon taille du contexte/coût;5:Context engineering maîtrisé — règles ciblées, inclusion pertinente, gestion de la taille du contexte, choix du modèle optimisé",
|
|
iteration:
|
|
"1:One-shot — une seule tentative, pas de retry si le résultat est insuffisant;2:Quelques itérations — 2-3 essais manuels si la première réponse échoue;3:Itératif — approche systématique: retry, reformulation, décomposition en sous-tâches;4:Décomposition — tâches complexes découpées en étapes, prompts en chaîne;5:IA sparring partner — dialogue continu avec l'IA pour explorer, affiner, challenger les réponses",
|
|
evaluation:
|
|
"1:Acceptation — acceptation des sorties sans vérification significative;2:Relecture superficielle — lecture rapide, pas de critères explicites;3:Vérif fonctionnelle — tests manuels ou automatisés, vérification du comportement;4:Regard archi — évaluation de la maintenabilité, alignement, cohérence;5:Culture critique — critères de qualité partagés, revue systématique, détection des hallucinations",
|
|
integration:
|
|
"1:Isolé — usage personnel, pas de partage ou discussion en équipe;2:Discussions — échanges informels sur les usages, pas de formalisation;3:Partages — démos, retours d'expérience, bonnes pratiques partagées;4:Formalisé — pratiques documentées, onboarding, standards d'usage;5:Doctrine équipe — vision partagée, roadmap IA, adoption comme pilier de la stratégie",
|
|
conception:
|
|
"1:Code direct — pas de phase conception, passage direct au code;2:Conception informelle — réflexion mentale ou notes rapides, pas de formalisation;3:Conception assistée — IA pour esquisser des designs, SDD ou schémas;4:Mode plan structuré — IA utilisée pour explorer options, challenger, documenter les décisions;5:Conception maîtrisée — boucle conception→validation→implémentation, cohérence archi vérifiée",
|
|
exploration:
|
|
"1:Statique — usage figé, pas de recherche ni d'expérimentation;2:Occasionnel — quelques essais ponctuels, pas de démarche structurée;3:Curieux — suit des sources (web, X, communautés), teste de temps en temps;4:Actif — teste régulièrement workflows et astuces, identifie ce qui améliore contexte/pertinence;5:Explorateur — veille continue, validation systématique, adoption des pratiques qui font la différence",
|
|
impact:
|
|
"1:Aucun — pas d'impact visible sur la delivery;2:Marginal — gain de temps perçu mais non quantifié;3:Accélération — vélocité accrue, moins de tâches répétitives;4:Gain mesurable — métriques (temps, qualité, vélocité) documentées;5:Levier clair — IA comme levier stratégique, pilotage de l'adoption, ROI démontré",
|
|
alignment:
|
|
"1:Hors standards — code généré souvent non conforme, rework systématique;2:Rework lourd — modifications importantes nécessaires pour aligner;3:Cohérent — code généralement aligné, quelques ajustements;4:Aligné — prompts et garde-fous pour respecter standards et archi;5:Quasi conforme — sorties quasi conformes, validation automatisée possible",
|
|
quality_usage:
|
|
"1:Rarement — utilisation peu fréquente pour la qualité;2:Tests simples — génération de tests unitaires basiques;3:Tests utiles — tests pertinents, couverture, refacto assistée;4:Refacto guidée — IA pour identifier du code à améliorer, suggérer des refactorings;5:Levier qualité — IA intégrée dans la boucle qualité (review, dette technique, standards)",
|
|
learning:
|
|
"1:Dépendance — copier-coller sans comprendre, risque de régression;2:Apprentissage limité — utilisation pour débloquer mais compréhension superficielle;3:Compréhension — IA pour comprendre les concepts, valider sa compréhension;4:IA pour patterns — utilisation pour apprendre des patterns, architectures, bonnes pratiques;5:Accélérateur de progression — IA comme outil de montée en compétence structurée",
|
|
cost_control:
|
|
"1:Inconscient — pas de visibilité sur les coûts, usage sans limite;2:Aware — conscience des coûts, pas de suivi ni de budget;3:Suivi basique — métriques de consommation (tokens, API), pas d'alertes;4:Piloté — budgets par équipe/projet, alertes, arbitrage modèles/qualité;5:Optimisé — optimisation continue (contexte, batch, modèles), ROI coût documenté",
|
|
accompagnement:
|
|
"1:Aucun besoin exprimé — pas de demande formulée;2:Besoins vagues — envie d'aide sans direction précise;3:Besoins identifiés — sujets d'accompagnement clairs;4:Besoins priorisés — axes de progression définis;5:Plan d'action — besoins concrets et pistes identifiées, prêt à s'engager",
|
|
scaling:
|
|
"1:Pas de réflexion — aucune idée de comment contribuer au partage;2:Passif — ouvert à partager si sollicité;3:Contributeur ponctuel — partage ses pratiques de temps en temps;4:Multiplicateur — anime des retours d'expérience, documente ses outils;5:Levier d'équipe — impulse une dynamique de diffusion, produit des ressources réutilisables",
|
|
};
|
|
|
|
const RUBRICS_V2: Record<string, string> = {
|
|
...RUBRICS,
|
|
prompts:
|
|
"1:Vague — instructions floues ou incomplètes, l'IA doit deviner l'intention, résultats aléatoires;2:Clair — instructions compréhensibles avec une intention explicite, adapte le niveau de détail à la tâche;3:Précis — donne du contexte utile, précise les contraintes et le résultat attendu, ajuste selon les réponses;4:Méthodique — sait trouver et réutiliser des prompts efficaces, adapte sa formulation selon l'outil et la tâche;5:Maîtrise — spécification \"verrouillée\" : périmètre + définitions + hypothèses + priorités en cas de conflit + critères de sortie/acceptation, minimise l'interprétation et la variabilité des réponses",
|
|
conception:
|
|
"1:Code direct — pas de phase conception, passage direct au code;2:Conception informelle — réflexion mentale ou notes rapides, pas de formalisation;3:Conception assistée — IA pour esquisser des designs, SDD ou schémas;4:Mode plan structuré — IA utilisée pour explorer options, challenger, documenter les décisions;5:Conception maîtrisée — boucle conception-validation itérative, alternatives comparées et trade-offs explicites avant de coder",
|
|
iteration:
|
|
"1:One-shot — une seule tentative, pas de retry si le résultat est insuffisant;2:Quelques itérations — 2-3 essais manuels, reformulation si la première réponse échoue;3:Itératif — retry systématique avec reformulation ciblée, sait identifier ce qui ne va pas pour corriger le tir;4:Planifié — découpage en étapes avant de commencer, chaque étape traitée et validée avant la suivante;5:IA sparring partner — dialogue continu avec l'IA pour explorer, affiner, challenger les réponses",
|
|
evaluation:
|
|
"1:Acceptation — acceptation des sorties sans vérification significative;2:Relecture superficielle — lecture rapide, pas de critères explicites;3:Vérif fonctionnelle — tests manuels ou automatisés, vérification du comportement;4:Regard archi — évaluation de la maintenabilité, cohérence avec les patterns existants;5:Vigilance avancée — détection active des hallucinations et erreurs subtiles, vérification croisée avec d'autres sources, checklist personnelle de contrôle",
|
|
alignment:
|
|
"1:Hors standards — code généré souvent non conforme, rework systématique;2:Rework fréquent — modifications régulières nécessaires pour aligner le code aux standards;3:Globalement aligné — code généralement conforme, ajustements mineurs, NFR basiques (logs, erreurs) pris en compte;4:Proactif — rules ou instructions dédiées pour respecter standards, archi et NFR (perf, sécurité, observabilité);5:Intégré — NFR systématiquement couverts, garde-fous automatisés (rules, linters, templates), peu ou pas de rework",
|
|
cost_control:
|
|
"1:Inconscient — pas de visibilité sur les coûts, usage sans limite;2:Aware — conscience des coûts, consulte sa consommation de temps en temps;3:Attentif — choisit le modèle selon la tâche (léger pour le simple, puissant pour le complexe), limite le contexte inutile;4:Économe — optimise activement ses usages (taille du contexte, regroupement de requêtes, évite les générations inutiles);5:Exemplaire — pratiques de sobriété maîtrisées, sait arbitrer coût vs qualité, partage ses astuces d'optimisation",
|
|
};
|
|
|
|
// Réponses réalistes par dimension et score (justification + exemples observés)
|
|
const DEMO_RESPONSES: Record<
|
|
string,
|
|
Record<number, { justification: string; examplesObserved: string }>
|
|
> = {
|
|
tools: {
|
|
2: {
|
|
justification: "Un outil principal (Cursor), choix fait sur recommandation. Pas de personnalisation.",
|
|
examplesObserved: "« J'utilise Cursor depuis 6 mois, un collègue me l'a conseillé. »",
|
|
},
|
|
3: {
|
|
justification: "Compare Cursor et Copilot, critères de coût et latence. Intégré au workflow quotidien.",
|
|
examplesObserved: "« J'ai testé les deux, Cursor me convient mieux pour le contexte. J'ai des règles basiques. »",
|
|
},
|
|
4: {
|
|
justification: "Rules et skills configurés, usage fluide. Connaît les agents mais les utilise peu.",
|
|
examplesObserved: "« J'ai des .cursorrules par projet, des skills pour les revues. Pas encore d'agents. »",
|
|
},
|
|
},
|
|
prompts: {
|
|
2: {
|
|
justification: "Instructions claires mais pas de format réutilisable. Résultats corrects sur tâches simples.",
|
|
examplesObserved: "« Je décris ce que je veux, parfois je précise le format. Ça marche la plupart du temps. »",
|
|
},
|
|
3: {
|
|
justification: "Format rôle-contexte-tâche utilisé. Teste manuellement. Pas de bibliothèque de prompts.",
|
|
examplesObserved: "« Je commence par le rôle, puis le contexte du fichier, puis la tâche. »",
|
|
},
|
|
4: {
|
|
justification: "Templates trouvés (ex. prompts de revue), réutilisés. Pas de few-shot systématique.",
|
|
examplesObserved: "« J'ai des prompts types pour la doc et les tests que je réutilise. »",
|
|
},
|
|
},
|
|
context: {
|
|
2: {
|
|
justification: "Quelques fichiers ouverts, @ parfois. Pas de stratégie de sélection.",
|
|
examplesObserved: "« J'ouvre les fichiers concernés, j'utilise @ pour le fichier courant. »",
|
|
},
|
|
3: {
|
|
justification: "Fichiers pertinents inclus, choix du modèle selon la tâche. Pas de rules pré-chargées.",
|
|
examplesObserved: "« Je @ le module et les tests. Pour les grosses tâches je prends un modèle plus capable. »",
|
|
},
|
|
4: {
|
|
justification: "Rules dans .cursorrules, stratégie de sélection. Gère la taille du contexte.",
|
|
examplesObserved: "« On a des rules projet pour l'archi. Je limite le contexte aux 10 fichiers les plus pertinents. »",
|
|
},
|
|
},
|
|
iteration: {
|
|
2: {
|
|
justification: "2-3 essais si ça échoue. Pas de décomposition systématique.",
|
|
examplesObserved: "« Si ça ne va pas je reformule ou je coupe en deux. »",
|
|
},
|
|
3: {
|
|
justification: "Retry systématique, reformulation. Décompose les grosses tâches.",
|
|
examplesObserved: "« Je décompose les features en sous-tâches, une par prompt. »",
|
|
},
|
|
4: {
|
|
justification: "Prompts en chaîne, décomposition claire. Utilise l'IA pour challenger.",
|
|
examplesObserved: "« Pour un refacto je fais : analyse → plan → implémentation. L'IA me pose des questions. »",
|
|
},
|
|
},
|
|
evaluation: {
|
|
2: {
|
|
justification: "Relecture rapide, pas de critères explicites. Accepte si ça compile.",
|
|
examplesObserved: "« Je relis le code, je lance les tests. Si ça passe je merge. »",
|
|
},
|
|
3: {
|
|
justification: "Tests manuels ou auto avant merge. Vérifie le comportement.",
|
|
examplesObserved: "« On a des tests, je les lance. Je vérifie les cas limites à la main. »",
|
|
},
|
|
4: {
|
|
justification: "Regard sur maintenabilité et alignement. Critères implicites.",
|
|
examplesObserved: "« Je vérifie que ça respecte nos patterns. Si c'est du copier-coller je refuse. »",
|
|
},
|
|
},
|
|
integration: {
|
|
2: {
|
|
justification: "Discussions informelles en équipe. Pas de formalisation.",
|
|
examplesObserved: "« On en parle à la pause, on se montre des trucs. »",
|
|
},
|
|
3: {
|
|
justification: "Démos, partage de REX. Pas de doc ni onboarding.",
|
|
examplesObserved: "« On a fait une démo Cursor au team meeting. Les gens posent des questions. »",
|
|
},
|
|
4: {
|
|
justification: "Pratiques documentées, onboarding des nouveaux.",
|
|
examplesObserved: "« On a une page Confluence avec les bonnes pratiques. Les juniors la lisent. »",
|
|
},
|
|
},
|
|
conception: {
|
|
2: {
|
|
justification: "Notes rapides ou réflexion mentale. Pas de doc ni schéma.",
|
|
examplesObserved: "« Je réfléchis avant, je note des idées. Pas de SDD formel. »",
|
|
},
|
|
3: {
|
|
justification: "IA pour esquisser des designs. Schémas ou doc légère.",
|
|
examplesObserved: "« Je demande à l'IA de proposer une archi, je valide avant de coder. »",
|
|
},
|
|
4: {
|
|
justification: "Mode plan structuré. IA pour explorer options et documenter.",
|
|
examplesObserved: "« On fait un petit SDD, l'IA propose des variantes. On documente les décisions. »",
|
|
},
|
|
},
|
|
exploration: {
|
|
2: {
|
|
justification: "Quelques essais ponctuels. Pas de veille structurée.",
|
|
examplesObserved: "« J'ai vu un truc sur X l'autre jour, j'ai testé. Bof. »",
|
|
},
|
|
3: {
|
|
justification: "Suit web/X, teste de temps en temps. Identifie des astuces.",
|
|
examplesObserved: "« Je suis des comptes dev sur X, je teste les astuces qui ont l'air bien. »",
|
|
},
|
|
4: {
|
|
justification: "Teste régulièrement. Identifie ce qui améliore contexte et pertinence.",
|
|
examplesObserved: "« J'ai trouvé une astuce pour le contexte qui a bien amélioré mes résultats. »",
|
|
},
|
|
},
|
|
impact: {
|
|
2: {
|
|
justification: "Gain de temps perçu, non quantifié.",
|
|
examplesObserved: "« Je sens que je vais plus vite. Je n'ai pas mesuré. »",
|
|
},
|
|
3: {
|
|
justification: "Vélocité accrue, moins de répétitif. Pas de métriques.",
|
|
examplesObserved: "« On livre plus vite. Les tâches répétitives prennent moins de temps. »",
|
|
},
|
|
4: {
|
|
justification: "Métriques documentées (temps, qualité).",
|
|
examplesObserved: "« On a mesuré : -30% sur les tâches de doc, +20% de vélocité sur les features. »",
|
|
},
|
|
},
|
|
alignment: {
|
|
2: {
|
|
justification: "Rework important souvent nécessaire. NFR pas dans le contexte.",
|
|
examplesObserved: "« Le code marche mais il faut souvent adapter pour nos standards. »",
|
|
},
|
|
3: {
|
|
justification: "Généralement aligné, quelques ajustements. NFR parfois oubliés.",
|
|
examplesObserved: "« Ça respecte nos patterns la plupart du temps. Parfois je dois ajouter les logs. »",
|
|
},
|
|
4: {
|
|
justification: "Prompts et rules pour standards, archi et NFR. Garde-fous en place.",
|
|
examplesObserved: "« On a des rules pour la perf et l'observabilité. L'IA les respecte bien. »",
|
|
},
|
|
},
|
|
quality_usage: {
|
|
2: {
|
|
justification: "Tests unitaires basiques générés. Peu de review assistée.",
|
|
examplesObserved: "« Je génère des tests parfois. Pour la review je préfère faire à la main. »",
|
|
},
|
|
3: {
|
|
justification: "Tests pertinents, refacto assistée. Couverture correcte.",
|
|
examplesObserved: "« L'IA génère des tests utiles. Je l'utilise pour identifier du code à refactorer. »",
|
|
},
|
|
4: {
|
|
justification: "IA dans la boucle qualité. Review, dette technique.",
|
|
examplesObserved: "« On utilise l'IA pour la review de PR et pour prioriser la dette technique. »",
|
|
},
|
|
},
|
|
learning: {
|
|
2: {
|
|
justification: "Utilise pour débloquer. Compréhension superficielle.",
|
|
examplesObserved: "« Quand je suis bloqué je demande à l'IA. Je comprends à peu près. »",
|
|
},
|
|
3: {
|
|
justification: "IA pour valider sa compréhension. Évite le copier-coller aveugle.",
|
|
examplesObserved: "« Je demande des explications, je vérifie que j'ai compris avant d'utiliser. »",
|
|
},
|
|
4: {
|
|
justification: "Apprend patterns et archi via l'IA. Montée en compétence structurée.",
|
|
examplesObserved: "« L'IA m'aide à comprendre des patterns qu'on utilise. Je pose des questions ciblées. »",
|
|
},
|
|
},
|
|
cost_control: {
|
|
2: {
|
|
justification: "Conscience des coûts, pas de suivi.",
|
|
examplesObserved: "« Je sais que ça coûte mais je ne regarde pas. »",
|
|
},
|
|
3: {
|
|
justification: "Métriques de consommation visibles. Pas d'alertes ni budgets.",
|
|
examplesObserved: "« On voit la conso dans le dashboard. Pas de limite par équipe. »",
|
|
},
|
|
4: {
|
|
justification: "Budgets par équipe, alertes. Arbitrage modèles/qualité.",
|
|
examplesObserved: "« On a des budgets, des alertes si on dépasse. On utilise des modèles plus légers pour le trivial. »",
|
|
},
|
|
},
|
|
};
|
|
|
|
function getDemoResponse(
|
|
slug: string,
|
|
score: number
|
|
): { justification: string; examplesObserved: string } {
|
|
const dim = DEMO_RESPONSES[slug];
|
|
const exact = dim?.[score];
|
|
if (exact) return exact;
|
|
// Fallback: prendre le plus proche ou générique
|
|
const scores = dim ? Object.keys(dim).map(Number) : [];
|
|
const nearest = scores.length
|
|
? scores.reduce((a, b) => (Math.abs(a - score) < Math.abs(b - score) ? a : b))
|
|
: 3;
|
|
return (
|
|
dim?.[nearest] ?? {
|
|
justification: `Niveau ${score} observé lors de l'entretien.`,
|
|
examplesObserved: `Éléments relevés pour cette dimension.`,
|
|
}
|
|
);
|
|
}
|
|
|
|
const TEMPLATES_DATA = [
|
|
{
|
|
id: "full-15",
|
|
name: "Full - 15 dimensions",
|
|
dimensions: [
|
|
{
|
|
id: "tools",
|
|
title: "Maîtrise individuelle de l'outillage",
|
|
rubric: RUBRICS.tools,
|
|
},
|
|
{ id: "prompts", title: "Clarté des prompts", rubric: RUBRICS.prompts },
|
|
{
|
|
id: "conception",
|
|
title: "Conception & mode plan (SDD, design)",
|
|
rubric: RUBRICS.conception,
|
|
},
|
|
{
|
|
id: "context",
|
|
title: "Gestion du contexte",
|
|
rubric: RUBRICS.context,
|
|
},
|
|
{
|
|
id: "iteration",
|
|
title: "Capacité d'itération",
|
|
rubric: RUBRICS.iteration,
|
|
},
|
|
{
|
|
id: "evaluation",
|
|
title: "Évaluation critique",
|
|
rubric: RUBRICS.evaluation,
|
|
},
|
|
{
|
|
id: "exploration",
|
|
title: "Exploration & veille (workflows, astuces, pertinence)",
|
|
rubric: RUBRICS.exploration,
|
|
},
|
|
{
|
|
id: "alignment",
|
|
title: "Alignement archi & standards",
|
|
rubric: RUBRICS.alignment,
|
|
},
|
|
{
|
|
id: "quality_usage",
|
|
title: "Usage pour la qualité (tests, review)",
|
|
rubric: RUBRICS.quality_usage,
|
|
},
|
|
{
|
|
id: "learning",
|
|
title: "Montée en compétence via IA",
|
|
rubric: RUBRICS.learning,
|
|
},
|
|
{
|
|
id: "cost_control",
|
|
title: "Maîtrise des coûts",
|
|
rubric: RUBRICS.cost_control,
|
|
},
|
|
{
|
|
id: "integration",
|
|
title: "[Optionnel] Intégration dans les pratiques d'équipe",
|
|
rubric: RUBRICS.integration,
|
|
},
|
|
{
|
|
id: "impact",
|
|
title: "[Optionnel] Impact sur la delivery",
|
|
rubric: RUBRICS.impact,
|
|
},
|
|
{
|
|
id: "accompagnement",
|
|
title: "[Optionnel] Accompagnement & besoins",
|
|
rubric: RUBRICS.accompagnement,
|
|
},
|
|
{
|
|
id: "scaling",
|
|
title: "[Optionnel] Mise à l'échelle des compétences & outils",
|
|
rubric: RUBRICS.scaling,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "full-15-v2",
|
|
name: "Full - 15 dimensions (V2)",
|
|
dimensions: [
|
|
{
|
|
id: "tools",
|
|
title: "Maîtrise individuelle de l'outillage",
|
|
rubric: RUBRICS_V2.tools,
|
|
},
|
|
{ id: "prompts", title: "Clarté des prompts", rubric: RUBRICS_V2.prompts },
|
|
{
|
|
id: "conception",
|
|
title: "Conception & mode plan (SDD, design)",
|
|
rubric: RUBRICS_V2.conception,
|
|
},
|
|
{
|
|
id: "context",
|
|
title: "Gestion du contexte",
|
|
rubric: RUBRICS_V2.context,
|
|
},
|
|
{
|
|
id: "iteration",
|
|
title: "Capacité d'itération",
|
|
rubric: RUBRICS_V2.iteration,
|
|
},
|
|
{
|
|
id: "evaluation",
|
|
title: "Évaluation critique",
|
|
rubric: RUBRICS_V2.evaluation,
|
|
},
|
|
{
|
|
id: "exploration",
|
|
title: "Exploration & veille (workflows, astuces, pertinence)",
|
|
rubric: RUBRICS_V2.exploration,
|
|
},
|
|
{
|
|
id: "alignment",
|
|
title: "Alignement archi & standards",
|
|
rubric: RUBRICS_V2.alignment,
|
|
},
|
|
{
|
|
id: "quality_usage",
|
|
title: "Usage pour la qualité (tests, review)",
|
|
rubric: RUBRICS_V2.quality_usage,
|
|
},
|
|
{
|
|
id: "learning",
|
|
title: "Montée en compétence via IA",
|
|
rubric: RUBRICS_V2.learning,
|
|
},
|
|
{
|
|
id: "cost_control",
|
|
title: "Maîtrise des coûts",
|
|
rubric: RUBRICS_V2.cost_control,
|
|
},
|
|
{
|
|
id: "integration",
|
|
title: "[Optionnel] Intégration dans les pratiques d'équipe",
|
|
rubric: RUBRICS_V2.integration,
|
|
},
|
|
{
|
|
id: "impact",
|
|
title: "[Optionnel] Impact sur la delivery",
|
|
rubric: RUBRICS_V2.impact,
|
|
},
|
|
{
|
|
id: "accompagnement",
|
|
title: "[Optionnel] Accompagnement & besoins",
|
|
rubric: RUBRICS_V2.accompagnement,
|
|
},
|
|
{
|
|
id: "scaling",
|
|
title: "[Optionnel] Mise à l'échelle des compétences & outils",
|
|
rubric: RUBRICS_V2.scaling,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
async function main() {
|
|
// Sync templates & dimensions only — ne touche pas aux évaluations, users, audit logs
|
|
for (const t of TEMPLATES_DATA) {
|
|
const template = await prisma.template.upsert({
|
|
where: { id: t.id },
|
|
create: { id: t.id, name: t.name },
|
|
update: { name: t.name },
|
|
});
|
|
for (let i = 0; i < t.dimensions.length; i++) {
|
|
const d = t.dimensions[i];
|
|
const questions = SUGGESTED_QUESTIONS[d.id];
|
|
await prisma.templateDimension.upsert({
|
|
where: {
|
|
templateId_slug: { templateId: template.id, slug: d.id },
|
|
},
|
|
create: {
|
|
templateId: template.id,
|
|
slug: d.id,
|
|
orderIndex: i,
|
|
title: d.title,
|
|
rubric: d.rubric,
|
|
suggestedQuestions: questions ? JSON.stringify(questions) : null,
|
|
},
|
|
update: {
|
|
orderIndex: i,
|
|
title: d.title,
|
|
rubric: d.rubric,
|
|
suggestedQuestions: questions ? JSON.stringify(questions) : null,
|
|
},
|
|
});
|
|
}
|
|
// Supprime les dimensions retirées du template
|
|
const currentSlugs = t.dimensions.map((d) => d.id);
|
|
await prisma.templateDimension.deleteMany({
|
|
where: {
|
|
templateId: template.id,
|
|
slug: { notIn: currentSlugs },
|
|
},
|
|
});
|
|
}
|
|
|
|
// Upsert répondants (candidates) par nom : create si absent, update si existant. Ne vide pas les évaluations.
|
|
const template = await prisma.template.findUnique({
|
|
where: { id: "full-15-v2" },
|
|
});
|
|
if (!template) throw new Error("Template not found");
|
|
|
|
const adminHash = bcrypt.hashSync("admin123", 10);
|
|
const admin = await prisma.user.upsert({
|
|
where: { email: "admin@peaksys.local" },
|
|
create: {
|
|
email: "admin@peaksys.local",
|
|
name: "Admin User",
|
|
passwordHash: adminHash,
|
|
role: "admin",
|
|
},
|
|
update: { passwordHash: adminHash },
|
|
});
|
|
|
|
const dims = await prisma.templateDimension.findMany({
|
|
where: { templateId: template.id },
|
|
orderBy: { orderIndex: "asc" },
|
|
});
|
|
|
|
const repondants = [
|
|
{
|
|
name: "Alice Chen",
|
|
role: "Senior ML Engineer",
|
|
team: "Peaksys",
|
|
evaluator: "Jean Dupont",
|
|
},
|
|
{
|
|
name: "Bob Martin",
|
|
role: "Data Scientist",
|
|
team: "Peaksys",
|
|
evaluator: "Marie Curie",
|
|
},
|
|
{
|
|
name: "Carol White",
|
|
role: "AI Product Manager",
|
|
team: "Data",
|
|
evaluator: "Jean Dupont",
|
|
},
|
|
];
|
|
|
|
for (let i = 0; i < repondants.length; i++) {
|
|
const r = repondants[i];
|
|
const existing = await prisma.evaluation.findFirst({
|
|
where: {
|
|
candidateName: r.name,
|
|
evaluatorName: r.evaluator,
|
|
},
|
|
orderBy: { evaluationDate: "desc" },
|
|
});
|
|
|
|
const evalData = {
|
|
candidateName: r.name,
|
|
candidateRole: r.role,
|
|
candidateTeam: r.team,
|
|
evaluatorName: r.evaluator,
|
|
evaluatorId: admin.id,
|
|
evaluationDate: new Date(2025, 1, 15 + i),
|
|
templateId: template.id,
|
|
status: i === 0 ? "submitted" : "draft",
|
|
isPublic: true, // démo visible par tous
|
|
findings:
|
|
i === 0
|
|
? "Bonne maîtrise des outils et des prompts. Conception et exploration à renforcer. Alignement NFR correct."
|
|
: null,
|
|
recommendations:
|
|
i === 0
|
|
? "Encourager le mode plan avant implémentation. Veille sur les workflows IA."
|
|
: null,
|
|
};
|
|
|
|
let evaluation;
|
|
if (existing) {
|
|
evaluation = await prisma.evaluation.update({
|
|
where: { id: existing.id },
|
|
data: evalData,
|
|
});
|
|
await prisma.dimensionScore.deleteMany({ where: { evaluationId: existing.id } });
|
|
} else {
|
|
evaluation = await prisma.evaluation.create({
|
|
data: evalData,
|
|
});
|
|
}
|
|
|
|
for (const d of dims) {
|
|
const score = 2 + Math.floor(Math.random() * 3);
|
|
const { justification, examplesObserved } = getDemoResponse(d.slug, score);
|
|
await prisma.dimensionScore.create({
|
|
data: {
|
|
evaluationId: evaluation.id,
|
|
dimensionId: d.id,
|
|
score,
|
|
justification,
|
|
examplesObserved,
|
|
confidence: ["low", "med", "high"][Math.floor(Math.random() * 3)],
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
// Rattacher les évaluations orphelines (sans evaluatorId) à l'admin
|
|
await prisma.evaluation.updateMany({
|
|
where: { evaluatorId: null },
|
|
data: { evaluatorId: admin.id },
|
|
});
|
|
|
|
console.log("Seed complete: templates synced, répondants upserted (évaluations non vidées)");
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(() => prisma.$disconnect());
|