import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); const SUGGESTED_QUESTIONS: Record = { 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 ?", ], }; const RUBRICS: Record = { 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é", }; // Réponses réalistes par dimension et score (justification + exemples observés) const DEMO_RESPONSES: Record< string, Record > = { 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 - 13 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, }, ], }, ]; 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" }, }); if (!template) throw new Error("Template not found"); const bcrypt = require("bcryptjs"); const adminHash = bcrypt.hashSync("admin123", 10); const admin = await prisma.user.upsert({ where: { email: "admin@cars-front.local" }, create: { email: "admin@cars-front.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: "Cars Front", evaluator: "Jean Dupont", }, { name: "Bob Martin", role: "Data Scientist", team: "Cars Front", evaluator: "Marie Curie", }, { name: "Carol White", role: "AI Product Manager", team: "Cars 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", 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());