Organize/lib/actions/projects.ts

57 lines
1.8 KiB
TypeScript

"use server";
import { revalidatePath } from "next/cache";
import { prisma } from "@/lib/db";
import { requireUserId } from "@/lib/auth-helpers";
import { projectAccessFilter } from "@/lib/access";
import { ProjectTitleSchema } from "@/lib/validation/project";
import type { ProjectDTO } from "@/types/project";
export async function createProject(title: string): Promise<ProjectDTO> {
const userId = await requireUserId();
const parsedTitle = ProjectTitleSchema.parse(title);
const project = await prisma.project.create({
data: { title: parsedTitle, ownerId: userId },
});
revalidatePath("/projects");
return { id: project.id, title: project.title };
}
export async function renameProject(projectId: string, title: string): Promise<void> {
const userId = await requireUserId();
const parsedTitle = ProjectTitleSchema.parse(title);
const { count } = await prisma.project.updateMany({
where: { id: projectId, ...projectAccessFilter(userId) },
data: { title: parsedTitle },
});
if (count === 0) throw new Error("Project not found");
revalidatePath("/projects");
revalidatePath(`/projects/${projectId}`);
}
export type DeleteProjectResult = { error?: string };
/**
* Deletes a project and everything in it -- its categories, groups, and
* to-dos all cascade away with it (unlike deleting a single Category,
* which refuses if it still has groups). The confirmation dialog on the
* client carries the "this can't be undone" warning; this action doesn't
* re-check emptiness.
*/
export async function deleteProject(projectId: string): Promise<DeleteProjectResult> {
const userId = await requireUserId();
const { count } = await prisma.project.deleteMany({
where: { id: projectId, ...projectAccessFilter(userId) },
});
if (count === 0) return { error: "Project not found." };
revalidatePath("/projects");
return {};
}