Initial commit: buildfor_life_repair inventory system
SvelteKit + PostgreSQL app for tracking vintage computers, audio equipment, components, and installation history. Features device/component CRUD, operation logs, QR code labels, global search, image uploads, and dark mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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<string, number> = {};
|
||||
for (const r of deviceCounts) {
|
||||
if (r.locationId) dcMap[r.locationId] = r.count;
|
||||
}
|
||||
const ccMap: Record<string, number> = {};
|
||||
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 };
|
||||
},
|
||||
|
||||
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 };
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user