Files
buildfor_life_repair/src/routes/(app)/+page.server.ts
T
grabowski 5c4595ed16
Deploy to LXC / deploy (push) Successful in 29s
Restructure components into types + instances
Components are now split into two concepts:
- Component (type definition): title, componentType, brand, partNumber,
  specs, notes, default condition/firmware/location
- Component Instance (individual physical unit): serialNumber, condition,
  firmwareVersion, notes, currentDeviceId, locationId

Key changes:
- New component_instances table with per-unit tracking
- Component list shows cards with total/installed/available counts
- Component detail page shows all instances with inline edit
- Add instances: bulk (quantity) or one at a time
- Each instance has install/remove/edit/delete actions
- Installation log now references instances, not components
- Device detail shows installed instances with instance numbers
- Dashboard and sidebar counts use instance totals
- Location pages show instances, not component types
- Labels show component type info (serial is per-instance)

IMPORTANT: Run db:push on the server after deploy to create the new
tables and columns. Existing component data will need manual migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:41:06 +07:00

74 lines
2.3 KiB
TypeScript

import type { PageServerLoad } from './$types';
import { db } from '$lib/server/db/index.js';
import { devices, components, componentInstances, installationLog } from '$lib/server/db/schema.js';
import { count, eq, or, and, desc, sql } from 'drizzle-orm';
export const load: PageServerLoad = async () => {
const active = eq(devices.disabled, false);
// Total counts
const [totalDevices] = await db.select({ value: count() }).from(devices).where(active);
const [computers] = await db
.select({ value: count() })
.from(devices)
.where(and(active, eq(devices.category, 'Computer')));
const [audio] = await db
.select({ value: count() })
.from(devices)
.where(and(active, eq(devices.category, 'Audio Equipment')));
const [totalComponents] = await db.select({ value: count() }).from(componentInstances);
// Condition breakdown
const conditionBreakdown = await db
.select({
condition: devices.condition,
count: count()
})
.from(devices)
.where(active)
.groupBy(devices.condition);
// Recent installation activity
const recentActivity = await db
.select({
action: installationLog.action,
performedAt: installationLog.performedAt,
instanceId: installationLog.instanceId,
instanceNumber: componentInstances.instanceNumber,
deviceId: installationLog.deviceId,
componentTitle: components.title,
deviceTitle: devices.title
})
.from(installationLog)
.innerJoin(componentInstances, eq(installationLog.instanceId, componentInstances.id))
.innerJoin(components, eq(componentInstances.componentId, components.id))
.innerJoin(devices, eq(installationLog.deviceId, devices.id))
.orderBy(desc(installationLog.performedAt))
.limit(10);
// Devices needing repair
const needsRepair = await db
.select({
id: devices.id,
title: devices.title,
category: devices.category,
condition: devices.condition,
faultDescription: devices.faultDescription
})
.from(devices)
.where(and(active, or(eq(devices.condition, 'In Repair'), eq(devices.condition, 'Waiting for Repair'))))
.limit(10);
return {
stats: {
totalDevices: totalDevices?.value ?? 0,
computers: computers?.value ?? 0,
audio: audio?.value ?? 0,
totalComponents: totalComponents?.value ?? 0
},
conditionBreakdown,
recentActivity,
needsRepair
};
};