NeahStable/scripts/clean-orphan-calendars.ts
2026-01-21 00:34:52 +01:00

150 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Script de nettoyage des calendriers de groupes orphelins
*
* Ce script supprime les calendriers de groupes dont le groupe n'existe plus dans Keycloak.
*
* Usage:
* npx tsx scripts/clean-orphan-calendars.ts
*/
import { prisma } from '../lib/prisma';
async function getAdminToken() {
try {
const tokenResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
}),
}
);
const data = await tokenResponse.json();
if (!tokenResponse.ok || !data.access_token) {
console.error('❌ Erreur token:', data);
return null;
}
return data.access_token;
} catch (error) {
console.error('❌ Erreur token:', error);
return null;
}
}
async function getAllKeycloakGroups(token: string): Promise<Set<string>> {
try {
const response = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/groups`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
if (!response.ok) {
throw new Error('Failed to fetch groups from Keycloak');
}
const groups = await response.json();
const groupNames = new Set<string>();
groups.forEach((group: any) => {
groupNames.add(group.name);
});
return groupNames;
} catch (error) {
console.error('❌ Erreur lors de la récupération des groupes:', error);
return new Set();
}
}
async function cleanOrphanCalendars() {
console.log('🧹 Début du nettoyage des calendriers orphelins...\n');
// 1. Récupérer le token Keycloak
const token = await getAdminToken();
if (!token) {
console.error('❌ Impossible d\'obtenir le token Keycloak');
process.exit(1);
}
// 2. Récupérer tous les groupes existants dans Keycloak
console.log('📋 Récupération des groupes depuis Keycloak...');
const keycloakGroups = await getAllKeycloakGroups(token);
console.log(`${keycloakGroups.size} groupes trouvés dans Keycloak\n`);
// 3. Récupérer tous les calendriers de groupes
console.log('📋 Récupération des calendriers de groupes depuis la base...');
const groupCalendars = await prisma.calendar.findMany({
where: {
name: {
startsWith: 'Groupe: ',
},
},
});
console.log(`${groupCalendars.length} calendriers de groupes trouvés\n`);
// 4. Identifier les calendriers orphelins
const orphanCalendars = groupCalendars.filter((calendar) => {
const groupName = calendar.name.replace('Groupe: ', '');
return !keycloakGroups.has(groupName);
});
if (orphanCalendars.length === 0) {
console.log('✅ Aucun calendrier orphelin trouvé. Base de données propre!\n');
return;
}
console.log(`⚠️ ${orphanCalendars.length} calendrier(s) orphelin(s) trouvé(s):\n`);
orphanCalendars.forEach((cal) => {
console.log(` - ${cal.name} (ID: ${cal.id})`);
});
// 5. Demander confirmation (commentez cette section si vous voulez une suppression automatique)
console.log('\n⚠ ATTENTION: Les calendriers ci-dessus vont être supprimés avec tous leurs événements!');
console.log('Pour confirmer, lancez le script avec: npx tsx scripts/clean-orphan-calendars.ts --confirm\n');
const isConfirmed = process.argv.includes('--confirm');
if (!isConfirmed) {
console.log('❌ Suppression annulée. Utilisez --confirm pour supprimer.');
return;
}
// 6. Supprimer les calendriers orphelins
console.log('\n🗑 Suppression des calendriers orphelins...\n');
for (const calendar of orphanCalendars) {
try {
await prisma.calendar.delete({
where: { id: calendar.id },
});
console.log(` ✅ Supprimé: ${calendar.name}`);
} catch (error) {
console.error(` ❌ Erreur lors de la suppression de ${calendar.name}:`, error);
}
}
console.log(`\n✅ Nettoyage terminé! ${orphanCalendars.length} calendrier(s) supprimé(s).\n`);
}
// Exécuter le script
cleanOrphanCalendars()
.then(() => {
process.exit(0);
})
.catch((error) => {
console.error('❌ Erreur fatale:', error);
process.exit(1);
});