Files
leistungsbilanz-ts/docs/circuit-list-editor-architecture.md
T

5.1 KiB

Circuit List Editor Architecture

Purpose

The circuit-list editor is a circuit-first planning workspace for distribution-board design. It is optimized for spreadsheet-like editing while preserving electrical domain boundaries: circuit-level data stays on circuits, and load rows stay inside circuits.

Frontend Grid Modules

  • circuit-tree-editor.tsx owns React state, API commands, undo/redo and drag-and-drop orchestration.
  • circuit-grid-model.ts owns column metadata, circuit/device cell ownership, value projection, formatting, numeric parsing and block sort values.
  • circuit-grid-projection.ts owns block-preserving filtering/sorting and the normalized visible row projection.
  • circuit-grid-insertion.ts resolves insertion intent and insertion sort positions.
  • circuit-grid-safety.ts resolves delete intent, BMK conflicts and cross-section move confirmation requirements.

The pure grid modules have no React state and are covered by focused unit tests. This keeps circuit/device ownership rules testable while the editor UI is split incrementally.

Domain Model Overview

  • CircuitSection
    • Represents a protected circuit group in one of the categories lighting, single-phase or three-phase.
    • Owns category, positive group number, generated prefix, display name and ordering.
  • Circuit
    • Core electrical unit in the list.
    • Owns circuit-level identifiers and technical data:
      • equipmentIdentifier (BMK)
      • one explicit one-to-one protection device
      • cable data
      • reserve state
      • voltage and optional control requirement for future sizing
      • circuit-level remark/status
  • CircuitDeviceRow
    • Load/device line inside a circuit.
    • Owns row-level load and context values:
      • quantity
      • powerPerUnit
      • simultaneityFactor
      • cosPhi
      • room snapshots
      • category/cost group and related row attributes
      • canonical phaseType values single_phase or three_phase; the frontend always presents these as 1-phasig or 3-phasig and edits them through a selection control
  • ProjectDevice
    • Reusable device template entity at project level.
    • Can be linked to CircuitDeviceRow entries, with copied display values on insert.
  • DistributionBoardComponent
    • Represents fixed header components, optional group protection and manually named auxiliary footer devices with their own unique BMK.
    • Group protection may own a separate one-to-one protection configuration.

Why A Circuit Is Not One Row

A circuit can contain zero, one, or many device rows. Treating a circuit as a single row breaks:

  • BMK ownership (belongs to circuit, not each device row)
  • circuit-level protection/cable fields
  • grouped calculations and circuit move/reorder semantics

The tree model keeps circuit identity stable while allowing row-level load composition.

Rendering Model: Single vs Multi Device

  • Single-device circuit:
    • Rendered as compact combined row (circuitCompact) for fast editing.
  • Multi-device circuit:
    • Rendered as one circuit summary row (circuitSummary) plus indented deviceRow entries.

This keeps visual density high without losing ownership boundaries.

Reserve / Empty Circuits

Circuits with no device rows are rendered as reserve rows (reserveCircuit).
Section-level -frei- placeholder rows represent insertion targets for creating a new circuit in that section.

BMK Ownership (equipmentIdentifier)

equipmentIdentifier / BMK is circuit-owned (Circuit.equipmentIdentifier).

  • Device rows do not have their own BMK.
  • Existing identifiers stay stable on sort, insert and delete. Explicit renumbering may change them, and a user-initiated complete-circuit move to another same-category group assigns the next target-group identifier.
  • Renumbering is explicit, not implicit on move/sort/delete.

Data Ownership Split: Circuit vs Device Row

Circuit-level fields on Circuit:

  • protection type/rating/characteristic
  • cable type/cross-section/length
  • RCD/terminal/status

Device-level load fields on CircuitDeviceRow:

  • quantity, power per unit, simultaneity, cosPhi
  • row naming/categorization and room snapshots

This split matches execution-design workflows where many loads share one protective path.

Calculated Totals

  • rowTotalPower is calculated per CircuitDeviceRow.
  • circuitTotalPower is calculated as sum of all row totals in one circuit.

Totals are exposed by the tree response and shown in computed read-only cells.

Frontend Route

Primary circuit-first editor route:

  • /projects/:projectId/circuit-lists/:circuitListId/tree-edit

The sibling /tree route is a read-only structure preview. Old /projects/:projectId/circuit-lists bookmarks redirect to the project page.

Future Persistence Direction

Persistent Undo/Redo, project revisions and logical snapshots are implemented through project-scoped commands and the shared transaction boundary. Database backups remain separate from user-visible project snapshots. External-model exchange and PostgreSQL readiness are specified in Project History and External Model Architecture and remain future work.