117 lines
3.9 KiB
TypeScript
117 lines
3.9 KiB
TypeScript
"use server";
|
|
|
|
import { auth } from "@/auth";
|
|
import { db } from "@/lib/db";
|
|
import { revalidatePath } from "next/cache";
|
|
import { z } from "zod";
|
|
import { ShotStatus, ShotPriority } from "@prisma/client";
|
|
|
|
const createAssetSchema = z.object({
|
|
assetCode: z.string().min(1, "Asset code is required").max(30).regex(/^[A-Z0-9_\-]+$/i),
|
|
name: z.string().min(1, "Name is required").max(200),
|
|
description: z.string().optional(),
|
|
status: z.nativeEnum(ShotStatus).default("WAITING"),
|
|
priority: z.nativeEnum(ShotPriority).default("NORMAL"),
|
|
leadId: z.string().cuid().optional().or(z.literal("")),
|
|
dueDate: z.string().optional(),
|
|
projectId: z.string().cuid(),
|
|
});
|
|
|
|
export async function createAsset(data: z.infer<typeof createAssetSchema>) {
|
|
const session = await auth();
|
|
if (!session?.user) throw new Error("Unauthorized");
|
|
if (!["ADMIN", "PRODUCER", "SUPERVISOR"].includes(session.user.role)) {
|
|
throw new Error("Insufficient permissions");
|
|
}
|
|
|
|
const parsed = createAssetSchema.parse(data);
|
|
|
|
const asset = await db.asset.create({
|
|
data: {
|
|
assetCode: parsed.assetCode.toUpperCase(),
|
|
name: parsed.name,
|
|
description: parsed.description,
|
|
status: parsed.status,
|
|
priority: parsed.priority,
|
|
leadId: parsed.leadId || undefined,
|
|
dueDate: parsed.dueDate ? new Date(parsed.dueDate) : undefined,
|
|
projectId: parsed.projectId,
|
|
},
|
|
});
|
|
|
|
revalidatePath(`/projects/${parsed.projectId}`);
|
|
return { success: true, asset };
|
|
}
|
|
|
|
const updateAssetSchema = z.object({
|
|
name: z.string().min(1).max(200).optional(),
|
|
description: z.string().optional(),
|
|
status: z.nativeEnum(ShotStatus).optional(),
|
|
priority: z.nativeEnum(ShotPriority).optional(),
|
|
leadId: z.string().cuid().nullable().optional(),
|
|
dueDate: z.string().nullable().optional(),
|
|
});
|
|
|
|
export async function updateAsset(assetId: string, data: z.infer<typeof updateAssetSchema>) {
|
|
const session = await auth();
|
|
if (!session?.user) throw new Error("Unauthorized");
|
|
if (!["ADMIN", "PRODUCER", "SUPERVISOR"].includes(session.user.role)) {
|
|
throw new Error("Insufficient permissions");
|
|
}
|
|
|
|
const parsed = updateAssetSchema.parse(data);
|
|
|
|
const asset = await db.asset.findUnique({ where: { id: assetId } });
|
|
if (!asset) throw new Error("Asset not found");
|
|
|
|
const updated = await db.asset.update({
|
|
where: { id: assetId },
|
|
data: {
|
|
...(parsed.name !== undefined && { name: parsed.name }),
|
|
...(parsed.description !== undefined && { description: parsed.description }),
|
|
...(parsed.status !== undefined && { status: parsed.status }),
|
|
...(parsed.priority !== undefined && { priority: parsed.priority }),
|
|
...(parsed.leadId !== undefined && { leadId: parsed.leadId }),
|
|
...(parsed.dueDate !== undefined && {
|
|
dueDate: parsed.dueDate ? new Date(parsed.dueDate) : null,
|
|
}),
|
|
},
|
|
});
|
|
|
|
revalidatePath(`/projects/${asset.projectId}`);
|
|
return { success: true, asset: updated };
|
|
}
|
|
|
|
export async function deleteAsset(assetId: string) {
|
|
const session = await auth();
|
|
if (!session?.user) throw new Error("Unauthorized");
|
|
if (!["ADMIN", "PRODUCER", "SUPERVISOR"].includes(session.user.role)) {
|
|
throw new Error("Insufficient permissions");
|
|
}
|
|
|
|
const asset = await db.asset.findUnique({ where: { id: assetId } });
|
|
if (!asset) throw new Error("Asset not found");
|
|
|
|
await db.asset.delete({ where: { id: assetId } });
|
|
revalidatePath(`/projects/${asset.projectId}`);
|
|
return { success: true };
|
|
}
|
|
|
|
export async function getProjectAssets(projectId: string) {
|
|
const session = await auth();
|
|
if (!session?.user) throw new Error("Unauthorized");
|
|
|
|
return db.asset.findMany({
|
|
where: { projectId },
|
|
orderBy: { assetCode: "asc" },
|
|
include: {
|
|
lead: { select: { id: true, name: true, email: true, image: true } },
|
|
_count: { select: { tasks: true } },
|
|
tasks: {
|
|
orderBy: { sortOrder: "asc" },
|
|
select: { id: true, status: true, title: true, type: true },
|
|
},
|
|
},
|
|
});
|
|
}
|