diff --git a/package.json b/package.json index 477d3aa..08faf0a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "build": "next build", "dev": "next dev", "lint": "next lint", - "start": "next start" + "start": "next start", + "generate-test-data": "tsx scripts/generate-test-data.ts" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^7.0.0", @@ -74,6 +75,7 @@ "postcss": "^8.5", "tailwindcss": "^4.1.9", "tw-animate-css": "1.3.3", + "tsx": "^4.19.2", "typescript": "^5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5de36a..977c2f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,6 +195,9 @@ importers: tailwindcss: specifier: ^4.1.9 version: 4.1.12 + tsx: + specifier: ^4.19.2 + version: 4.20.4 tw-animate-css: specifier: 1.3.3 version: 1.3.3 @@ -218,6 +221,162 @@ packages: '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + '@esbuild/aix-ppc64@0.25.9': + resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.9': + resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.9': + resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.9': + resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.9': + resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.9': + resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.9': + resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.9': + resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.9': + resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.9': + resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.9': + resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.9': + resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.9': + resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.9': + resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.9': + resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.9': + resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.9': + resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.9': + resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.9': + resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.9': + resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.9': + resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.9': + resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.9': + resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.9': + resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.9': + resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.9': + resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} @@ -1370,6 +1529,11 @@ packages: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + esbuild@0.25.9: + resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1384,6 +1548,11 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + geist@1.4.2: resolution: {integrity: sha512-OQUga/KUc8ueijck6EbtT07L4tZ5+TZgjw8PyWfxo16sL5FWk7gNViPNU8hgCFjy6bJi9yuTP+CRpywzaGN8zw==} peerDependencies: @@ -1393,6 +1562,9 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -1703,6 +1875,9 @@ packages: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} @@ -1774,6 +1949,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.4: + resolution: {integrity: sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==} + engines: {node: '>=18.0.0'} + hasBin: true + tw-animate-css@1.3.3: resolution: {integrity: sha512-tXE2TRWrskc4TU3RDd7T8n8Np/wCfoeH9gz22c7PzYqNPQ9FBGFbWWzwL0JyHcFp+jHozmF76tbHfPAx22ua2Q==} @@ -1849,6 +2029,84 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.25.9': + optional: true + + '@esbuild/android-arm64@0.25.9': + optional: true + + '@esbuild/android-arm@0.25.9': + optional: true + + '@esbuild/android-x64@0.25.9': + optional: true + + '@esbuild/darwin-arm64@0.25.9': + optional: true + + '@esbuild/darwin-x64@0.25.9': + optional: true + + '@esbuild/freebsd-arm64@0.25.9': + optional: true + + '@esbuild/freebsd-x64@0.25.9': + optional: true + + '@esbuild/linux-arm64@0.25.9': + optional: true + + '@esbuild/linux-arm@0.25.9': + optional: true + + '@esbuild/linux-ia32@0.25.9': + optional: true + + '@esbuild/linux-loong64@0.25.9': + optional: true + + '@esbuild/linux-mips64el@0.25.9': + optional: true + + '@esbuild/linux-ppc64@0.25.9': + optional: true + + '@esbuild/linux-riscv64@0.25.9': + optional: true + + '@esbuild/linux-s390x@0.25.9': + optional: true + + '@esbuild/linux-x64@0.25.9': + optional: true + + '@esbuild/netbsd-arm64@0.25.9': + optional: true + + '@esbuild/netbsd-x64@0.25.9': + optional: true + + '@esbuild/openbsd-arm64@0.25.9': + optional: true + + '@esbuild/openbsd-x64@0.25.9': + optional: true + + '@esbuild/openharmony-arm64@0.25.9': + optional: true + + '@esbuild/sunos-x64@0.25.9': + optional: true + + '@esbuild/win32-arm64@0.25.9': + optional: true + + '@esbuild/win32-ia32@0.25.9': + optional: true + + '@esbuild/win32-x64@0.25.9': + optional: true + '@floating-ui/core@1.7.3': dependencies: '@floating-ui/utils': 0.2.10 @@ -2969,6 +3227,35 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.2 + esbuild@0.25.9: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.9 + '@esbuild/android-arm': 0.25.9 + '@esbuild/android-arm64': 0.25.9 + '@esbuild/android-x64': 0.25.9 + '@esbuild/darwin-arm64': 0.25.9 + '@esbuild/darwin-x64': 0.25.9 + '@esbuild/freebsd-arm64': 0.25.9 + '@esbuild/freebsd-x64': 0.25.9 + '@esbuild/linux-arm': 0.25.9 + '@esbuild/linux-arm64': 0.25.9 + '@esbuild/linux-ia32': 0.25.9 + '@esbuild/linux-loong64': 0.25.9 + '@esbuild/linux-mips64el': 0.25.9 + '@esbuild/linux-ppc64': 0.25.9 + '@esbuild/linux-riscv64': 0.25.9 + '@esbuild/linux-s390x': 0.25.9 + '@esbuild/linux-x64': 0.25.9 + '@esbuild/netbsd-arm64': 0.25.9 + '@esbuild/netbsd-x64': 0.25.9 + '@esbuild/openbsd-arm64': 0.25.9 + '@esbuild/openbsd-x64': 0.25.9 + '@esbuild/openharmony-arm64': 0.25.9 + '@esbuild/sunos-x64': 0.25.9 + '@esbuild/win32-arm64': 0.25.9 + '@esbuild/win32-ia32': 0.25.9 + '@esbuild/win32-x64': 0.25.9 + escalade@3.2.0: {} eventemitter3@4.0.7: {} @@ -2977,12 +3264,19 @@ snapshots: fraction.js@4.3.7: {} + fsevents@2.3.3: + optional: true + geist@1.4.2(next@15.2.4(react-dom@19.1.1(react@19.1.1))(react@19.1.1)): dependencies: next: 15.2.4(react-dom@19.1.1(react@19.1.1))(react@19.1.1) get-nonce@1.0.1: {} + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + graceful-fs@4.2.11: {} input-otp@1.4.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1): @@ -3259,6 +3553,8 @@ snapshots: tiny-invariant: 1.3.3 victory-vendor: 36.9.2 + resolve-pkg-maps@1.0.0: {} + scheduler@0.26.0: {} semver@7.7.2: @@ -3335,6 +3631,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.4: + dependencies: + esbuild: 0.25.9 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + tw-animate-css@1.3.3: {} typescript@5.9.2: {} diff --git a/scripts/generate-test-data.ts b/scripts/generate-test-data.ts new file mode 100644 index 0000000..a233f6d --- /dev/null +++ b/scripts/generate-test-data.ts @@ -0,0 +1,271 @@ +#!/usr/bin/env tsx +import { getPool, closePool } from "../services/database"; +import { SkillLevel } from "../lib/types"; +import * as fs from "fs"; +import * as path from "path"; + +// Données de test +const TEST_DIRECTION = "TestData"; + +const TEST_TEAMS = [ + { id: "test-frontend", name: "Test Frontend Team" }, + { id: "test-backend", name: "Test Backend Team" }, + { id: "test-fullstack", name: "Test Full Stack Team" }, + { id: "test-mobile", name: "Test Mobile Team" }, + { id: "test-devops", name: "Test DevOps Team" }, +]; + +const FIRST_NAMES = [ + "Alice", + "Bob", + "Claire", + "David", + "Emma", + "François", + "Julie", + "Marc", + "Sophie", + "Thomas", + "Amélie", + "Nicolas", + "Camille", + "Pierre", + "Léa", + "Julien", + "Marie", + "Antoine", + "Sarah", + "Maxime", +]; + +const LAST_NAMES = [ + "Martin", + "Bernard", + "Dubois", + "Thomas", + "Robert", + "Petit", + "Durand", + "Leroy", + "Moreau", + "Simon", + "Laurent", + "Lefebvre", + "Michel", + "Garcia", + "David", + "Bertrand", + "Roux", + "Vincent", + "Fournier", + "Morel", +]; + +const SKILL_LEVELS: SkillLevel[] = [ + "never", + "not-autonomous", + "autonomous", + "expert", +]; + +interface SkillData { + id: string; + name: string; + description: string; + icon?: string; + category: string; +} + +async function loadAllSkills(): Promise { + const skillsDir = path.join(__dirname, "../data/skills"); + const files = fs + .readdirSync(skillsDir) + .filter((file) => file.endsWith(".json")); + + const allSkills: SkillData[] = []; + + for (const file of files) { + const filePath = path.join(skillsDir, file); + const content = JSON.parse(fs.readFileSync(filePath, "utf-8")); + + content.skills.forEach((skill: any) => { + allSkills.push({ + ...skill, + category: content.category, + }); + }); + } + + return allSkills; +} + +function getRandomElement(array: T[]): T { + return array[Math.floor(Math.random() * array.length)]; +} + +function getRandomElements(array: T[], count: number): T[] { + const shuffled = [...array].sort(() => 0.5 - Math.random()); + return shuffled.slice(0, count); +} + +function generateRandomLevel(): SkillLevel { + const weights = [0.3, 0.4, 0.25, 0.05]; // never, not-autonomous, autonomous, expert + const random = Math.random(); + let cumulative = 0; + + for (let i = 0; i < weights.length; i++) { + cumulative += weights[i]; + if (random <= cumulative) { + return SKILL_LEVELS[i]; + } + } + + return "never"; +} + +async function insertTestTeams() { + const pool = getPool(); + + console.log("🏢 Création des teams de test..."); + + for (const team of TEST_TEAMS) { + await pool.query( + "INSERT INTO teams (id, name, direction) VALUES ($1, $2, $3) ON CONFLICT (id) DO NOTHING", + [team.id, team.name, TEST_DIRECTION] + ); + console.log(` ✅ Team créée: ${team.name}`); + } +} + +async function insertTestUsers() { + const pool = getPool(); + + console.log("👥 Création des utilisateurs de test..."); + + const users = []; + + // Créer 3-5 utilisateurs par team + for (const team of TEST_TEAMS) { + const userCount = 3 + Math.floor(Math.random() * 3); // 3 à 5 utilisateurs + + for (let i = 0; i < userCount; i++) { + const firstName = getRandomElement(FIRST_NAMES); + const lastName = getRandomElement(LAST_NAMES); + + try { + const result = await pool.query( + `INSERT INTO users (first_name, last_name, team_id) + VALUES ($1, $2, $3) + ON CONFLICT (first_name, last_name, team_id) DO NOTHING + RETURNING uuid_id`, + [firstName, lastName, team.id] + ); + + if (result.rows.length > 0) { + users.push({ + uuid: result.rows[0].uuid_id, + firstName, + lastName, + teamId: team.id, + }); + console.log( + ` ✅ Utilisateur créé: ${firstName} ${lastName} (${team.name})` + ); + } + } catch (error) { + // Ignore les conflits de nom + console.log( + ` ⚠️ Utilisateur ${firstName} ${lastName} existe déjà dans ${team.name}` + ); + } + } + } + + return users; +} + +async function insertTestEvaluations(users: any[], skills: SkillData[]) { + const pool = getPool(); + + console.log("📊 Création des évaluations de test..."); + + for (const user of users) { + console.log(` 📝 Évaluation pour ${user.firstName} ${user.lastName}...`); + + // Créer une évaluation pour cet utilisateur + const evaluationResult = await pool.query( + `INSERT INTO user_evaluations (user_uuid) + VALUES ($1) + ON CONFLICT (user_uuid) DO UPDATE SET last_updated = CURRENT_TIMESTAMP + RETURNING id`, + [user.uuid] + ); + + const evaluationId = evaluationResult.rows[0].id; + + // Sélectionner aléatoirement 15-30 skills à évaluer + const skillsToEvaluate = getRandomElements( + skills, + 15 + Math.floor(Math.random() * 16) + ); + + for (const skill of skillsToEvaluate) { + const level = generateRandomLevel(); + const canMentor = level === "expert" ? Math.random() > 0.5 : false; + const wantsToLearn = + level === "never" || level === "not-autonomous" + ? Math.random() > 0.3 + : false; + + await pool.query( + `INSERT INTO skill_evaluations (user_evaluation_id, skill_id, level, can_mentor, wants_to_learn, is_selected) + VALUES ($1, $2, $3, $4, $5, $6) + ON CONFLICT (user_evaluation_id, skill_id) DO UPDATE SET + level = $3, can_mentor = $4, wants_to_learn = $5, updated_at = CURRENT_TIMESTAMP`, + [evaluationId, skill.id, level, canMentor, wantsToLearn, true] + ); + } + + console.log(` ✅ ${skillsToEvaluate.length} skills évaluées`); + } +} + +async function main() { + try { + console.log("🚀 Génération des données de test...\n"); + + // Charger tous les skills + console.log("📚 Chargement des skills..."); + const skills = await loadAllSkills(); + console.log(` ✅ ${skills.length} skills chargées\n`); + + // Créer les teams + await insertTestTeams(); + console.log(""); + + // Créer les utilisateurs + const users = await insertTestUsers(); + console.log(` 📊 Total: ${users.length} utilisateurs créés\n`); + + // Créer les évaluations + await insertTestEvaluations(users, skills); + console.log(""); + + console.log("✨ Données de test générées avec succès !"); + console.log(`📈 Résumé :`); + console.log(` - Direction: ${TEST_DIRECTION}`); + console.log(` - Teams: ${TEST_TEAMS.length}`); + console.log(` - Utilisateurs: ${users.length}`); + console.log(` - Skills disponibles: ${skills.length}`); + } catch (error) { + console.error("❌ Erreur lors de la génération des données:", error); + process.exit(1); + } finally { + await closePool(); + } +} + +// Exécuter le script +if (require.main === module) { + main(); +}