Files
iag-dev-evaluator/prisma/seed.ts

571 lines
27 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",
};
// 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,
},
],
},
];
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 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());