"use server"; import { auth } from "@/auth"; import { prisma } from "@/lib/db"; import { canAccessEvaluation } from "@/lib/evaluation-access"; import { getEvaluation } from "@/lib/server-data"; import { revalidatePath } from "next/cache"; export type ActionResult = { success: true; data?: T } | { success: false; error: string }; export async function fetchEvaluation(id: string): Promise>>> { const session = await auth(); if (!session?.user) return { success: false, error: "Non authentifié" }; const evaluation = await getEvaluation(id); if (!evaluation) return { success: false, error: "Évaluation introuvable" }; return { success: true, data: evaluation }; } export async function deleteEvaluation(id: string): Promise { const session = await auth(); if (!session?.user) return { success: false, error: "Non authentifié" }; const hasAccess = await canAccessEvaluation(id, session.user.id, session.user.role === "admin"); if (!hasAccess) return { success: false, error: "Accès refusé" }; try { await prisma.evaluation.delete({ where: { id } }); revalidatePath("/dashboard"); return { success: true }; } catch (e) { console.error(e); return { success: false, error: "Erreur lors de la suppression" }; } } export async function createEvaluation(data: { candidateName: string; candidateRole: string; candidateTeam?: string; evaluationDate: string; templateId: string; }): Promise> { const session = await auth(); if (!session?.user) return { success: false, error: "Non authentifié" }; const { candidateName, candidateRole, candidateTeam, evaluationDate, templateId } = data; if (!candidateName || !candidateRole || !evaluationDate || !templateId) { return { success: false, error: "Champs requis manquants" }; } try { const evaluatorName = session.user.name || session.user.email || "Évaluateur"; const template = await prisma.template.findUnique({ where: { id: templateId }, include: { dimensions: { orderBy: { orderIndex: "asc" } } }, }); if (!template) return { success: false, error: "Template introuvable" }; const evaluation = await prisma.evaluation.create({ data: { candidateName, candidateRole, candidateTeam: candidateTeam || null, evaluatorName, evaluatorId: session.user.id, evaluationDate: new Date(evaluationDate), templateId, status: "draft", }, }); await prisma.dimensionScore.createMany({ data: template.dimensions.map((dim) => ({ evaluationId: evaluation.id, dimensionId: dim.id, })), }); revalidatePath("/dashboard"); return { success: true, data: { id: evaluation.id } }; } catch (e) { console.error(e); return { success: false, error: "Erreur lors de la création" }; } } export interface UpdateEvaluationInput { candidateName?: string; candidateRole?: string; candidateTeam?: string | null; evaluatorName?: string; evaluationDate?: string; status?: string; findings?: string | null; recommendations?: string | null; isPublic?: boolean; dimensionScores?: { dimensionId: string; evaluationId: string; score: number | null; justification?: string | null; examplesObserved?: string | null; confidence?: string | null; candidateNotes?: string | null; }[]; } export async function updateDimensionScore( evaluationId: string, dimensionId: string, data: { score?: number | null; justification?: string | null; examplesObserved?: string | null; confidence?: string | null; candidateNotes?: string | null } ): Promise { const session = await auth(); if (!session?.user) return { success: false, error: "Non authentifié" }; const hasAccess = await canAccessEvaluation(evaluationId, session.user.id, session.user.role === "admin"); if (!hasAccess) return { success: false, error: "Accès refusé" }; try { await prisma.dimensionScore.upsert({ where: { evaluationId_dimensionId: { evaluationId, dimensionId } }, update: data, create: { evaluationId, dimensionId, ...data }, }); revalidatePath(`/evaluations/${evaluationId}`); return { success: true }; } catch (e) { return { success: false, error: e instanceof Error ? e.message : "Erreur" }; } } export async function updateEvaluation(id: string, data: UpdateEvaluationInput): Promise { const session = await auth(); if (!session?.user) return { success: false, error: "Non authentifié" }; const hasAccess = await canAccessEvaluation(id, session.user.id, session.user.role === "admin"); if (!hasAccess) return { success: false, error: "Accès refusé" }; const existing = await prisma.evaluation.findUnique({ where: { id } }); if (!existing) return { success: false, error: "Évaluation introuvable" }; try { const { candidateName, candidateRole, candidateTeam, evaluatorName, evaluationDate, status, findings, recommendations, isPublic, dimensionScores, } = data; const updateData: Record = {}; if (candidateName != null) updateData.candidateName = candidateName; if (candidateRole != null) updateData.candidateRole = candidateRole; if (candidateTeam !== undefined) updateData.candidateTeam = candidateTeam; if (evaluatorName != null) updateData.evaluatorName = evaluatorName; if (evaluationDate != null) { const d = new Date(evaluationDate); if (!isNaN(d.getTime())) updateData.evaluationDate = d; } if (status != null) updateData.status = status; if (findings != null) updateData.findings = findings; if (recommendations != null) updateData.recommendations = recommendations; if (typeof isPublic === "boolean") updateData.isPublic = isPublic; if (Object.keys(updateData).length > 0) { await prisma.auditLog.create({ data: { evaluationId: id, action: "updated", newValue: JSON.stringify(updateData) }, }); await prisma.evaluation.update({ where: { id }, data: updateData as Record }); } if (dimensionScores && Array.isArray(dimensionScores)) { const validScores = dimensionScores.filter((ds) => ds.dimensionId); if (validScores.length > 0) { await prisma.$transaction( validScores.map((ds) => prisma.dimensionScore.upsert({ where: { evaluationId_dimensionId: { evaluationId: id, dimensionId: ds.dimensionId }, }, update: { score: ds.score, justification: ds.justification, examplesObserved: ds.examplesObserved, confidence: ds.confidence, candidateNotes: ds.candidateNotes, }, create: { evaluationId: id, dimensionId: ds.dimensionId, score: ds.score, justification: ds.justification, examplesObserved: ds.examplesObserved, confidence: ds.confidence, candidateNotes: ds.candidateNotes, }, }) ) ); } } revalidatePath(`/evaluations/${id}`); revalidatePath("/dashboard"); return { success: true }; } catch (e) { console.error(e); return { success: false, error: e instanceof Error ? e.message : "Erreur lors de la sauvegarde" }; } }