import crypto from "node:crypto"; import { and, asc, eq, inArray } from "drizzle-orm"; import { db } from "../client.js"; import { circuitDeviceRows } from "../schema/circuit-device-rows.js"; import { circuitLists } from "../schema/circuit-lists.js"; import { circuits } from "../schema/circuits.js"; import { distributionBoards } from "../schema/distribution-boards.js"; export class CircuitDeviceRowRepository { async findById(rowId: string) { const [row] = await db.select().from(circuitDeviceRows).where(eq(circuitDeviceRows.id, rowId)).limit(1); return row ?? null; } async countByCircuit(circuitId: string) { const rows = await db.select({ id: circuitDeviceRows.id }).from(circuitDeviceRows).where(eq(circuitDeviceRows.circuitId, circuitId)); return rows.length; } async listByCircuitList(circuitIds: string[]) { if (!circuitIds.length) { return []; } return db .select() .from(circuitDeviceRows) .where(inArray(circuitDeviceRows.circuitId, circuitIds)) .orderBy(asc(circuitDeviceRows.sortOrder)); } async listLinkedByProjectDevice(projectId: string, projectDeviceId: string) { return db .select({ id: circuitDeviceRows.id, circuitId: circuitDeviceRows.circuitId, linkedProjectDeviceId: circuitDeviceRows.linkedProjectDeviceId, legacyConsumerId: circuitDeviceRows.legacyConsumerId, sortOrder: circuitDeviceRows.sortOrder, name: circuitDeviceRows.name, displayName: circuitDeviceRows.displayName, phaseType: circuitDeviceRows.phaseType, connectionKind: circuitDeviceRows.connectionKind, costGroup: circuitDeviceRows.costGroup, category: circuitDeviceRows.category, level: circuitDeviceRows.level, roomId: circuitDeviceRows.roomId, roomNumberSnapshot: circuitDeviceRows.roomNumberSnapshot, roomNameSnapshot: circuitDeviceRows.roomNameSnapshot, quantity: circuitDeviceRows.quantity, powerPerUnit: circuitDeviceRows.powerPerUnit, simultaneityFactor: circuitDeviceRows.simultaneityFactor, cosPhi: circuitDeviceRows.cosPhi, remark: circuitDeviceRows.remark, overriddenFields: circuitDeviceRows.overriddenFields, equipmentIdentifier: circuits.equipmentIdentifier, circuitDisplayName: circuits.displayName, circuitListId: circuitLists.id, circuitListName: circuitLists.name, distributionBoardId: distributionBoards.id, distributionBoardName: distributionBoards.name, }) .from(circuitDeviceRows) .innerJoin(circuits, eq(circuitDeviceRows.circuitId, circuits.id)) .innerJoin(circuitLists, eq(circuits.circuitListId, circuitLists.id)) .innerJoin(distributionBoards, eq(circuitLists.distributionBoardId, distributionBoards.id)) .where( and( eq(circuitDeviceRows.linkedProjectDeviceId, projectDeviceId), eq(circuitLists.projectId, projectId) ) ) .orderBy(asc(distributionBoards.name), asc(circuits.equipmentIdentifier), asc(circuitDeviceRows.sortOrder)); } async create(input: { circuitId: string; linkedProjectDeviceId?: string; legacyConsumerId?: string; sortOrder: number; name: string; displayName: string; phaseType?: string; connectionKind?: string; costGroup?: string; category?: string; level?: string; roomId?: string; roomNumberSnapshot?: string; roomNameSnapshot?: string; quantity: number; powerPerUnit: number; simultaneityFactor: number; cosPhi?: number; remark?: string; overriddenFields?: string; }) { const id = crypto.randomUUID(); await db.insert(circuitDeviceRows).values({ id, circuitId: input.circuitId, linkedProjectDeviceId: input.linkedProjectDeviceId ?? null, legacyConsumerId: input.legacyConsumerId ?? null, sortOrder: input.sortOrder, name: input.name, displayName: input.displayName, phaseType: input.phaseType ?? null, connectionKind: input.connectionKind ?? null, costGroup: input.costGroup ?? null, category: input.category ?? null, level: input.level ?? null, roomId: input.roomId ?? null, roomNumberSnapshot: input.roomNumberSnapshot ?? null, roomNameSnapshot: input.roomNameSnapshot ?? null, quantity: input.quantity, powerPerUnit: input.powerPerUnit, simultaneityFactor: input.simultaneityFactor, cosPhi: input.cosPhi ?? null, remark: input.remark ?? null, overriddenFields: input.overriddenFields ?? null, }); return id; } async update( rowId: string, input: { linkedProjectDeviceId?: string; name: string; displayName: string; phaseType?: string; connectionKind?: string; costGroup?: string; category?: string; level?: string; roomId?: string; roomNumberSnapshot?: string; roomNameSnapshot?: string; quantity: number; powerPerUnit: number; simultaneityFactor: number; cosPhi?: number; remark?: string; overriddenFields?: string; } ) { await db .update(circuitDeviceRows) .set({ linkedProjectDeviceId: input.linkedProjectDeviceId ?? null, name: input.name, displayName: input.displayName, phaseType: input.phaseType ?? null, connectionKind: input.connectionKind ?? null, costGroup: input.costGroup ?? null, category: input.category ?? null, level: input.level ?? null, roomId: input.roomId ?? null, roomNumberSnapshot: input.roomNumberSnapshot ?? null, roomNameSnapshot: input.roomNameSnapshot ?? null, quantity: input.quantity, powerPerUnit: input.powerPerUnit, simultaneityFactor: input.simultaneityFactor, cosPhi: input.cosPhi ?? null, remark: input.remark ?? null, overriddenFields: input.overriddenFields ?? null, }) .where(eq(circuitDeviceRows.id, rowId)); } async delete(rowId: string) { await db.delete(circuitDeviceRows).where(eq(circuitDeviceRows.id, rowId)); } async moveToCircuit(rowId: string, targetCircuitId: string, sortOrder: number) { await db .update(circuitDeviceRows) .set({ circuitId: targetCircuitId, sortOrder, }) .where(eq(circuitDeviceRows.id, rowId)); } }