"use server"; import { createAdminClient } from "@/lib/supabase/server"; import { auth } from "@clerk/nextjs/server"; async function getOrgAndUserId() { const { userId } = await auth(); if (!userId) throw new Error("Unauthenticated"); const supabase = await createAdminClient(); const { data } = await supabase .from("organisation_members") .select("organisation_id, role") .eq("user_id", userId) .single(); if (!data) throw new Error("No org found"); return { orgId: data.organisation_id, userId }; } export async function fetchAppraisalTemplates(): Promise { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data } = await supabase .from("appraisal_templates") .select("*") .eq("organisation_id", orgId) .order("created_at", { ascending: false }); return data || []; } export async function createAppraisalTemplate( name: string, questions: { id: string; question: string; type: string }[] ): Promise<{ success: boolean; id?: string; error?: string }> { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data, error } = await supabase .from("appraisal_templates") .insert({ organisation_id: orgId, name, questions: JSON.stringify(questions) }) .select("id") .single(); if (error) return { success: false, error: error.message }; return { success: true, id: data.id }; } export async function deleteAppraisalTemplate( id: string ): Promise<{ success: boolean; error?: string }> { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { error } = await supabase .from("appraisal_templates") .delete() .eq("id", id) .eq("organisation_id", orgId); if (error) return { success: false, error: error.message }; return { success: true }; } export async function fetchAppraisalCycles(): Promise { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data } = await supabase .from("appraisal_cycles") .select("*, template:appraisal_templates(name), appraisals:appraisals(count)") .eq("organisation_id", orgId) .order("created_at", { ascending: false }); return data || []; } export async function createAppraisalCycle(input: { name: string; template_id?: string; period_start: string; period_end: string; }): Promise<{ success: boolean; id?: string; error?: string }> { const { orgId, userId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data, error } = await supabase .from("appraisal_cycles") .insert({ ...input, organisation_id: orgId, created_by: userId }) .select("id") .single(); if (error) return { success: false, error: error.message }; // Generate appraisals for all active employees if (input.template_id) { const { data: employees } = await supabase .from("employees") .select("id, manager_id") .eq("organisation_id", orgId) .eq("status", "active"); const inserts: any[] = []; for (const emp of employees || []) { inserts.push({ organisation_id: orgId, cycle_id: data.id, employee_id: emp.id, reviewer_id: emp.id, type: "self", }); if (emp.manager_id) { inserts.push({ organisation_id: orgId, cycle_id: data.id, employee_id: emp.id, reviewer_id: emp.manager_id, type: "manager", }); } } if (inserts.length > 0) { await supabase.from("appraisals").insert(inserts); } } return { success: true, id: data.id }; } export async function updateAppraisalCycleStatus( id: string, status: string ): Promise<{ success: boolean; error?: string }> { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { error } = await supabase .from("appraisal_cycles") .update({ status }) .eq("id", id) .eq("organisation_id", orgId); if (error) return { success: false, error: error.message }; return { success: true }; } export async function fetchCycleAppraisals(cycleId: string): Promise { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data } = await supabase .from("appraisals") .select("*, employee:employees(first_name, last_name), reviewer:employees(first_name, last_name)") .eq("organisation_id", orgId) .eq("cycle_id", cycleId) .order("employee_id"); return data || []; } export async function fetchAppraisal(id: string): Promise { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data } = await supabase .from("appraisals") .select("*, employee:employees(first_name, last_name), reviewer:employees(first_name, last_name), cycle:appraisal_cycles(name, template:appraisal_templates(questions))") .eq("organisation_id", orgId) .eq("id", id) .single(); return data; } export async function submitAppraisal( id: string, responses: any, overallRating: number ): Promise<{ success: boolean; error?: string }> { const supabase = await createAdminClient(); const { error } = await supabase .from("appraisals") .update({ responses: JSON.stringify(responses), overall_rating: overallRating, status: "submitted", submitted_at: new Date().toISOString(), }) .eq("id", id); if (error) return { success: false, error: error.message }; return { success: true }; } export async function fetchMyPendingAppraisals(): Promise { const { userId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data: emp } = await supabase .from("employees") .select("id") .eq("user_id", userId) .single(); if (!emp) return []; const { data } = await supabase .from("appraisals") .select("*, employee:employees(first_name, last_name), cycle:appraisal_cycles(name)") .eq("reviewer_id", emp.id) .eq("status", "pending") .order("created_at"); return data || []; }