forked from jappel/leistungsbilanz-ts
Merge remote-tracking branch 'origin/main' into feature/cable-sizing
This commit is contained in:
commit
598003554a
136 changed files with 27182 additions and 1669 deletions
126
AGENTS.md
126
AGENTS.md
|
|
@ -164,6 +164,9 @@ Keyboard behavior:
|
|||
- Escape cancels
|
||||
- Tab / Shift+Tab navigates editable cells
|
||||
- Arrow keys navigate cells when not editing
|
||||
- Alt+ArrowDown on a GZF cell opens the AMEV table (`GzfPickerModal`); the
|
||||
selected GZF cell also shows a small table-icon button. The picked value is
|
||||
committed like a typed edit.
|
||||
|
||||
Support Ctrl+Plus and Ctrl+Shift+Plus for insertion.
|
||||
|
||||
|
|
@ -177,17 +180,37 @@ Column headers show the label (click to sort) with a funnel icon for the
|
|||
value filter; an active filter is highlighted and shows its value count.
|
||||
Header labels break only between words and put a trailing unit such as
|
||||
`[kW]` on a second line.
|
||||
The project overview uses the same rule: row actions are icon-only
|
||||
`IconButton`s, card-header and panel actions show icon plus text, navigation
|
||||
uses `IconLink` (`src/frontend/components/icon-link.tsx`). Page-header buttons
|
||||
stay Bootstrap `btn` with a lucide icon (`btn-with-icon`). List cards filter
|
||||
through a collapsible PM-style filter bar (`CollapsibleFilterPanel`,
|
||||
`MultiSelectDropdown`; logic in `src/frontend/utils/overview-filters.ts`): only
|
||||
the bar collapses, its state is kept per card in `localStorage`, a collapsed
|
||||
active filter shows "Filter aktiv".
|
||||
|
||||
## Bootstrap / Styling Rule
|
||||
|
||||
Bootstrap may be used for the general application UI, such as navigation, page layout, buttons, forms, cards, alerts and modals.
|
||||
|
||||
Cards follow the PM app look: 1px border all around, 16px radius and the
|
||||
soft shadow defined on `.card` in `globals.css` (own dark-mode value). The
|
||||
`.card` rule maps Bootstrap's `shadow-sm` to the same shadow; do not add other
|
||||
`shadow-*` classes or a colored top border to cards.
|
||||
|
||||
Do not use Bootstrap as the core table/grid framework for the circuit list editor.
|
||||
|
||||
The circuit list editor must remain a custom spreadsheet-like component with controlled cell selection, inline edit mode, row grouping, drag-and-drop indicators and keyboard behavior.
|
||||
|
||||
Avoid permanent Bootstrap form controls inside table cells. Table cells should show static text by default and switch to inputs only while editing.
|
||||
|
||||
## Browser Runtime
|
||||
|
||||
The web UI is also opened over plain HTTP from other machines in the LAN, which
|
||||
is not a secure context. Do not call secure-context-only browser APIs such as
|
||||
`crypto.randomUUID()` directly; create client-side ids with `createClientId()`
|
||||
from `src/frontend/utils/client-id.ts`.
|
||||
|
||||
## Drag-and-Drop Rules
|
||||
|
||||
Dragging from the circuit identifier / circuit handle moves the whole circuit.
|
||||
|
|
@ -261,8 +284,16 @@ not change the project revision or undo/redo stacks. Restoring a server-stored
|
|||
snapshot verifies its checksum and the current-state hash, replaces supported
|
||||
project data atomically and records a new `restore` revision with a complete
|
||||
inverse command. Restore can therefore be undone and redone after a restart.
|
||||
Current snapshot schema version 5 additionally stores the manual quantity share
|
||||
of every CircuitDeviceRow. Version 4 snapshots are upgraded with
|
||||
Current snapshot schema version 7 additionally stores the project buildings
|
||||
and `floors[].buildingId` (see `docs/building-structure.md`); versions 1 to 6
|
||||
are upgraded with no buildings and `buildingId = null`. Version 6 stores the
|
||||
distribution-board info fields `boardNumber`, `location`, `fedFrom` and
|
||||
`remark` and the project cover fields `siteAddress`, `workStage`,
|
||||
`projectLead` and `projectEditor`; all older supported versions are upgraded
|
||||
with `null` for these fields.
|
||||
Stored named and automatic snapshots of every supported version (1 to 7)
|
||||
remain restorable; they are upgraded while parsing. Version 5 stores
|
||||
the manual quantity share of every CircuitDeviceRow. Version 4 snapshots are upgraded with
|
||||
`manualQuantity = quantity`; they already contain the complete confirmed
|
||||
external-model source, import batches, room mappings and objects. Version 3
|
||||
snapshots are upgraded with an empty external-model state; version 2 snapshots
|
||||
|
|
@ -276,7 +307,7 @@ project graph.
|
|||
Project-wide Revit CSV configuration uses
|
||||
`external-csv-configuration.update`. Its complete expected/target snapshot is
|
||||
persisted through the shared project-command transaction, so create, update,
|
||||
delete, Undo and Redo are revision-safe. Snapshot schema 5, restore and portable
|
||||
delete, Undo and Redo are revision-safe. Snapshot schema 5-7, restore and portable
|
||||
project duplication preserve the configuration; duplication remaps its internal
|
||||
id and project link.
|
||||
The project page exposes the Revit CSV modal. It edits the complete
|
||||
|
|
@ -290,7 +321,7 @@ immutable import batches with original bytes plus the classified cell matrix,
|
|||
normalized source-room mappings and external objects unique by
|
||||
`(sourceId, ifcGuid)`. Source values, planning values and overrides are separate.
|
||||
The general external-model repository is read-only; runtime writes belong only
|
||||
to typed command adapters. Snapshot/restore and portable project transfer schema version 5
|
||||
to typed command adapters. Snapshot/restore and portable project transfer schema version 5/6
|
||||
capture the complete external state and remap every internal UUID and link while
|
||||
preserving IFCGUIDs, source values, original bytes and the classified matrix.
|
||||
Import batches additionally store the monotonic project CSV configuration
|
||||
|
|
@ -379,6 +410,10 @@ Project settings use the persistent `project.update-settings` command. Project
|
|||
metadata, the public-building classification, both voltage defaults and the
|
||||
enabled distribution-board supply types change in one revision and Undo/Redo
|
||||
restores them together; the project PUT route requires `expectedRevision`.
|
||||
Schema version 3 additionally carries the print cover fields `siteAddress`,
|
||||
`workStage`, `projectLead` and `projectEditor` (migration `0008`); version 2
|
||||
(without them) and baseline version 1 stay executable and keep the current
|
||||
cover values. The PUT route accepts the cover fields optionally.
|
||||
The public-building flag is the future sizing input for requiring halogen-free
|
||||
cables and lines. The system catalog is `AV`, `SV`, `EV`,
|
||||
`USV`, `MSR`, `SiBe`; at least one must be enabled and a type used by a board
|
||||
|
|
@ -433,6 +468,18 @@ the only supported circuit-protection source; no flat compatibility fields remai
|
|||
Distribution-board floor assignment and a project-enabled supply type use
|
||||
`distribution-board.update`; both values are snapshot/export fields and one
|
||||
persistent undo step.
|
||||
The same command (still schema version 1, additively extended) carries the
|
||||
board info-card fields `boardNumber`, `location`, `fedFrom` and `remark`
|
||||
(migration `0007`). They are nullable, trimmed planner values; the PUT route
|
||||
only includes submitted info fields in the command and its inverse. An empty
|
||||
board with info values is no longer an unchanged setup, so history deletion of
|
||||
it is rejected like a changed simultaneity factor. Populated-subtree commands
|
||||
stored before these fields existed are normalized to `null` values
|
||||
(`normalizeDistributionBoardSubtreeSnapshot`). `fedFrom` is deliberately free
|
||||
text: the logical link to the feeding board/circuit is an open design decision.
|
||||
These fields are intended to be prefillable from Revit parameters later, but
|
||||
only through the Phase 14 rules (preview, explicit confirmation, no silent
|
||||
overwrite).
|
||||
Floor and room setup uses persistent insert, update and delete commands with
|
||||
complete stable snapshots. Their inverses remove or restore only unchanged records and
|
||||
reject floors with assigned rooms/distribution boards or rooms referenced by
|
||||
|
|
@ -454,8 +501,49 @@ Required operations:
|
|||
- synchronization changes
|
||||
|
||||
|
||||
## Print View (Seitenansicht)
|
||||
|
||||
- Route `src/app/projects/[projectId]/print/page.tsx`, opened from the project
|
||||
page button "Seitenansicht". Read-only: it only uses existing GET endpoints.
|
||||
- Pure read model `src/frontend/print/print-document-model.ts` (tested in
|
||||
`tests/print-document-model.test.ts`); React sheets in
|
||||
`src/frontend/print/print-document.tsx`; styles scoped to `.print-view` in
|
||||
`src/frontend/print/print-document.css`.
|
||||
- Pages: cover (A4 portrait, tabular), board overview with structure and
|
||||
power sums, one plan per board (A4/A3 landscape) whose title block sits in
|
||||
`<thead>` so it repeats on printed pages. PDF export uses the browser print
|
||||
dialog; page size, margins and "Seite x von y" come from injected named
|
||||
`@page` rules (`lb-portrait`, `lb-landscape`).
|
||||
- The board hierarchy and "Σ inkl. unterlagert" in the overview are
|
||||
PRELIMINARY (text match of `fedFrom` against board number/name, plain sum,
|
||||
no upstream simultaneity factor). Replace this once the feed link is modeled.
|
||||
- Colors/fonts follow the kbp corporate design (`--pd-*` variables in
|
||||
`print-document.css`). Empty cover values are shown as
|
||||
"[ergänzen]"; the Planstände editor column shows the project's current
|
||||
`projectEditor` because snapshots do not record an editor.
|
||||
- The document logo and the office profile (office name/address on the
|
||||
cover) are global office branding: tables `document_branding_assets`
|
||||
(migration `0007`) and `document_branding_settings` (migration `0008`),
|
||||
endpoints `GET|PUT|DELETE /api/document-branding/logo`,
|
||||
`PUT /api/document-branding/office` and `GET /api/document-branding`.
|
||||
It is intentionally outside project revisions, snapshots and transfer.
|
||||
Uploads are PNG/JPEG/SVG up to 2 MB with a content signature check; the logo
|
||||
is served with `nosniff` and a restrictive CSP.
|
||||
|
||||
## Revit / CSV External Model Work
|
||||
|
||||
Status: further Revit work (editor assignment UI, follow-up import, return
|
||||
export) is deferred and will be tackled later. When it resumes, the exchange
|
||||
stays CSV-based and uses the CSV export/import of the Linear plugin in Revit.
|
||||
The internal Revit/CAD steering committee prefers this over manipulating the
|
||||
model directly through Dynamo. Do not start Dynamo, Revit API or JSON
|
||||
transport work. The Linear CSV layout is not yet known: check a sample export
|
||||
against the existing project CSV configuration before changing the parser.
|
||||
Earlier Dynamo considerations are archived in
|
||||
`docs/archive/revit-dynamo-leistungsbilanz-integration-konzept.md`; the
|
||||
removed diagnostic scripts remain reachable through the git tag
|
||||
`archive/dynamo-vorueberlegungen`.
|
||||
|
||||
When explicitly working on Phase 14, use
|
||||
`docs/spec/revit-csv-integration-requirements.md` as the detailed source of
|
||||
truth together with the current architecture documents.
|
||||
|
|
@ -549,6 +637,30 @@ Future sizing will need:
|
|||
|
||||
Users must be able to override sizing suggestions.
|
||||
|
||||
## Estimate Balance Module (Grobe Leistungsbilanz)
|
||||
|
||||
`src/estimate-balance` plus `src/shared/estimate-balance` is a separate module
|
||||
for the early-phase power balance by DIN 276 cost group (see
|
||||
`docs/estimate-balance.md`). Rules:
|
||||
|
||||
- It has its own tables (`estimate_*`) and never writes circuit, board or
|
||||
project-device data; it only reads device rows for the comparison.
|
||||
- Writes use the project command mechanism (`estimate-balance.insert/.update/
|
||||
.delete` with complete documents), so revision checks and Undo/Redo apply.
|
||||
- The calculation and comparison live in the import-free
|
||||
`src/shared/estimate-balance/estimate-balance.ts` and are shared by API and UI;
|
||||
displayed values use `roundEstimateValue`.
|
||||
- It is deliberately not part of named/automatic project snapshots or snapshot
|
||||
restore; those operations leave estimate balances unchanged. Portable project
|
||||
transfer format version 2 includes every estimate balance and remaps balance,
|
||||
group and row ids when duplicating a project. Version 1 transfers remain
|
||||
importable and contain no estimate balances.
|
||||
- UI: `/projects/:id/grobbilanz` (Stände) and `/grobbilanz/:balanceId` (editor,
|
||||
`src/frontend/estimate-balance/`). The editor autosaves the whole document
|
||||
debounced (one Undo step per save), keeps invalid raw input local, and on a
|
||||
409 reloads only if the balance itself changed; otherwise it re-saves with
|
||||
the new revision. `request()` throws `ApiRequestError` (status, code).
|
||||
|
||||
## Persistence and Migration Rules
|
||||
|
||||
- SQLite is the currently supported database.
|
||||
|
|
@ -566,11 +678,15 @@ Users must be able to override sizing suggestions.
|
|||
|
||||
## Current Deferred Work
|
||||
|
||||
- Revit/CSV/IFCGUID round-trip, except when Phase 14 is explicitly requested and
|
||||
- Revit/CSV/IFCGUID round-trip (deferred; later via Linear plugin CSV, never
|
||||
Dynamo), except when Phase 14 is explicitly requested and
|
||||
`docs/spec/revit-csv-integration-requirements.md` is being followed
|
||||
- full electrical sizing
|
||||
- multi-user/PostgreSQL operation
|
||||
- supported production deployment
|
||||
- logical feed link between distribution boards (`fedFrom` stays free text
|
||||
until the project owner decides whether it references a board, a feeding
|
||||
circuit or both) and the resulting hierarchical power summation
|
||||
|
||||
Do not implement these while working on an unrelated phase.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue