Derive device voltages from project settings

This commit is contained in:
2026-07-29 09:53:58 +02:00
parent b1a11397b3
commit 084103bf54
39 changed files with 2696 additions and 76 deletions
@@ -55,6 +55,8 @@ export async function getCircuitTree(req: Request, res: Response) {
const tree: CircuitTreeResponse = {
circuitListId,
currentRevision: project.currentRevision,
singlePhaseVoltageV: project.singlePhaseVoltageV,
threePhaseVoltageV: project.threePhaseVoltageV,
sections: sections.map((section) => ({
id: section.id,
key: section.key,
@@ -127,6 +129,8 @@ export async function getCircuitTree(req: Request, res: Response) {
return res.json({
circuitListId,
currentRevision: project.currentRevision,
singlePhaseVoltageV: project.singlePhaseVoltageV,
threePhaseVoltageV: project.threePhaseVoltageV,
sections: [],
warning:
"Circuit-first tables are not available yet. Run database migrations (including 0008_circuit_first_model).",
@@ -70,7 +70,6 @@ export async function copyProjectDeviceToGlobal(req: Request, res: Response) {
quantity: source.quantity,
installedPowerPerUnitKw: source.powerPerUnit,
demandFactor: source.simultaneityFactor,
voltageV: source.voltageV ?? undefined,
phaseCount: source.phaseType === "three_phase" ? 3 : 1,
powerFactor: source.cosPhi ?? undefined,
note: source.remark ?? undefined,
@@ -11,6 +11,7 @@ import { projectCommandService } from "../composition/project-command-stores.js"
import {
globalDeviceRepository,
projectDeviceRepository,
projectRepository,
} from "../composition/application-repositories.js";
import {
createProjectDeviceCommandSchema,
@@ -21,6 +22,7 @@ import {
} from "../../shared/validation/project-device.schemas.js";
import type { CreateProjectDeviceInput } from "../../shared/validation/project-device.schemas.js";
import { respondWithProjectCommandError } from "./project-command.controller.js";
import { resolveProjectVoltage } from "../../domain/services/project-voltage.service.js";
export async function listProjectDevicesByProject(req: Request, res: Response) {
const { projectId } = req.params;
@@ -41,9 +43,18 @@ export async function createProjectDevice(req: Request, res: Response) {
return res.status(400).json({ error: parsed.error.flatten() });
}
const { expectedRevision, ...input } = parsed.data;
const projectDevice = toProjectDeviceSnapshot(projectId, randomUUID(), input);
try {
const project = await projectRepository.findById(projectId);
if (!project) {
return res.status(404).json({ error: "Project not found" });
}
const projectDevice = toProjectDeviceSnapshot(
projectId,
randomUUID(),
input,
project
);
const result = projectCommandService.executeUser({
projectId,
expectedRevision,
@@ -73,13 +84,17 @@ export async function updateProjectDevice(req: Request, res: Response) {
const { expectedRevision, ...input } = parsed.data;
try {
const project = await projectRepository.findById(projectId);
if (!project) {
return res.status(404).json({ error: "Project not found" });
}
const result = projectCommandService.executeUser({
projectId,
expectedRevision,
description: "Projektgerät bearbeiten",
command: createProjectDeviceUpdateProjectCommand(
projectDeviceId,
toProjectDeviceValues(input)
toProjectDeviceValues(input, project)
),
});
// Linked rows are synchronized only through the explicit review flow.
@@ -133,6 +148,10 @@ export async function copyGlobalDeviceToProject(req: Request, res: Response) {
if (!source) {
return res.status(404).json({ error: "Global device not found" });
}
const project = await projectRepository.findById(projectId);
if (!project) {
return res.status(404).json({ error: "Project not found" });
}
const projectDevice = toProjectDeviceSnapshot(projectId, randomUUID(), {
name: source.name,
@@ -144,8 +163,7 @@ export async function copyGlobalDeviceToProject(req: Request, res: Response) {
simultaneityFactor: source.demandFactor,
cosPhi: source.powerFactor ?? undefined,
remark: source.note ?? undefined,
voltageV: source.voltageV ?? undefined,
});
}, project);
try {
const result = projectCommandService.executeUser({
@@ -167,16 +185,26 @@ export async function copyGlobalDeviceToProject(req: Request, res: Response) {
function toProjectDeviceSnapshot(
projectId: string,
id: string,
input: CreateProjectDeviceInput
input: CreateProjectDeviceInput,
project: {
singlePhaseVoltageV: number;
threePhaseVoltageV: number;
}
): ProjectDeviceSnapshot {
return {
id,
projectId,
...toProjectDeviceValues(input),
...toProjectDeviceValues(input, project),
};
}
function toProjectDeviceValues(input: CreateProjectDeviceInput) {
function toProjectDeviceValues(
input: CreateProjectDeviceInput,
project: {
singlePhaseVoltageV: number;
threePhaseVoltageV: number;
}
) {
return {
name: input.name,
displayName: input.displayName,
@@ -189,7 +217,7 @@ function toProjectDeviceValues(input: CreateProjectDeviceInput) {
simultaneityFactor: input.simultaneityFactor,
cosPhi: input.cosPhi ?? null,
remark: input.remark ?? null,
voltageV: input.voltageV ?? null,
voltageV: resolveProjectVoltage(input.phaseType, project),
};
}