79 lines
1.7 KiB
TypeScript
79 lines
1.7 KiB
TypeScript
import { prisma } from "@/lib/prisma"
|
|
import type { Folder } from "@/lib/types"
|
|
|
|
export class FolderNotFoundError extends Error {
|
|
constructor(id: string) {
|
|
super(`Folder not found: ${id}`)
|
|
this.name = "FolderNotFoundError"
|
|
}
|
|
}
|
|
|
|
export const folderService = {
|
|
async create(data: Omit<Folder, "id">): Promise<Folder> {
|
|
const created = await prisma.folder.create({
|
|
data: {
|
|
name: data.name,
|
|
parentId: data.parentId,
|
|
color: data.color,
|
|
icon: data.icon,
|
|
},
|
|
})
|
|
|
|
return {
|
|
id: created.id,
|
|
name: created.name,
|
|
parentId: created.parentId,
|
|
color: created.color,
|
|
icon: created.icon,
|
|
}
|
|
},
|
|
|
|
async update(id: string, data: Partial<Omit<Folder, "id">>): Promise<Folder> {
|
|
const updated = await prisma.folder.update({
|
|
where: { id },
|
|
data: {
|
|
name: data.name,
|
|
parentId: data.parentId,
|
|
color: data.color,
|
|
icon: data.icon,
|
|
},
|
|
})
|
|
|
|
return {
|
|
id: updated.id,
|
|
name: updated.name,
|
|
parentId: updated.parentId,
|
|
color: updated.color,
|
|
icon: updated.icon,
|
|
}
|
|
},
|
|
|
|
async delete(id: string): Promise<void> {
|
|
const folder = await prisma.folder.findUnique({
|
|
where: { id },
|
|
include: { children: true },
|
|
})
|
|
|
|
if (!folder) {
|
|
throw new FolderNotFoundError(id)
|
|
}
|
|
|
|
// Business rule: Move accounts to root (null folderId)
|
|
await prisma.account.updateMany({
|
|
where: { folderId: id },
|
|
data: { folderId: null },
|
|
})
|
|
|
|
// Business rule: Move subfolders to parent (or root if no parent)
|
|
await prisma.folder.updateMany({
|
|
where: { parentId: id },
|
|
data: { parentId: folder.parentId },
|
|
})
|
|
|
|
await prisma.folder.delete({
|
|
where: { id },
|
|
})
|
|
},
|
|
}
|
|
|