import { and, asc, eq, inArray, isNull } from 'drizzle-orm'; import { message, superValidate } from 'sveltekit-superforms/server'; import { zod4 } from 'sveltekit-superforms/adapters'; import { db } from '$lib/server/db'; import { contracts, contractRooms, clients, rooms, services } from '$lib/server/db/schema'; import { loadOrganizationContext } from '$lib/server/organizations'; import { archiveSchema } from '$lib/schemas/shared.schema'; import type { Actions, PageServerLoad } from './$types'; async function loadOptions(organizationId: string) { const clientRows = await db .select({ id: clients.id, name: clients.name }) .from(clients) .where(and(eq(clients.organizationId, organizationId), isNull(clients.archivedAt))) .orderBy(asc(clients.name)); return { clients: clientRows.map((client) => ({ label: client.name, value: client.id })) }; } export const load: PageServerLoad = async ({ locals }) => { const { activeOrganizationId } = await loadOrganizationContext(locals); const records = await db .select({ contract: contracts, serviceName: services.name }) .from(contracts) .leftJoin(services, eq(contracts.serviceId, services.id)) .where(and(eq(contracts.organizationId, activeOrganizationId), isNull(contracts.archivedAt))) .orderBy(asc(contracts.startDate)); const contractIds = records.map((record) => record.contract.id); const roomLinks = contractIds.length > 0 ? await db .select({ contractId: contractRooms.contractId, roomName: rooms.name }) .from(contractRooms) .innerJoin(rooms, eq(contractRooms.roomId, rooms.id)) .where(inArray(contractRooms.contractId, contractIds)) .orderBy(asc(rooms.name)) : []; const roomNamesByContract = new Map(); for (const link of roomLinks) { const existing = roomNamesByContract.get(link.contractId) ?? []; existing.push(link.roomName); roomNamesByContract.set(link.contractId, existing); } return { records: records.map((record) => ({ ...record.contract, roomName: (roomNamesByContract.get(record.contract.id) ?? []).join(', '), serviceName: record.serviceName })), options: await loadOptions(activeOrganizationId), archiveForm: await superValidate(zod4(archiveSchema), { id: 'contracts-archive', errors: false }) }; }; export const actions: Actions = { archive: async (event) => { const { activeOrganizationId } = await loadOrganizationContext(event.locals); const form = await superValidate(event, zod4(archiveSchema), { id: 'contracts-archive' }); if (!form.valid) return message(form, 'Contract id is required.', { status: 400 }); await db .update(contracts) .set({ archivedAt: new Date(), updatedAt: new Date() }) .where( and(eq(contracts.id, form.data.id), eq(contracts.organizationId, activeOrganizationId)) ); return message(form, 'Contract archived.'); } };