import type { PageServerLoad, Actions } from './$types'; import { db } from '$lib/server/db/index.js'; import { locations, devices, components } from '$lib/server/db/schema.js'; import { eq, count, isNull } from 'drizzle-orm'; import { fail } from '@sveltejs/kit'; import { z } from 'zod'; export const load: PageServerLoad = async () => { const locationList = await db .select({ id: locations.id, name: locations.name, description: locations.description, parentId: locations.parentId }) .from(locations) .orderBy(locations.name); // Count devices and components per location const deviceCounts = await db .select({ locationId: devices.locationId, count: count() }) .from(devices) .groupBy(devices.locationId); const componentCounts = await db .select({ locationId: components.locationId, count: count() }) .from(components) .where(isNull(components.currentDeviceId)) .groupBy(components.locationId); const dcMap: Record = {}; for (const r of deviceCounts) { if (r.locationId) dcMap[r.locationId] = r.count; } const ccMap: Record = {}; for (const r of componentCounts) { if (r.locationId) ccMap[r.locationId] = r.count; } return { locations: locationList.map((l) => ({ ...l, deviceCount: dcMap[l.id] ?? 0, componentCount: ccMap[l.id] ?? 0 })) }; }; const locationSchema = z.object({ name: z.string().min(1, 'Name is required'), description: z.string().optional(), parentId: z.string().uuid().optional().or(z.literal('')) }); export const actions: Actions = { create: async ({ request }) => { const formData = await request.formData(); const raw = Object.fromEntries(formData); const result = locationSchema.safeParse(raw); if (!result.success) { return fail(400, { error: result.error.errors[0]?.message }); } await db.insert(locations).values({ name: result.data.name, description: result.data.description || null, parentId: result.data.parentId || null }); return { created: true }; }, rename: async ({ request }) => { const formData = await request.formData(); const id = formData.get('id') as string; const name = (formData.get('name') as string)?.trim(); const description = (formData.get('description') as string)?.trim(); const parentId = (formData.get('parentId') as string) || null; if (!name) return fail(400, { error: 'Name is required' }); // Prevent setting self as parent if (parentId === id) return fail(400, { error: 'Cannot set location as its own parent' }); await db .update(locations) .set({ name, description: description || null, parentId, updatedAt: new Date() }) .where(eq(locations.id, id)); return { renamed: true }; }, delete: async ({ request }) => { const formData = await request.formData(); const id = formData.get('id') as string; // Clear references first await db.update(devices).set({ locationId: null }).where(eq(devices.locationId, id)); await db.update(components).set({ locationId: null }).where(eq(components.locationId, id)); await db.delete(locations).where(eq(locations.id, id)); return { deleted: true }; } };