leistungsbilanz-ts/src/frontend/components/cable-sizing-api.ts
Grovy311 8b8526b8df Add proposed cable-sizing module
Isolated module (mirrors src/external-model/ dependency direction) that
adds an on-demand, DIN VDE 0298-4 referenced cable cross-section
calculator: a click-on-a-circuit input mask for laying method,
insulation, ambient temperature, grouping and voltage-drop limit that
suggests a cross-section for the circuit cableCrossSection/cableLength
fields. Applying a suggestion goes through the existing circuit.update
command (expectedRevision, undo/redo) unchanged - nothing here writes
to circuits directly or touches the revision/command system. See
docs/cable-sizing-module.md for the full rationale, API contract,
verification status and maintenance plan. Proposal, not yet reviewed
by the project owner - see the docs file.

423 existing + 11 new tests pass, build:api/build:web/typecheck:scripts
clean.
2026-09-25 19:31:35 +02:00

71 lines
2.1 KiB
TypeScript

// Thin, self-contained fetch client for the cable-sizing module. Deliberately
// not merged into ../utils/api.ts to keep this module's frontend footprint a
// single new file rather than growing the existing shared API file - see
// docs/cable-sizing-module.md.
import type {
CableSizingAlert,
CableSizingInput,
CableSizingResult,
InsulationMaterial,
LayingMethod,
} from "../../cable-sizing/domain/cable-sizing-calculation";
async function request<T>(url: string, init?: RequestInit): Promise<T> {
const response = await fetch(url, {
...init,
headers: { "Content-Type": "application/json", ...init?.headers },
cache: "no-store",
});
if (!response.ok) {
let details = await response.text();
try {
const parsed = JSON.parse(details) as { error?: unknown };
if (typeof parsed.error === "string") details = parsed.error;
} catch {
// keep raw text
}
throw new Error(details || `Anfrage fehlgeschlagen (Status ${response.status})`);
}
return response.json() as Promise<T>;
}
export interface CalculateCableSizingResponse {
calculationId: string;
result: CableSizingResult;
alerts: CableSizingAlert[];
}
export function calculateCableSizing(
input: CableSizingInput,
context?: { projectId?: string; circuitId?: string; equipmentIdentifier?: string }
): Promise<CalculateCableSizingResponse> {
return request("/api/cable-sizing/calculate", {
method: "POST",
body: JSON.stringify({ ...input, context }),
});
}
export function markCableSizingCalculationApplied(calculationId: string): Promise<unknown> {
return request(`/api/cable-sizing/calculations/${calculationId}/applied`, {
method: "POST",
});
}
export interface LayingMethodOption {
method: LayingMethod;
label: string;
dataVerified: boolean;
}
export function listLayingMethods(): Promise<LayingMethodOption[]> {
return request("/api/cable-sizing/laying-methods");
}
export interface InsulationMaterialOption {
insulation: InsulationMaterial;
label: string;
}
export function listInsulationMaterials(): Promise<InsulationMaterialOption[]> {
return request("/api/cable-sizing/insulation-materials");
}