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:
2026-04-06 17:11:05 +07:00
commit 6f0e0ad6c6
64 changed files with 8996 additions and 0 deletions
@@ -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 };
}
};