Add the rough power balance module for early design phases
In LPH 2/3 there are no circuits yet, but the office needs a power balance by DIN 276 cost group, as in the Excel template "Leistungsbilanz - KG400": each trade enters consumers by piece or by area (W/m²) with GLF and cos phi; the balance sums AV and SV per cost group, adds a reserve and derives the maximum current. The module is separate from the circuit structure: own tables (migration 0010), own folder src/estimate-balance and an import-free shared calculation used by API and UI. Writes go through project commands (estimate-balance.insert/.update/.delete with complete documents), so revision checks and Undo/Redo apply; it is not part of project snapshots or transfer yet. A comparison endpoint sums the device rows of all circuit lists by cost group (longest prefix) against the estimate. The UI adds a sidebar entry, a list of Stände (template KG 400, empty or copy) and a spreadsheet-like editor with autosave, AMEV picker for the GLF, totals, reserve, maximum current, comparison table and print layout. The tests reproduce the template example exactly (143.24 kW, 148.48 kVA, 157.56 kW / 163.33 kVA with 10 % reserve, 235.75 A). See docs/estimate-balance.md and issue #7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
80dbc73230
commit
37a70b6b36
37 changed files with 8537 additions and 4 deletions
|
|
@ -16,6 +16,8 @@ ausdrücklich getrennt und dürfen nicht als bereits implementiert verstanden we
|
|||
Verteilerübersicht, Verteilerpläne, Büro-Logo
|
||||
- [Gebäudestruktur](building-structure.md) – Gebäude → Etagen → Räume,
|
||||
Befehle, Snapshot-Schema 7, eigene Seite
|
||||
- [Grobe Leistungsbilanz](estimate-balance.md) – LPH 2/3 nach Kostengruppen,
|
||||
Rechnung, Vergleich mit der detaillierten Bilanz
|
||||
- [Editor-API](circuit-list-editor-api.md) – unterstützte Circuit-First-Endpunkte
|
||||
- [Bekannte Einschränkungen](circuit-list-editor-known-limitations.md) –
|
||||
bewusst noch nicht implementierte oder begrenzte Funktionen
|
||||
|
|
|
|||
|
|
@ -214,6 +214,12 @@ A stale `expectedRevision` returns HTTP `409` with
|
|||
`PROJECT_REVISION_CONFLICT`. Undo or redo without an eligible stack entry
|
||||
returns HTTP `409` with `PROJECT_HISTORY_OPERATION_UNAVAILABLE`.
|
||||
|
||||
## Estimate Balance (Grobe Leistungsbilanz)
|
||||
|
||||
Separate module under `/projects/:projectId/estimate-balances`; complete
|
||||
documents are written through `estimate-balance.insert/.update/.delete` project
|
||||
commands. Endpoints, payloads and calculation rules: `docs/estimate-balance.md`.
|
||||
|
||||
## Circuit-First Endpoints
|
||||
|
||||
### Distribution Board Setup
|
||||
|
|
|
|||
108
docs/estimate-balance.md
Normal file
108
docs/estimate-balance.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Grobe Leistungsbilanz (LPH 2/3)
|
||||
|
||||
Eigenes Modul für die Leistungsbilanz der Vor- und Entwurfsplanung, gegliedert
|
||||
nach Kostengruppen (DIN 276, KG 400). Es gibt dort noch keine Verteilungen und
|
||||
Stromkreise: Jedes Gewerk trägt unter seiner Kostengruppe Verbraucher als
|
||||
Stückzahl mit Einzelleistung oder als Fläche mit W/m² ein. Aufbau und Rechnung
|
||||
folgen der bisherigen Excel-Vorlage „Leistungsbilanz – KG400“. Abstimmung:
|
||||
Issue #7.
|
||||
|
||||
Das Modul ist **nicht** mit der Stromkreisstruktur verknüpft. Es liest die
|
||||
Gerätezeilen nur für den Vergleich „geschätzt ↔ detailliert“ und schreibt
|
||||
nichts in Stromkreislisten, Verteilungen oder Projektgeräte.
|
||||
|
||||
## Aufbau
|
||||
|
||||
```
|
||||
src/shared/estimate-balance/estimate-balance.ts Datenform, Rechnung, Vergleich (rein, ohne Imports)
|
||||
src/estimate-balance/domain/estimate-balance-command.model.ts Snapshot-Schema (Zod), Befehle
|
||||
src/estimate-balance/domain/estimate-balance-project-command.store.ts Store-Port
|
||||
src/estimate-balance/api/estimate-balance-request.schemas.ts Request-Schemas
|
||||
src/db/schema/estimate-balances.ts Tabellen (Migration 0010)
|
||||
src/db/repositories/estimate-balance*.ts Lesen, Schreiben, Befehls-Store
|
||||
src/server/controllers/estimate-balance.controller.ts API
|
||||
src/app/projects/[projectId]/grobbilanz/ Übersicht der Stände und Editor
|
||||
src/frontend/estimate-balance/ Editor-Komponenten und Helfer
|
||||
```
|
||||
|
||||
Die gemeinsame Datei unter `src/shared/estimate-balance` hat keine Imports, weil
|
||||
das Frontend sie direkt nutzt (Turbopack löst die `.js`-Suffixe der API nicht auf).
|
||||
|
||||
## Datenmodell
|
||||
|
||||
| Tabelle | Inhalt |
|
||||
|---|---|
|
||||
| `estimate_balances` | ein **Stand** je Projekt (z. B. Vorplanung, Entwurfsplanung): Name, LPH, Datum, Reserve AV/SV in %, Sortierung |
|
||||
| `estimate_groups` | Kostengruppe (`"410"` … `"480"`, `""` für „Allgemein“), Titel, „bearbeitet von“, Sortierung |
|
||||
| `estimate_rows` | Versorgung, Stromkreis-Nr. (Freitext), Verbraucher/Fläche, Anzahl bzw. Fläche, Einheit (`piece` = St., `area` = m²), Anschluss (fest/Steckdose), Einzelleistung in W bzw. W/m², GLF, cos φ, SV ja/nein, Anmerkung |
|
||||
|
||||
Neue Stände entstehen aus der Vorlage KG 400 (410 Sanitär, 420 Wärme, 430 Luft,
|
||||
434 Kälte, 440 Starkstrom, 450 Schwachstrom, 460 Förder, 470 Nutzungsspezifisch,
|
||||
480 GA, Allgemein; Reserve AV 10 %), leer oder als Kopie eines bestehenden
|
||||
Stands mit neuen IDs. So lässt sich ein Stand einfrieren und später vergleichen.
|
||||
|
||||
## Rechnung
|
||||
|
||||
- Zeile: P = Anzahl bzw. Fläche × Einzelleistung × GLF, S = P / cos φ.
|
||||
- **AV** enthält alle Verbraucher (Normalversorgung). **SV** listet zusätzlich
|
||||
die Zeilen mit „SV = ja“, die auch aus der Sicherheitsstromversorgung versorgt
|
||||
werden müssen. Das ist die Lesart der Vorlage; die Regel liegt in
|
||||
`calculateEstimateRow` und lässt sich dort zentral ändern.
|
||||
- Summen je Kostengruppe, Gesamtsumme, Reserve in % (AV und SV getrennt),
|
||||
Leistung inklusive Reserve und Maximalstrom I = S / (√3 · U) mit der
|
||||
Drehstromspannung aus den Projekteinstellungen.
|
||||
- Anzeige wie in der Tabellenkalkulation gerundet (`roundEstimateValue`,
|
||||
40,175 → 40,18). Der Test `tests/estimate-balance.test.ts` rechnet das
|
||||
Beispiel der Vorlage vollständig nach (143,24 kW, 148,48 kVA, mit 10 %
|
||||
Reserve 157,56 kW / 163,33 kVA, 235,75 A).
|
||||
|
||||
## Vergleich geschätzt ↔ detailliert
|
||||
|
||||
`GET …/comparison` summiert alle Gerätezeilen aller Stromkreislisten des
|
||||
Projekts (Anzahl × Leistung je Stück × Geräte-GZF, wie der Stromkreisbaum) und
|
||||
ordnet sie über das Feld **Kostengruppe** der Gerätezeile zu. Maßgeblich ist das
|
||||
längste passende Präfix: `434` → Gruppe 434, `431` → Gruppe 430, `444` → 440.
|
||||
Zeilen ohne passende Kostengruppe erscheinen als „nicht zugeordnet“. Der
|
||||
Verteiler-GZF wird auf keiner Seite angewendet; ein fehlendes cos φ zählt als 1.
|
||||
Verglichen wird die AV-Leistung (kW) mit Differenz absolut und in %.
|
||||
|
||||
## Befehle, Undo/Redo
|
||||
|
||||
Alle Änderungen laufen über den bestehenden Projekt-Befehlsmechanismus mit
|
||||
Revision, Inverse und persistentem Undo/Redo:
|
||||
|
||||
- `estimate-balance.insert` / `estimate-balance.delete` mit dem vollständigen
|
||||
Stand (Gruppen und Zeilen)
|
||||
- `estimate-balance.update` mit vollständigem `expected`/`target`-Dokument; der
|
||||
Store prüft, dass der gespeicherte Stand genau `expected` entspricht, und
|
||||
ersetzt ihn atomar. Die Inverse ist das vertauschte Paar.
|
||||
|
||||
Der Editor speichert das ganze Dokument verzögert (Autosave); jeder
|
||||
Speichervorgang ist ein Undo-Schritt. Unveränderte Dokumente erzeugen keine
|
||||
Revision (`{ unchanged: true }`).
|
||||
|
||||
## Bewusst nicht enthalten (Fragen an Julian, Issue #7)
|
||||
|
||||
- Die grobe Bilanz ist **nicht** Teil von Projekt-Snapshot, Restore und
|
||||
Projekttransfer; das Snapshot-Schema bleibt unverändert. Ein Restore lässt
|
||||
die Stände unverändert, eine Projektkopie übernimmt sie nicht.
|
||||
- Keine Rechte je Gewerk; „bearbeitet von“ ist ein Freitext je Kostengruppe.
|
||||
- Kostengruppen der Gerätezeilen sind nicht normiert; der Vergleich arbeitet
|
||||
mit Präfixen.
|
||||
|
||||
## API
|
||||
|
||||
- `GET /api/projects/:projectId/estimate-balances`
|
||||
- `POST /api/projects/:projectId/estimate-balances` –
|
||||
`{ "expectedRevision": 7, "name": "Entwurfsplanung", "workStage": "LPH 3", "dateIso": "2026-09-26", "template": "kg400" }`
|
||||
(`template`: `kg400` | `empty` | `copy` mit `copyFromBalanceId`)
|
||||
- `GET /api/projects/:projectId/estimate-balances/:balanceId`
|
||||
- `PUT /api/projects/:projectId/estimate-balances/:balanceId` –
|
||||
`{ "expectedRevision": 8, "balance": { …vollständiges Dokument… } }`
|
||||
- `DELETE /api/projects/:projectId/estimate-balances/:balanceId` – `{ "expectedRevision": 9 }`
|
||||
- `GET /api/projects/:projectId/estimate-balances/:balanceId/comparison`
|
||||
|
||||
Validierung: Name 1–200 Zeichen, getrimmte Texte, Anzahl/Fläche und
|
||||
Einzelleistung ≥ 0, GLF 0–1, cos φ > 0 bis 1, Reserve 0–100 %, Datum
|
||||
`YYYY-MM-DD`, eindeutige Gruppen- und Zeilen-IDs, unbekannte Felder werden
|
||||
abgelehnt.
|
||||
Loading…
Add table
Add a link
Reference in a new issue