Specify protected circuit groups
This commit is contained in:
@@ -0,0 +1,636 @@
|
||||
# Distribution Board Components and Protection Groups
|
||||
|
||||
## Status
|
||||
|
||||
This document defines the agreed target behavior for distribution-board
|
||||
components, protected circuit groups and circuit protection devices. It is a
|
||||
future specification, not proof of implementation.
|
||||
|
||||
Full rule-based protection and cable sizing is deliberately deferred. This
|
||||
phase establishes the structure and manually selected technical values that a
|
||||
later calculation and warning engine will evaluate.
|
||||
|
||||
## Goals
|
||||
|
||||
- represent the circuit list as the basis of a tabular single-line diagram
|
||||
- list incoming, group-level and auxiliary distribution-board components with
|
||||
stable equipment identifiers
|
||||
- support multiple independently protected groups for lighting, single-phase
|
||||
and three-phase outgoing circuits
|
||||
- give every newly created outgoing circuit one explicit protection device
|
||||
- preserve the existing distinction between a circuit and its device rows
|
||||
- keep every structural change atomic, revisioned and persistently undoable
|
||||
- prepare stable target fields for the later Revit round-trip
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- norm-compliant protection or cable sizing
|
||||
- automatic creation of additional groups based on the incoming rating
|
||||
- automatic phase balancing
|
||||
- manufacturer-specific product catalogs
|
||||
- automatic equipment-identifier generation for auxiliary components
|
||||
- channel-level relationships between actors and controlled circuits
|
||||
- PostgreSQL or multi-user operation
|
||||
|
||||
## Existing Model Audit
|
||||
|
||||
### Keep
|
||||
|
||||
- `Circuit` remains the outgoing-circuit aggregate.
|
||||
- `CircuitDeviceRow` remains a load assigned to a circuit and never receives
|
||||
its own protection device or equipment identifier.
|
||||
- Circuit-level load, cable and control fields remain circuit-owned.
|
||||
- Existing stable UUIDs, project revisions, snapshots and persistent Undo/Redo
|
||||
remain authoritative.
|
||||
- `CircuitSection` remains the migration starting point for a protected circuit
|
||||
group.
|
||||
- Grid projection remains separate from persisted domain structure.
|
||||
|
||||
### Change
|
||||
|
||||
- A `CircuitSection` gains an explicit category and group number and represents
|
||||
one protected circuit group.
|
||||
- Circuit protection changes from loosely related flat strings to an explicit
|
||||
one-to-one protection-device model.
|
||||
- Distribution-board components become independent BMK-bearing list entries.
|
||||
- Equipment-identifier uniqueness covers circuits and all distribution-board
|
||||
components in the complete circuit list.
|
||||
- Moving a circuit to another group of the same category atomically assigns the
|
||||
next identifier of the target group.
|
||||
- New distribution boards create three default groups rather than treating the
|
||||
optional unassigned compatibility section as a normal fourth group.
|
||||
|
||||
### Remove Eventually
|
||||
|
||||
- hard-coded assumptions that each category has exactly one section
|
||||
- numbering that only understands `prefix + integer`
|
||||
- free-text protection-device combinations that cannot be validated
|
||||
- `rcdAssignment` as a substitute for an explicit group relationship
|
||||
|
||||
Removal happens only after migrated state, snapshots, commands and the editor
|
||||
use the replacement model.
|
||||
|
||||
## Target Domain Structure
|
||||
|
||||
```text
|
||||
Project
|
||||
└── DistributionBoard
|
||||
└── CircuitList
|
||||
├── fixed header components
|
||||
│ ├── Main switch
|
||||
│ └── Surge protective device
|
||||
├── CircuitGroup 1..n
|
||||
│ ├── optional upstream protection component
|
||||
│ ├── optional group RCD component
|
||||
│ └── Circuit 0..n
|
||||
│ ├── ProtectionDevice exactly 1
|
||||
│ └── CircuitDeviceRow 0..n
|
||||
└── auxiliary components 0..n
|
||||
```
|
||||
|
||||
The hierarchy defines ownership and electrical grouping. It does not require
|
||||
every level to be visually indented in the table.
|
||||
|
||||
## Circuit Groups
|
||||
|
||||
`CircuitSection` evolves into the circuit-group entity. A group has:
|
||||
|
||||
- stable UUID
|
||||
- circuit-list ownership
|
||||
- category
|
||||
- positive group number
|
||||
- display name
|
||||
- sort order
|
||||
- optional upstream protection component
|
||||
- optional group RCD component
|
||||
- zero or more outgoing circuits
|
||||
|
||||
Supported categories:
|
||||
|
||||
- `lighting`
|
||||
- `single_phase`
|
||||
- `three_phase`
|
||||
|
||||
Each new distribution board creates exactly:
|
||||
|
||||
1. `Beleuchtung 1`
|
||||
2. `1-phasig 1`
|
||||
3. `3-phasig 1`
|
||||
|
||||
Additional groups are created manually. A new group receives the highest
|
||||
existing group number in its category plus one. Gaps are not filled
|
||||
automatically.
|
||||
|
||||
A group may have at most one upstream protection component and at most one
|
||||
group RCD. Both are optional. Every circuit in the group remains downstream of
|
||||
those group components until it is moved to another group.
|
||||
|
||||
## Distribution-Board Components
|
||||
|
||||
Every distribution-board component has:
|
||||
|
||||
- stable UUID
|
||||
- circuit-list ownership
|
||||
- unique equipment identifier
|
||||
- name
|
||||
- role
|
||||
- placement
|
||||
- sort order within its placement
|
||||
|
||||
Initial roles:
|
||||
|
||||
- `main_switch`
|
||||
- `surge_protective_device`
|
||||
- `group_upstream_protection`
|
||||
- `group_residual_current_protection`
|
||||
- `auxiliary`
|
||||
|
||||
Initial placement zones:
|
||||
|
||||
- `header`
|
||||
- `group`
|
||||
- `footer`
|
||||
|
||||
New distribution boards create exactly:
|
||||
|
||||
- `-Q0`, name `Hauptschalter`, role `main_switch`
|
||||
- `-FA`, name `Überspannungsableiter`, role
|
||||
`surge_protective_device`
|
||||
|
||||
These fixed components appear at the top and may initially have no further
|
||||
technical product data.
|
||||
|
||||
Auxiliary components initially require only:
|
||||
|
||||
- manually entered equipment identifier
|
||||
- name
|
||||
- sort order
|
||||
|
||||
Examples include KNX switching actuators, blind actuators, phase-monitoring
|
||||
modules, DALI gateways, relays and other installed board equipment. They appear
|
||||
after all circuit groups and can be reordered by drag-and-drop. Automatic BMK
|
||||
suggestions and channel-to-circuit relationships are deferred.
|
||||
|
||||
## Circuit Protection
|
||||
|
||||
Every newly created outgoing circuit owns exactly one protection device.
|
||||
`CircuitDeviceRow` does not own a protection device.
|
||||
|
||||
The circuit and its protection device are projected as one circuit row. The
|
||||
circuit equipment identifier is also the displayed identifier of its
|
||||
protection device and must not be stored twice.
|
||||
|
||||
Supported protection-device types:
|
||||
|
||||
- `D02`
|
||||
- `NH000`
|
||||
- `NH00`
|
||||
- `NH0`
|
||||
- `NH1`
|
||||
- `NH2`
|
||||
- `NH3`
|
||||
- `LS`
|
||||
- `FI`
|
||||
- `FI_LS`
|
||||
- `AFDD`
|
||||
|
||||
`D01` and `NH4` are intentionally excluded.
|
||||
|
||||
## Protection-Device Fields
|
||||
|
||||
All protection devices have:
|
||||
|
||||
- type
|
||||
- rated current in ampere
|
||||
|
||||
Type-dependent fields:
|
||||
|
||||
- D02 and NH:
|
||||
- fuse utilization category `gG` or `gR`
|
||||
- LS:
|
||||
- trip characteristic `B`, `C`, `D` or `Z`
|
||||
- FI:
|
||||
- RCD type `A`, `AC`, `B` or `B+`
|
||||
- rated residual current in milliampere
|
||||
- FI/LS:
|
||||
- trip characteristic `B`, `C`, `D` or `Z`
|
||||
- RCD type `A`, `AC`, `B` or `B+`
|
||||
- rated residual current in milliampere
|
||||
- AFDD:
|
||||
- trip characteristic `B`, `C`, `D` or `Z`
|
||||
- no RCD type
|
||||
- no rated residual current
|
||||
|
||||
Poles are intentionally not stored. The circuit-group category supplies the
|
||||
required phase context for the current scope.
|
||||
|
||||
## Allowed Ratings
|
||||
|
||||
### D02
|
||||
|
||||
`20, 25, 32, 35, 40, 50, 63 A`
|
||||
|
||||
### NH000 and NH00
|
||||
|
||||
`6, 10, 16, 20, 25, 32, 35, 40, 50, 63, 80, 100, 125, 160 A`
|
||||
|
||||
### NH0
|
||||
|
||||
`6, 10, 16, 20, 25, 32, 35, 40, 50, 63, 80, 100, 125, 160, 200, 224, 250 A`
|
||||
|
||||
### NH1
|
||||
|
||||
`16, 20, 25, 32, 35, 40, 50, 63, 80, 100, 125, 160, 200, 224, 250 A`
|
||||
|
||||
### NH2
|
||||
|
||||
`25, 32, 35, 40, 50, 63, 80, 100, 125, 160, 200, 224, 250, 300, 315, 355, 400 A`
|
||||
|
||||
### NH3
|
||||
|
||||
`50, 63, 80, 100, 125, 160, 200, 224, 250, 315, 355, 400, 500, 630, 800 A`
|
||||
|
||||
### LS, FI/LS and AFDD
|
||||
|
||||
`6, 10, 13, 16, 20, 25, 32, 40, 50, 63, 80, 100, 125 A`
|
||||
|
||||
### FI/RCD
|
||||
|
||||
Rated currents:
|
||||
|
||||
`16, 25, 40, 63, 80, 100, 125 A`
|
||||
|
||||
Rated residual currents:
|
||||
|
||||
`10, 30, 100, 300, 500 mA`
|
||||
|
||||
The device type determines which values and characteristics are valid. UI,
|
||||
request validation and domain validation use one shared catalog rather than
|
||||
duplicated free-text rules.
|
||||
|
||||
All supported devices that provide overcurrent protection may be selected as a
|
||||
group upstream protection device. A standalone FI belongs in the separate
|
||||
optional group-RCD role.
|
||||
|
||||
## Default Protection Devices
|
||||
|
||||
New circuits receive:
|
||||
|
||||
- lighting:
|
||||
- LS
|
||||
- 10 A
|
||||
- characteristic B
|
||||
- single-phase:
|
||||
- FI/LS
|
||||
- 16 A
|
||||
- characteristic B
|
||||
- RCD type A
|
||||
- 30 mA
|
||||
- three-phase:
|
||||
- FI/LS
|
||||
- 16 A
|
||||
- characteristic B
|
||||
- RCD type A
|
||||
- 30 mA
|
||||
|
||||
A newly added group RCD defaults to:
|
||||
|
||||
- FI
|
||||
- 40 A
|
||||
- RCD type A
|
||||
- 30 mA
|
||||
|
||||
An upstream protection component has no automatic default and is created only
|
||||
when the planner requests it.
|
||||
|
||||
## Equipment-Identifier Rules
|
||||
|
||||
The leading hyphen is part of every generated identifier.
|
||||
|
||||
Group 1 examples:
|
||||
|
||||
```text
|
||||
-1F1.0 upstream protection, lighting
|
||||
-1Q1.0 group RCD, lighting
|
||||
-1F1.1 first lighting circuit
|
||||
|
||||
-2F1.0 upstream protection, single-phase
|
||||
-2Q1.0 group RCD, single-phase
|
||||
-2F1.1 first single-phase circuit
|
||||
|
||||
-3F1.0 upstream protection, three-phase
|
||||
-3Q1.0 group RCD, three-phase
|
||||
-3F1.1 first three-phase circuit
|
||||
```
|
||||
|
||||
Category numbers:
|
||||
|
||||
- lighting: `1`
|
||||
- single-phase: `2`
|
||||
- three-phase: `3`
|
||||
|
||||
Function letters:
|
||||
|
||||
- overcurrent protection and outgoing circuit: `F`
|
||||
- group RCD: `Q`
|
||||
|
||||
The group number follows the function letter. `.0` is reserved for the group
|
||||
component. Outgoing-circuit suffixes start at `.1`.
|
||||
|
||||
Equipment identifiers must be unique across all circuits and components of the
|
||||
complete circuit list, including header and footer components.
|
||||
|
||||
Manual BMK edits must validate that same shared uniqueness boundary.
|
||||
|
||||
## Reorder, Move and Renumber Behavior
|
||||
|
||||
### Reorder Within One Group
|
||||
|
||||
Changing circuit order changes only `sortOrder`. It never changes an equipment
|
||||
identifier.
|
||||
|
||||
### Move to Another Group
|
||||
|
||||
A circuit may move only to another group of the same category.
|
||||
|
||||
The move:
|
||||
|
||||
1. finds the highest existing outgoing-circuit suffix in the target group
|
||||
2. assigns that suffix plus one
|
||||
3. moves the complete circuit, its one-to-one protection device and all device
|
||||
rows
|
||||
4. commits old and new group, position and identifier atomically
|
||||
|
||||
Gaps are not filled. Undo restores the original group, sort position and
|
||||
equipment identifier. Redo reapplies the same previously determined target
|
||||
identifier rather than calculating another one.
|
||||
|
||||
This automatic identifier change is specific to a cross-group move initiated
|
||||
by the user. A reorder inside one group never renumbers.
|
||||
|
||||
### Reorder Groups
|
||||
|
||||
Changing group display order changes only group `sortOrder`. Group numbers and
|
||||
all equipment identifiers remain unchanged.
|
||||
|
||||
### Explicitly Renumber Groups
|
||||
|
||||
Group renumbering is a separate explicit action. It:
|
||||
|
||||
- changes group numbers according to the requested mapping
|
||||
- preserves every outgoing circuit suffix
|
||||
- updates optional `.0` group-component identifiers
|
||||
- updates every affected circuit identifier
|
||||
- resolves swaps through collision-safe temporary identifiers
|
||||
- commits the complete mapping as one project revision
|
||||
|
||||
Undo restores the exact previous group numbers and identifiers.
|
||||
|
||||
## Delete Behavior
|
||||
|
||||
A group may be deleted even when populated, but only after an explicit warning
|
||||
that summarizes:
|
||||
|
||||
- optional upstream protection
|
||||
- optional group RCD
|
||||
- number of circuits
|
||||
- number of circuit device rows
|
||||
|
||||
Confirmation deletes the complete group subtree atomically. The inverse
|
||||
command stores the complete stable snapshots needed to restore all UUIDs,
|
||||
fields, links, protection devices, group relationships, identifiers and sort
|
||||
positions.
|
||||
|
||||
A stale or partially changed subtree must not be silently deleted or restored.
|
||||
|
||||
## UI Projection
|
||||
|
||||
The circuit-list editor projects three fixed zones:
|
||||
|
||||
1. header:
|
||||
- `-Q0 Hauptschalter`
|
||||
- `-FA Überspannungsableiter`
|
||||
2. groups:
|
||||
- group heading
|
||||
- optional upstream protection row
|
||||
- optional group RCD row
|
||||
- circuit rows and their optional expanded device rows
|
||||
3. footer:
|
||||
- auxiliary distribution-board components
|
||||
|
||||
Group indentation is optional presentation. Group ownership must remain clear
|
||||
through headings, separators or a dedicated group indication.
|
||||
|
||||
The grid remains a custom spreadsheet component:
|
||||
|
||||
- static text by default
|
||||
- edit mode only when invoked
|
||||
- group and auxiliary-component drag handles
|
||||
- clear valid and invalid drop indicators
|
||||
- German user-facing labels
|
||||
|
||||
Protection editing must show only fields valid for the selected device type.
|
||||
Changing the type resets or explicitly confirms removal of fields that the new
|
||||
type cannot use.
|
||||
|
||||
## History and Command Boundary
|
||||
|
||||
New project-scoped writes must use typed persistent commands and the existing
|
||||
shared project-command transaction boundary.
|
||||
|
||||
Required logical operations:
|
||||
|
||||
- insert/update/delete auxiliary component
|
||||
- reorder auxiliary components
|
||||
- insert/update/delete group protection component
|
||||
- insert/delete group
|
||||
- reorder groups
|
||||
- explicitly renumber groups
|
||||
- move circuit between same-category groups with deterministic BMK assignment
|
||||
- update circuit protection device
|
||||
|
||||
Creating a distribution board includes its fixed components, three default
|
||||
groups, circuit list and all stable UUIDs in one `distribution-board.insert`
|
||||
command.
|
||||
|
||||
Every command must:
|
||||
|
||||
- require `expectedRevision`
|
||||
- validate complete project/list/group ownership
|
||||
- validate shared BMK uniqueness inside the write transaction
|
||||
- contain deterministic forward and inverse data
|
||||
- commit the domain mutation, revision and history transition atomically
|
||||
- remain undoable and redoable after application restart
|
||||
|
||||
## Snapshot and Transfer Compatibility
|
||||
|
||||
The supported logical project snapshot and portable JSON transfer must include:
|
||||
|
||||
- group category and group number
|
||||
- fixed, group and auxiliary components
|
||||
- circuit protection-device state
|
||||
- all new component relationships and sort positions
|
||||
|
||||
Introducing the model requires a snapshot-schema version increase and explicit
|
||||
upgraders for supported older payloads.
|
||||
|
||||
Database migration rules:
|
||||
|
||||
- preserve all existing stable UUIDs
|
||||
- preserve existing circuit equipment identifiers during schema migration
|
||||
- map the existing lighting, single-phase and three-phase sections to group 1
|
||||
of the respective category
|
||||
- preserve an existing unassigned section only when required by existing data;
|
||||
it is not created for a new distribution board
|
||||
- preserve existing flat circuit protection values when creating the new
|
||||
one-to-one protection state
|
||||
- do not silently replace an existing protection selection with a new default
|
||||
- allow legacy identifiers to remain until an explicit, collision-safe
|
||||
conversion or renumber action is approved
|
||||
|
||||
New defaults apply to newly created circuits and boards, not as an implicit
|
||||
rewrite of existing planning data.
|
||||
|
||||
Historical persisted commands and snapshots that remain in the supported
|
||||
compatibility window must still deserialize and execute after the migration.
|
||||
|
||||
## Later Sizing and Warning Engine
|
||||
|
||||
The selected protection device is the planner-owned value. Later sizing logic
|
||||
will calculate a recommendation separately.
|
||||
|
||||
Target behavior:
|
||||
|
||||
```text
|
||||
stored selection
|
||||
-> calculation and validation
|
||||
-> valid: no warning
|
||||
-> invalid: colored warning plus recommended protection
|
||||
-> user explicitly accepts or rejects the recommendation
|
||||
```
|
||||
|
||||
The same pattern applies later to cable cross-section and length. Suggestions
|
||||
never silently overwrite selected values.
|
||||
|
||||
Dimensioning rules and additional inputs are defined in a separate future
|
||||
specification supplied by the planner.
|
||||
|
||||
## Delivery Phases
|
||||
|
||||
### A. Catalog and Pure Domain Rules
|
||||
|
||||
- introduce typed component roles, categories and protection-device types
|
||||
- centralize rating and characteristic catalogs
|
||||
- validate device-specific field combinations
|
||||
- define default circuit and group-RCD protection values
|
||||
- test numbering parsing and formatting independently from persistence
|
||||
|
||||
Acceptance:
|
||||
|
||||
- every agreed valid combination is accepted
|
||||
- invalid rating/type/field combinations are rejected
|
||||
- defaults produce the exact agreed values
|
||||
|
||||
### B. Persistence and Compatibility Model
|
||||
|
||||
- add group category and group number
|
||||
- add distribution-board component persistence
|
||||
- add one-to-one circuit protection persistence
|
||||
- implement shared BMK uniqueness
|
||||
- generate and inspect one additive migration
|
||||
- add snapshot/transfer schema upgrade
|
||||
- preserve existing identifiers and protection values
|
||||
|
||||
Acceptance:
|
||||
|
||||
- a current database migrates without data loss
|
||||
- an empty database creates the complete schema
|
||||
- old supported snapshots and transfers upgrade deterministically
|
||||
- BMK collisions across circuits and components are rejected
|
||||
|
||||
### C. Persistent Commands and Board Defaults
|
||||
|
||||
- extend `distribution-board.insert` with fixed components and three groups
|
||||
- implement component and group CRUD commands
|
||||
- implement group and footer reordering
|
||||
- add complete inverse snapshots and rollback tests
|
||||
|
||||
Acceptance:
|
||||
|
||||
- new boards contain the agreed fixed structure
|
||||
- every structural write survives reload and supports Undo/Redo
|
||||
- forced late failures leave no partial components or groups
|
||||
|
||||
### D. Group Numbering and Circuit Moves
|
||||
|
||||
- implement nested identifier generation
|
||||
- support same-category cross-group circuit moves
|
||||
- implement explicit collision-safe group renumbering
|
||||
- implement confirmed populated-group deletion
|
||||
|
||||
Acceptance:
|
||||
|
||||
- target identifiers use highest suffix plus one
|
||||
- reordering never renumbers
|
||||
- cross-category moves are rejected
|
||||
- group renumbering preserves circuit suffixes
|
||||
- delete, move and renumber Undo restore exact prior UUIDs and BMKs
|
||||
|
||||
### E. Editor Projection and Editing
|
||||
|
||||
- render fixed header components
|
||||
- render group components and circuit blocks
|
||||
- render sortable auxiliary footer components
|
||||
- add group management and destructive confirmations
|
||||
- add type-dependent protection editing
|
||||
- keep spreadsheet selection, keyboard and drag behavior coherent
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the visible order is header, groups, footer
|
||||
- users can create, configure, reorder and delete groups
|
||||
- users can configure circuit and group protection without invalid fields
|
||||
- device rows remain visually and technically subordinate to their circuit
|
||||
|
||||
### F. Documentation and Full Verification
|
||||
|
||||
- update current architecture, API and interaction documentation
|
||||
- update demo/sample data
|
||||
- run focused domain and transaction tests
|
||||
- run the complete required test, build and type-check suite
|
||||
- perform the agreed GUI test checklist
|
||||
|
||||
Acceptance:
|
||||
|
||||
- documentation distinguishes implemented behavior from later sizing
|
||||
- clean install and migrated database both work
|
||||
- snapshots, JSON transfer and Undo/Redo cover all new state
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
- Mixed legacy and grouped BMKs:
|
||||
preserve old identifiers and provide an explicit conversion path.
|
||||
- Cross-entity BMK collisions:
|
||||
enforce one transaction-level uniqueness boundary for the complete list.
|
||||
- Partial destructive writes:
|
||||
persist complete subtree commands through the shared transaction wrapper.
|
||||
- Bloated grid logic:
|
||||
add pure projection and ownership modules before React rendering changes.
|
||||
- Invalid protection combinations:
|
||||
use one shared typed catalog for UI, API and domain validation.
|
||||
- Silent planning changes:
|
||||
apply defaults only on creation and keep later recommendations explicit.
|
||||
- Snapshot incompatibility:
|
||||
version payloads and test every supported upgrade path.
|
||||
|
||||
## Open Implementation Decisions
|
||||
|
||||
These decisions may be resolved during the relevant delivery phase without
|
||||
changing the agreed domain behavior:
|
||||
|
||||
- exact relational implementation of the shared BMK ownership boundary
|
||||
- presentation of group ownership through indentation, headings or a column
|
||||
- filter behavior for structural component rows
|
||||
- explicit UI for converting retained legacy identifiers to grouped numbering
|
||||
- whether fixed header components become editable beyond name and BMK in this
|
||||
phase
|
||||
Reference in New Issue
Block a user