Phase 1A done

This commit is contained in:
2026-05-03 21:16:52 +02:00
parent 49190c5d7e
commit b8995b3a1b
21 changed files with 1038 additions and 3 deletions
@@ -0,0 +1,113 @@
import type { Request, Response } from "express";
import { CircuitRepository } from "../../db/repositories/circuit.repository.js";
import { CircuitDeviceRowRepository } from "../../db/repositories/circuit-device-row.repository.js";
import { CircuitListRepository } from "../../db/repositories/circuit-list.repository.js";
import { CircuitSectionRepository } from "../../db/repositories/circuit-section.repository.js";
import type { CircuitTreeResponse } from "../../domain/models/circuit-tree.model.js";
import { LegacyConsumerMigrationService } from "../../domain/services/legacy-consumer-migration.service.js";
const circuitListRepository = new CircuitListRepository();
const circuitSectionRepository = new CircuitSectionRepository();
const circuitRepository = new CircuitRepository();
const circuitDeviceRowRepository = new CircuitDeviceRowRepository();
const legacyConsumerMigrationService = new LegacyConsumerMigrationService();
function rowTotalPower(quantity: number, powerPerUnit: number, simultaneityFactor: number): number {
return quantity * powerPerUnit * simultaneityFactor;
}
export async function getCircuitTree(req: Request, res: Response) {
const { projectId, circuitListId } = req.params;
if (typeof projectId !== "string" || typeof circuitListId !== "string") {
return res.status(400).json({ error: "Invalid parameters" });
}
const list = await circuitListRepository.findById(projectId, circuitListId);
if (!list) {
return res.status(404).json({ error: "Circuit list not found" });
}
const migrationReport = await legacyConsumerMigrationService.migrateCircuitList(projectId, circuitListId);
const sections = await circuitSectionRepository.listByCircuitList(circuitListId);
const circuits = await circuitRepository.listByCircuitList(circuitListId);
const rows = await circuitDeviceRowRepository.listByCircuitList(circuits.map((entry) => entry.id));
const sectionById = new Map(sections.map((section) => [section.id, section]));
const rowsByCircuitId = new Map<string, typeof rows>();
for (const row of rows) {
if (!rowsByCircuitId.has(row.circuitId)) {
rowsByCircuitId.set(row.circuitId, []);
}
rowsByCircuitId.get(row.circuitId)!.push(row);
}
const tree: CircuitTreeResponse = {
circuitListId,
sections: sections.map((section) => ({
id: section.id,
key: section.key,
displayName: section.displayName,
prefix: section.prefix,
sortOrder: section.sortOrder,
circuits: [],
})),
};
const sectionBlocks = new Map(tree.sections.map((section) => [section.id, section]));
for (const circuit of circuits) {
const section = sectionById.get(circuit.sectionId);
if (!section || section.circuitListId !== circuit.circuitListId) {
continue;
}
const deviceRows = (rowsByCircuitId.get(circuit.id) ?? []).map((row) => ({
id: row.id,
linkedProjectDeviceId: row.linkedProjectDeviceId ?? undefined,
legacyConsumerId: row.legacyConsumerId ?? undefined,
sortOrder: row.sortOrder,
name: row.name,
displayName: row.displayName,
phaseType: row.phaseType ?? undefined,
connectionKind: row.connectionKind ?? undefined,
costGroup: row.costGroup ?? undefined,
category: row.category ?? undefined,
level: row.level ?? undefined,
roomId: row.roomId ?? undefined,
roomNumberSnapshot: row.roomNumberSnapshot ?? undefined,
roomNameSnapshot: row.roomNameSnapshot ?? undefined,
quantity: row.quantity,
powerPerUnit: row.powerPerUnit,
simultaneityFactor: row.simultaneityFactor,
cosPhi: row.cosPhi ?? undefined,
remark: row.remark ?? undefined,
overriddenFields: row.overriddenFields ?? undefined,
rowTotalPower: rowTotalPower(row.quantity, row.powerPerUnit, row.simultaneityFactor),
}));
const circuitTotalPower = deviceRows.reduce((sum, row) => sum + row.rowTotalPower, 0);
sectionBlocks.get(section.id)?.circuits.push({
id: circuit.id,
circuitListId: circuit.circuitListId,
sectionId: circuit.sectionId,
equipmentIdentifier: circuit.equipmentIdentifier,
displayName: circuit.displayName ?? undefined,
sortOrder: circuit.sortOrder,
protectionType: circuit.protectionType ?? undefined,
protectionRatedCurrent: circuit.protectionRatedCurrent ?? undefined,
protectionCharacteristic: circuit.protectionCharacteristic ?? undefined,
cableType: circuit.cableType ?? undefined,
cableCrossSection: circuit.cableCrossSection ?? undefined,
cableLength: circuit.cableLength ?? undefined,
rcdAssignment: circuit.rcdAssignment ?? undefined,
terminalDesignation: circuit.terminalDesignation ?? undefined,
voltage: circuit.voltage ?? undefined,
status: circuit.status ?? undefined,
isReserve: Boolean(circuit.isReserve),
remark: circuit.remark ?? undefined,
circuitTotalPower,
deviceRows,
});
}
return res.json({ ...tree, migrationReport });
}
@@ -1,9 +1,11 @@
import type { Request, Response } from "express";
import { CircuitListRepository } from "../../db/repositories/circuit-list.repository.js";
import { CircuitSectionRepository } from "../../db/repositories/circuit-section.repository.js";
import { DistributionBoardRepository } from "../../db/repositories/distribution-board.repository.js";
import { createDistributionBoardSchema } from "../../shared/validation/consumer.schemas.js";
const circuitListRepository = new CircuitListRepository();
const circuitSectionRepository = new CircuitSectionRepository();
const distributionBoardRepository = new DistributionBoardRepository();
export async function listDistributionBoardsByProject(req: Request, res: Response) {
@@ -28,10 +30,11 @@ export async function createDistributionBoard(req: Request, res: Response) {
}
const board = await distributionBoardRepository.create(projectId, parsed.data.name);
await circuitListRepository.createForDistributionBoard({
const list = await circuitListRepository.createForDistributionBoard({
projectId,
distributionBoardId: board.id,
name: `${board.name} Stromkreisliste`,
});
await circuitSectionRepository.createDefaults(list.id);
return res.status(201).json(board);
}
+2
View File
@@ -12,6 +12,7 @@ import {
import { listCircuitListsByProject } from "../controllers/circuit-list.controller.js";
import { createFloor, listFloorsByProject } from "../controllers/floor.controller.js";
import { createRoom, listRoomsByProject } from "../controllers/room.controller.js";
import { getCircuitTree } from "../controllers/circuit-tree.controller.js";
export const projectRouter = Router();
@@ -22,6 +23,7 @@ projectRouter.put("/:projectId", updateProjectSettings);
projectRouter.get("/:projectId/distribution-boards", listDistributionBoardsByProject);
projectRouter.post("/:projectId/distribution-boards", createDistributionBoard);
projectRouter.get("/:projectId/circuit-lists", listCircuitListsByProject);
projectRouter.get("/:projectId/circuit-lists/:circuitListId/tree", getCircuitTree);
projectRouter.get("/:projectId/floors", listFloorsByProject);
projectRouter.post("/:projectId/floors", createFloor);
projectRouter.get("/:projectId/rooms", listRoomsByProject);