Files
peakskills/scripts/sync-skills.ts
Julien Froidefond a4b680b092 refactor: update database setup and remove skills migration API
- Changed migration commands in DATABASE_SETUP.md to use `pnpm run sync-skills` and `pnpm run sync-teams`.
- Removed the skills migration API endpoint in route.ts, streamlining the migration process.
- Updated MIGRATION_UUID.md to reflect changes in migration steps and removed the old skills migration script.
- Added new sync scripts for skills and teams in package.json.
- Cleaned up init.sql by removing old teams data insertion and adjusted comments for clarity.
2025-08-21 15:21:36 +02:00

150 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env tsx
import { SkillsService } from "../services/skills-service";
import { loadSkillCategoriesFromFiles } from "../lib/skill-file-loader";
import { SkillCategory, Skill } from "../lib/types";
interface SyncStats {
categoriesProcessed: number;
skillsProcessed: number;
newSkills: number;
updatedSkills: number;
skippedSkills: number;
}
/**
* Synchronise les skills depuis les fichiers JSON vers la base de données
* - Préserve les skills existantes (ne modifie que description/image)
* - Ajoute uniquement les nouvelles skills
* - Ne supprime jamais de skills
*/
async function syncSkillsToDatabase(): Promise<void> {
try {
console.log("🚀 Démarrage de la synchronisation des skills...");
// Charger les skills depuis les fichiers JSON
const skillCategoriesFromFiles = loadSkillCategoriesFromFiles();
console.log(`📁 ${skillCategoriesFromFiles.length} catégories trouvées dans les fichiers`);
// Récupérer les skills existantes de la base de données
const existingCategories = await SkillsService.getSkillCategories();
console.log(`💾 ${existingCategories.length} catégories existantes en base`);
// Créer un map des skills existantes pour une recherche rapide
const existingSkillsMap = new Map<string, Skill>();
existingCategories.forEach(category => {
category.skills.forEach(skill => {
existingSkillsMap.set(skill.id, skill);
});
});
console.log(`🔍 ${existingSkillsMap.size} skills existantes détectées`);
const stats: SyncStats = {
categoriesProcessed: 0,
skillsProcessed: 0,
newSkills: 0,
updatedSkills: 0,
skippedSkills: 0
};
// Synchroniser chaque catégorie
for (const categoryFromFile of skillCategoriesFromFiles) {
console.log(`\n📂 Traitement de la catégorie: ${categoryFromFile.category}`);
const categoryId = categoryFromFile.category.toLowerCase();
// Vérifier si la catégorie existe, sinon la créer
const existingCategory = existingCategories.find(cat =>
cat.category.toLowerCase() === categoryFromFile.category.toLowerCase()
);
if (!existingCategory) {
console.log(` Création de la nouvelle catégorie: ${categoryFromFile.category}`);
await SkillsService.createSkillCategory({
id: categoryId,
name: categoryFromFile.category,
icon: categoryFromFile.icon
});
}
// Synchroniser les skills de cette catégorie
for (const skillFromFile of categoryFromFile.skills) {
const existingSkill = existingSkillsMap.get(skillFromFile.id);
if (!existingSkill) {
// Nouvelle skill - l'ajouter
console.log(` Nouvelle skill: ${skillFromFile.name} (${skillFromFile.id})`);
await SkillsService.createSkill({
id: skillFromFile.id,
name: skillFromFile.name,
description: skillFromFile.description,
icon: skillFromFile.icon,
categoryId: categoryId,
links: skillFromFile.links || []
});
stats.newSkills++;
} else {
// Skill existante - vérifier s'il faut mettre à jour description/icon/links
const needsUpdate =
existingSkill.description !== skillFromFile.description ||
existingSkill.icon !== skillFromFile.icon ||
JSON.stringify(existingSkill.links?.sort()) !== JSON.stringify(skillFromFile.links?.sort());
if (needsUpdate) {
console.log(` 🔄 Mise à jour de la skill: ${skillFromFile.name} (${skillFromFile.id})`);
// Utiliser la méthode bulkInsert avec une seule catégorie/skill pour la mise à jour
await SkillsService.bulkInsertSkillsFromJSON([{
category: categoryFromFile.category,
icon: categoryFromFile.icon,
skills: [skillFromFile]
}]);
stats.updatedSkills++;
} else {
console.log(` ✅ Skill inchangée: ${skillFromFile.name} (${skillFromFile.id})`);
stats.skippedSkills++;
}
}
stats.skillsProcessed++;
}
stats.categoriesProcessed++;
}
// Afficher les statistiques finales
console.log("\n📊 Statistiques de synchronisation:");
console.log(` • Catégories traitées: ${stats.categoriesProcessed}`);
console.log(` • Skills traitées: ${stats.skillsProcessed}`);
console.log(` • Nouvelles skills: ${stats.newSkills}`);
console.log(` • Skills mises à jour: ${stats.updatedSkills}`);
console.log(` • Skills inchangées: ${stats.skippedSkills}`);
// Vérification finale
const finalCategories = await SkillsService.getSkillCategories();
const totalSkillsInDb = finalCategories.reduce((sum, cat) => sum + cat.skills.length, 0);
console.log(`\n✅ Synchronisation terminée avec succès!`);
console.log(`💾 Total skills en base: ${totalSkillsInDb}`);
} catch (error) {
console.error("❌ Erreur lors de la synchronisation:", error);
process.exit(1);
}
}
// Exécuter le script si appelé directement
if (require.main === module) {
syncSkillsToDatabase()
.then(() => {
console.log("🎉 Script terminé avec succès");
process.exit(0);
})
.catch((error) => {
console.error("💥 Erreur fatale:", error);
process.exit(1);
});
}
export { syncSkillsToDatabase };