/** * Vérifications après application : aucun fichier perdu, aucun orphelin, tout dossier rattaché au bon espace, * pas de dossier vide, unicité des noms par dossier. Affiche l'arborescence finale. * npx tsx --env-file=.env scripts/organize/verify.ts [--tree] */ import { prisma } from "../../lib/prisma"; import { sharedSpacesInScope } from "./common"; async function main() { const spaces = await sharedSpacesInScope(); let problems = 0; const totalFiles = await prisma.file.count({ where: { deletedAt: null } }); console.log(`Fichiers actifs (toute la base) : ${totalFiles}`); for (const s of spaces) { const folders = await prisma.folder.findMany({ where: { sharedSpaceId: s.id }, include: { _count: { select: { files: true, children: true } } } }); const fids = folders.map((f) => f.id); const files = await prisma.file.findMany({ where: { deletedAt: null, folderId: { in: fids } }, select: { id: true, name: true, folderId: true } }); if (!files.length && !folders.length) continue; // Dossiers vides for (const f of folders) if (f._count.files === 0 && f._count.children === 0) { console.log(` ⚠ dossier vide : ${s.name} / ${f.name}`); problems++; } // Parents dans le même espace const byId = new Map(folders.map((f) => [f.id, f])); for (const f of folders) if (f.parentId && !byId.has(f.parentId)) { console.log(` ⚠ parent hors espace : ${f.name}`); problems++; } // Unicité des noms const seen = new Set(); for (const f of files) { const k = `${f.folderId}::${f.name.toLowerCase()}`; if (seen.has(k)) { console.log(` ⚠ nom en double : ${f.name}`); problems++; } seen.add(k); } // Arbre const roots = folders.filter((f) => !f.parentId).sort((a, b) => a.name.localeCompare(b.name, "fr")); console.log(`\n📁 ${s.name} — ${files.length} fichiers, ${folders.length} dossiers`); for (const r of roots) { console.log(` ${r.name} (${r._count.files})`); const kids = folders.filter((f) => f.parentId === r.id).sort((a, b) => a.name.localeCompare(b.name, "fr")); for (const k of kids) { console.log(` └ ${k.name} (${k._count.files})`); if (process.argv.includes("--tree")) for (const fi of files.filter((x) => x.folderId === k.id).sort((a, b) => a.name.localeCompare(b.name)).slice(0, 6)) console.log(` · ${fi.name}`); } if (process.argv.includes("--tree")) for (const fi of files.filter((x) => x.folderId === r.id).sort((a, b) => a.name.localeCompare(b.name)).slice(0, 6)) console.log(` · ${fi.name}`); } } const orphans = await prisma.file.count({ where: { deletedAt: null, folderId: null } }); console.log(`\nFichiers à la racine (hors dossier) : ${orphans} · problèmes détectés : ${problems}`); await prisma.$disconnect(); process.exit(problems ? 1 : 0); } main().catch((e) => { console.error(e); process.exit(1); });