"use server"; import { revalidatePath } from "next/cache"; import { prisma } from "@/lib/db"; import { requireUserId } from "@/lib/auth-helpers"; import { CategoryNameSchema } from "@/lib/validation/category"; import type { CategoryDTO } from "@/types/board"; export async function createCategory(name: string): Promise { const userId = await requireUserId(); const parsedName = CategoryNameSchema.parse(name); const count = await prisma.category.count({ where: { userId } }); const category = await prisma.category.create({ data: { name: parsedName, order: count, userId }, }); revalidatePath("/"); return { id: category.id, name: category.name, order: category.order, groups: [] }; } export async function renameCategory(categoryId: string, name: string): Promise { const userId = await requireUserId(); const parsedName = CategoryNameSchema.parse(name); const { count } = await prisma.category.updateMany({ where: { id: categoryId, userId }, data: { name: parsedName }, }); if (count === 0) throw new Error("Category not found"); revalidatePath("/"); } export async function deleteCategory(categoryId: string): Promise { const userId = await requireUserId(); const { count } = await prisma.category.deleteMany({ where: { id: categoryId, userId }, }); if (count === 0) throw new Error("Category not found"); revalidatePath("/"); } /** * Persists a new lane order for all of the current user's categories. * `orderedIds` must contain every category id the user owns. */ export async function reorderCategories(orderedIds: string[]): Promise { const userId = await requireUserId(); const owned = await prisma.category.findMany({ where: { userId }, select: { id: true }, }); const ownedIds = new Set(owned.map((c) => c.id)); if (orderedIds.length !== ownedIds.size || !orderedIds.every((id) => ownedIds.has(id))) { throw new Error("Category list does not match the current user's categories"); } await prisma.$transaction( orderedIds.map((id, index) => prisma.category.update({ where: { id }, data: { order: index } }) ) ); revalidatePath("/"); }