import crypto from "node:crypto"; import { and, eq } from "drizzle-orm"; import { db } from "../client.js"; import { projectDevices } from "../schema/project-devices.js"; import { calculateRowTotalPower } from "../../domain/calculations/circuit-power-calculation.js"; import type { CreateProjectDeviceInput, UpdateProjectDeviceInput, } from "../../shared/validation/project-device.schemas.js"; function withTotalPower(row: typeof projectDevices.$inferSelect) { return { ...row, totalPower: calculateRowTotalPower(row.quantity, row.powerPerUnit, row.simultaneityFactor), }; } export class ProjectDeviceRepository { async listByProject(projectId: string) { const rows = await db.select().from(projectDevices).where(eq(projectDevices.projectId, projectId)); return rows.map(withTotalPower); } async create(projectId: string, input: CreateProjectDeviceInput) { const id = crypto.randomUUID(); await db.insert(projectDevices).values({ id, projectId, name: input.name, displayName: input.displayName, phaseType: input.phaseType, connectionKind: input.connectionKind ?? null, costGroup: input.costGroup ?? null, category: input.category ?? null, quantity: input.quantity, powerPerUnit: input.powerPerUnit, simultaneityFactor: input.simultaneityFactor, cosPhi: input.cosPhi ?? null, remark: input.remark ?? null, installedPowerPerUnitKw: input.powerPerUnit, demandFactor: input.simultaneityFactor, voltageV: input.voltageV ?? null, phaseCount: input.phaseType === "three_phase" ? 3 : 1, powerFactor: input.cosPhi ?? null, note: input.remark ?? null, }); const created = await this.findById(projectId, id); if (!created) { throw new Error("Failed to create project device."); } return created; } async findById(projectId: string, projectDeviceId: string) { const [row] = await db .select() .from(projectDevices) .where( and(eq(projectDevices.id, projectDeviceId), eq(projectDevices.projectId, projectId)) ) .limit(1); return row ? withTotalPower(row) : null; } async update(projectId: string, projectDeviceId: string, input: UpdateProjectDeviceInput) { await db .update(projectDevices) .set({ name: input.name, displayName: input.displayName, phaseType: input.phaseType, connectionKind: input.connectionKind ?? null, costGroup: input.costGroup ?? null, category: input.category ?? null, quantity: input.quantity, powerPerUnit: input.powerPerUnit, simultaneityFactor: input.simultaneityFactor, cosPhi: input.cosPhi ?? null, remark: input.remark ?? null, installedPowerPerUnitKw: input.powerPerUnit, demandFactor: input.simultaneityFactor, voltageV: input.voltageV ?? null, phaseCount: input.phaseType === "three_phase" ? 3 : 1, powerFactor: input.cosPhi ?? null, note: input.remark ?? null, }) .where( and(eq(projectDevices.id, projectDeviceId), eq(projectDevices.projectId, projectId)) ); } async delete(projectId: string, projectDeviceId: string) { await db .delete(projectDevices) .where( and(eq(projectDevices.id, projectDeviceId), eq(projectDevices.projectId, projectId)) ); } }