forked from jappel/leistungsbilanz-ts
151 lines
8.4 KiB
Markdown
151 lines
8.4 KiB
Markdown
# 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 automatisch in Stromkreislisten, Verteilungen oder Projektgeräte. Eine
|
||
ausdrückliche Einzelaktion kann die Werte einer Grobbilanz-Zeile als Vorschlag
|
||
in den bestehenden Projektgeräte-Dialog übernehmen; erst dessen Bestätigung
|
||
legt über `project-device.insert` ein unplatziertes Projektgerät an.
|
||
|
||
## 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 (Auswahl ELT/MSR oder 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. Stände bleiben bearbeitbar; ein zusätzlicher Status oder
|
||
eine Bearbeitungssperre ist derzeit nicht vorgesehen.
|
||
|
||
## 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 %.
|
||
|
||
## Übernahme als Projektgerät
|
||
|
||
Die Zeilenaktion „Als Projektgerät übernehmen“ ist eine einmalige, ausdrücklich
|
||
bestätigte Kopie. Vor dem Öffnen des Dialogs werden ausstehende Änderungen der
|
||
Grobbilanz gespeichert. Das Anlegen läuft anschließend mit der aktuellen
|
||
Projektrevision über den normalen Projektgeräte-Befehl und ist dadurch wie ein
|
||
manuell angelegtes Projektgerät rückgängig machbar.
|
||
|
||
- Name und Anzeigename kommen aus dem Zeilennamen; Kostengruppe, GZF, cos φ und
|
||
Anmerkung werden vorgeschlagen. `fixed` und `socket` erscheinen als
|
||
„Festanschluss“ und „Steckdose“.
|
||
- W werden für Stückzeilen in kW umgerechnet. Die Projektgeräte-Anzahl ist 1,
|
||
weil das Projektgerät als Vorlage für eine spätere Gerätezeile dient; die
|
||
ursprüngliche Stückzahl bleibt im Herkunftshinweis sichtbar.
|
||
- Die Kategorie ist mangels Phaseninformation in der Grobbilanz mit
|
||
„1-phasig“ vorbelegt und muss im Dialog fachlich geprüft werden.
|
||
- Flächenzeilen dürfen übernommen werden. Anzahl und Leistung je Stück bleiben
|
||
leer und müssen manuell angegeben werden, da das Projektgerät noch keine
|
||
Einheit W/m² kennt (siehe Issue #20).
|
||
- SV wird nur im Herkunftshinweis gezeigt. Die tatsächliche Versorgungsart
|
||
gehört zur Verteilung.
|
||
- Gleichnamige vorhandene Projektgeräte erzeugen eine Warnung, sperren das
|
||
Anlegen aber nicht.
|
||
|
||
Zwischen Grobbilanz-Zeile und Projektgerät wird keine Verbindung gespeichert.
|
||
Es gibt keine Stapelübernahme und keine automatische Platzierung in einer
|
||
Verteilung oder einem Stromkreis. Snapshot-, Transfer- und
|
||
Grobbilanz-Befehlsformate ändern sich dadurch nicht.
|
||
|
||
## 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 }`).
|
||
|
||
## Projekttransfer und bewusste Abgrenzung
|
||
|
||
- Das reguläre SQLite-Datenbank-Backup sichert die Grobbilanz-Tabellen zusammen
|
||
mit allen übrigen Anwendungsdaten.
|
||
- Benannte und automatische Projektsnapshots enthalten keine Grobbilanzen; das
|
||
Snapshot-Schema bleibt Version 7. Snapshot-Restore und dessen Undo/Redo lassen
|
||
vorhandene Grobbilanzen unverändert.
|
||
- Der portable Projektexport enthält alle Grobbilanzen ab Transferformat 2.
|
||
Ersetzen übernimmt sie atomar und rückgängig machbar; Duplizieren vergibt neue
|
||
IDs für Bilanz, Gruppen und Zeilen. Alte Transferdateien in Version 1 bleiben
|
||
importierbar und enthalten definitionsgemäß keine Grobbilanzen.
|
||
- Keine Rechte je Gewerk; „bearbeitet von“ ist ein Freitext je Kostengruppe.
|
||
- Kostengruppen der Gerätezeilen sind nicht normiert; der Vergleich arbeitet
|
||
mit Präfixen.
|
||
- Der erste Vergleich zeigt die geschätzte und detaillierte AV-Wirkleistung in
|
||
kW. SV- und kVA-Vergleiche können später ergänzt werden.
|
||
- Eine Stromkreisnummer gehört nicht zur Grobbilanz, weil sie eine frühe
|
||
Abschätzung ohne Stromkreisplanung ist.
|
||
|
||
## 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.
|