import type { PageServerLoad, Actions } from './$types'; import { db } from '$lib/server/db'; import { fosterAssignments, users } from '$lib/server/schema'; import { eq, and, asc } from 'drizzle-orm'; import { error, fail } from '@sveltejs/kit'; import { logAudit } from '$lib/server/audit'; import { hasPermission, canViewPets } from '$lib/roles'; export const load: PageServerLoad = async ({ parent, locals }) => { if (!canViewPets(locals.user!.role)) error(403, 'Access denied'); const { pet } = await parent(); const assignments = await db .select({ id: fosterAssignments.id, petId: fosterAssignments.petId, userId: fosterAssignments.userId, startDate: fosterAssignments.startDate, endDate: fosterAssignments.endDate, isCurrent: fosterAssignments.isCurrent, notes: fosterAssignments.notes, createdAt: fosterAssignments.createdAt, fosterName: users.name, fosterEmail: users.email }) .from(fosterAssignments) .leftJoin(users, eq(fosterAssignments.userId, users.id)) .where(eq(fosterAssignments.petId, pet.id)) .orderBy(asc(fosterAssignments.startDate)); // Load active foster-role users for the dropdown const fosterUsers = await db .select({ id: users.id, name: users.name, email: users.email }) .from(users) .where(and(eq(users.role, 'foster'), eq(users.active, true))) .orderBy(asc(users.name)); return { assignments, fosterUsers }; }; export const actions: Actions = { add: async ({ request, params, locals }) => { if (!hasPermission(locals.user!.role, 'pets')) error(403, 'Access denied'); const petId = parseInt(params.id, 10); const fd = await request.formData(); const userIdStr = fd.get('userId')?.toString(); const userId = userIdStr ? parseInt(userIdStr, 10) : null; if (!userId || isNaN(userId)) { return fail(400, { error: 'Foster user is required' }); } const startDateStr = fd.get('startDate')?.toString() || null; const startDate = startDateStr ? new Date(startDateStr) : new Date(); const endDateStr = fd.get('endDate')?.toString() || null; const endDate = endDateStr ? new Date(endDateStr) : null; const notes = fd.get('notes')?.toString().trim() || null; const isCurrent = fd.get('isCurrent') === 'on'; // If marking as current, unset all others if (isCurrent) { await db.update(fosterAssignments).set({ isCurrent: false }).where(eq(fosterAssignments.petId, petId)); } const [inserted] = await db.insert(fosterAssignments).values({ petId, userId, startDate, endDate, notes, isCurrent }).$returningId(); await logAudit({ userId: locals.user!.id, action: 'create', entity: 'foster_assignment', entityId: inserted.id, diff: { petId, userId, isCurrent } }); return { success: true }; }, setCurrent: async ({ request, params, locals }) => { if (!hasPermission(locals.user!.role, 'pets')) error(403, 'Access denied'); const petId = parseInt(params.id, 10); const fd = await request.formData(); const assignmentId = parseInt(fd.get('assignmentId') as string, 10); if (!assignmentId || isNaN(assignmentId)) { return fail(400, { error: 'Invalid assignment ID' }); } const isCurrent = fd.get('isCurrent') === 'on'; if (isCurrent) { await db.update(fosterAssignments).set({ isCurrent: false }).where(eq(fosterAssignments.petId, petId)); } await db.update(fosterAssignments).set({ isCurrent }).where(eq(fosterAssignments.id, assignmentId)); await logAudit({ userId: locals.user!.id, action: 'update', entity: 'foster_assignment', entityId: assignmentId, diff: { petId, isCurrent } }); return { success: true }; }, delete: async ({ request, params, locals }) => { if (!hasPermission(locals.user!.role, 'pets')) error(403, 'Access denied'); const petId = parseInt(params.id, 10); const fd = await request.formData(); const assignmentId = parseInt(fd.get('assignmentId') as string, 10); if (!assignmentId || isNaN(assignmentId)) { return fail(400, { error: 'Invalid assignment ID' }); } await db.delete(fosterAssignments).where(eq(fosterAssignments.id, assignmentId)); await logAudit({ userId: locals.user!.id, action: 'delete', entity: 'foster_assignment', entityId: assignmentId, diff: { petId } }); return { success: true }; } };