feat: implement hierarchical category management with parent-child relationships and enhance category creation dialog

This commit is contained in:
Julien Froidefond
2025-11-27 10:29:59 +01:00
parent d7374e4129
commit 7314cb6716
9 changed files with 1048 additions and 260 deletions

View File

@@ -4,41 +4,85 @@ import { defaultCategories, defaultRootFolder } from "../lib/defaults"
const prisma = new PrismaClient()
async function main() {
console.log("Seeding database...")
console.log("🌱 Seeding database...")
// Create root folder if it doesn't exist
// ═══════════════════════════════════════════════════════════════════════════
// Créer le dossier racine
// ═══════════════════════════════════════════════════════════════════════════
const rootFolder = await prisma.folder.upsert({
where: { id: defaultRootFolder.id },
update: {},
create: defaultRootFolder,
})
console.log("📁 Root folder:", rootFolder.name)
console.log("Root folder created:", rootFolder.name)
// ═══════════════════════════════════════════════════════════════════════════
// Créer les catégories (hiérarchiques)
// ═══════════════════════════════════════════════════════════════════════════
const slugToId = new Map<string, string>()
// Create default categories
for (const category of defaultCategories) {
// D'abord les parents
const parents = defaultCategories.filter((c) => c.parentSlug === null)
console.log(`\n🏷 Création de ${parents.length} catégories parentes...`)
for (const category of parents) {
const existing = await prisma.category.findFirst({
where: {
name: category.name,
parentId: category.parentId,
},
where: { name: category.name, parentId: null },
})
if (!existing) {
await prisma.category.create({
const created = await prisma.category.create({
data: {
name: category.name,
color: category.color,
icon: category.icon,
keywords: JSON.stringify(category.keywords),
parentId: category.parentId,
parentId: null,
},
})
console.log(`Created category: ${category.name}`)
slugToId.set(category.slug, created.id)
console.log(`${category.name}`)
} else {
slugToId.set(category.slug, existing.id)
}
}
console.log("Seeding completed!")
// Puis les enfants
const children = defaultCategories.filter((c) => c.parentSlug !== null)
console.log(`\n📂 Création de ${children.length} sous-catégories...`)
for (const category of children) {
const parentId = slugToId.get(category.parentSlug!)
if (!parentId) {
console.log(` ⚠️ Parent non trouvé pour: ${category.name}`)
continue
}
const existing = await prisma.category.findFirst({
where: { name: category.name, parentId },
})
if (!existing) {
const created = await prisma.category.create({
data: {
name: category.name,
color: category.color,
icon: category.icon,
keywords: JSON.stringify(category.keywords),
parentId,
},
})
slugToId.set(category.slug, created.id)
console.log(`${category.name}`)
} else {
slugToId.set(category.slug, existing.id)
}
}
// Stats
const totalCategories = await prisma.category.count()
console.log(`\n✨ Seeding terminé! ${totalCategories} catégories en base.`)
}
main()
@@ -49,4 +93,3 @@ main()
.finally(async () => {
await prisma.$disconnect()
})