Commit graph

255 commits

Author SHA1 Message Date
0a37783635 Improve feeder circuit creation workflow 2026-09-28 22:15:12 +02:00
9165b8238c Compact single-board feeder circuit rows 2026-09-28 22:14:39 +02:00
ade21fe386 Create feeder circuits while linking boards 2026-09-28 22:14:30 +02:00
552362bad1 Merge Issue #3 logical distribution board feeds 2026-09-28 20:58:35 +02:00
b74b495fab Update print view and documentation for logical feeds 2026-09-28 20:57:58 +02:00
042a050876 Show logical feeder loads in project and circuit views 2026-09-27 22:37:04 +02:00
dfeb0e3cb6 Add recursive distribution board load projection 2026-09-27 22:31:56 +02:00
855a04e655 Protect referenced feeder structures from deletion 2026-09-27 22:25:47 +02:00
b893c72534 Add logical distribution board feed links 2026-09-27 22:21:58 +02:00
b50c00c0ac Bring documentation in line with integrated features
List the building structure, room areas, rough power balance and cable
sizing in the README and documentation map, add an architecture section
for the rough power balance, correct stale snapshot schema references and
record the integrated contributor features in the backlog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:36:43 +02:00
dce31ee143 Add optional room areas 2026-09-27 20:00:03 +02:00
a6500e2b26 Add estimate row project device handoff 2026-09-27 18:36:48 +02:00
8b1923e8ec Merge optional cable sizing module 2026-09-27 17:06:08 +02:00
5cbbd3a84a Align cable sizing with DIN VDE 0298-4 2026-09-27 17:01:23 +02:00
598003554a Merge remote-tracking branch 'origin/main' into feature/cable-sizing 2026-09-27 16:54:12 +02:00
060a203425 Merge rough estimate balance 2026-09-27 12:38:32 +02:00
573487666c Integrate rough estimate balance 2026-09-27 12:37:59 +02:00
57a62b7e4a Record the confirmed building structure decisions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 11:17:24 +02:00
b9462e61c5 Defer Revit work and remove Dynamo scripts
Further Revit exchange will use the CSV export/import of the Linear
plugin instead of Dynamo, as preferred by the internal Revit/CAD
steering committee. Mark the Revit documentation as deferred and remove
the Dynamo diagnostic scripts, which stay reachable through the tag
archive/dynamo-vorueberlegungen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:51:13 +02:00
92da72bf14 Archive the Revit Dynamo integration concept
Keep the earlier Dynamo/API considerations as historical reference only.
Further Revit exchange will use CSV via the Linear plugin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:50:23 +02:00
868f48e7ac Integrate project building structure 2026-09-27 10:45:10 +02:00
4643c8d11a Integrate print view and document branding 2026-09-27 10:32:07 +02:00
3ffa50be4c Integrate consistent card styling
Document the shared card appearance. Validation: 431 tests, API/web builds, scripts and Next typechecks passed. GUI retest waived by the user.
2026-09-26 21:18:53 +02:00
2e223be8b4 Integrate project overview filters and icon actions
Document filter combinations, reset and browser persistence. Keep the search hint applicable before board information fields are introduced.

Validation: 20 focused tests, 431 total tests, API/web builds, scripts and Next typechecks, and diff checks passed. GUI retest skipped as authorized based on the colleague's prior testing.
2026-09-26 21:16:48 +02:00
641513c2ef Integrate circuit list navigation and AMEV cell picker
Preserve the ID fallback and compact editor controls. Add dialog keyboard focus, Tab containment and Escape handling; document navigation and picker behavior.

Validation: 418 tests, API/web builds, scripts and Next typechecks, isolated AMEV dialog checks and diff checks passed. Full GUI retest waived by the user based on the colleague's prior testing; the keyboard follow-up was checked in isolation.
2026-09-26 21:14:20 +02:00
203757b92c Integrate compact editor actions and fix header units 2026-09-26 21:07:36 +02:00
0a17da2b8e Align runtime and editor documentation with current implementation 2026-09-26 21:02:48 +02:00
Grovy311
7b2419b347 Polish the printed rough power balance
The printed page kept the dark app background in the page margins, the
consumer column wrapped while the empty remark column took the space, an
empty "bearbeitet von" label was printed, and numbers were printed as
typed (11200). Print margins are white now, the consumer column is wider,
empty editors are omitted and numbers print with thousands separators
(11.200) like the template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:04:54 +02:00
Grovy311
b7811085a3 Keep print margins white in dark mode
The dark theme sets color-scheme: dark on the root element; Chrome then
paints the page margins of printed pages dark, even with a white
background. The print view forces the light scheme and a white root
background while printing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:04:54 +02:00
Grovy311
72189d23a5 Offer supply suggestions, drop the circuit column, center cells
The Versorgung field suggests ELT and MSR (plus values already used in
the balance) through a datalist and still accepts free text. The circuit
number column is not needed in early design phases; it is removed from
the data model, the regenerated migration 0010, the editor and the
print. All cells are centered except "Verbraucher / Flächen", group
titles and total labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:56:53 +02:00
Grovy311
e06c7d91e2 Print the rough power balance in the kbp design
The print of the rough power balance was plain grey. It now follows the
kbp design of the print view: a title block with office logo, stand,
project, number, owner, address, work stage, date, editor and office;
header row in kbp blue, cost-group rows tinted with a lilac rule, bold
subtotals, the total including reserve as a blue band, colored
deviations in the comparison, Arial, exact print colors, and a footer
with project, stand and "Seite x von y" on every page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:48:37 +02:00
Grovy311
37a70b6b36 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>
2026-09-26 17:39:28 +02:00
Grovy311
80dbc73230 Merge fix/client-id-insecure-context for client-side ids 2026-09-26 14:22:35 +02:00
Grovy311
68b9ee850b Search board info fields and confirm project device deletion
The distribution-board search also matches board number and location as
soon as the boards carry them (distribution-board info card of
feature/print-view); the fields are optional in the filter, so the branch
works with and without them. Deleting a project device now asks for
confirmation like the other delete actions, since the row action is a
small trash icon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:16:22 +02:00
Grovy311
acff38afb8 Show a printer icon on the print view button
The "Seitenansicht" link in the project header had text only, while the
other header buttons show an icon plus text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:15:54 +02:00
Grovy311
837b29c7c5 Add icon actions and collapsible filters to the project overview
The overview now uses the same icon buttons as the circuit list editor:
row actions are icon-only IconButtons (Pencil, Link2, Library, Trash2),
card-header and panel actions show icon plus text, and the circuit-list
link uses the new IconLink. The version history uses Undo2/Redo2, a
chevron toggle and a RotateCcw restore action. Page-header buttons stay
Bootstrap buttons with a lucide icon so the upcoming "Seitenansicht"
button of feature/print-view merges without conflicts and matches them.

The Verteilungen and Projektgeräte cards get a PM-style filter bar:
search plus MultiSelectDropdown (checkbox list with "Alle", closes on
outside click and Escape) and "Zurücksetzen" while a filter is active.
Only the bar collapses; the state is kept per card in localStorage and a
collapsed active filter shows "Filter aktiv". The header row shows
"x von y", and an empty-state row explains when filters hide everything.
The filter logic is a pure module (overview-filters.ts) with node tests;
selections that are no longer offered (deleted floor) are ignored.

IconButton now imports React explicitly like the other components that
are rendered in node tests with the classic JSX runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:01:31 +02:00
Grovy311
5f4d9bf789 Show the sidebar on every page except the print view
AppShell showed the sidebar only on the project list and overview, so it
disappeared on the building structure page and in the circuit list
editor. It is collapsible, so it now stays on every page. Only the print
view, a stand-alone document opened in its own tab and printed as PDF,
keeps the full width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:00:20 +02:00
Grovy311
ead01fe5bd Keep card markup and map shadow-sm to the card shadow
Removing the shadow-sm classes touched the page markup of the project
overview, which other branches change as well. The card rule now sets
Bootstrap's --bs-box-shadow-sm to the card shadow instead, so cards with
and without shadow-sm look the same and the pages stay as they are on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:53:24 +02:00
Grovy311
cd89c4a499 Add buildings above floors and a building structure page
Projects with several buildings could not be structured: floors and rooms
hung directly off the project. Floors can now belong to a building
(migration 0009: table buildings, nullable floors.building_id). Rooms and
distribution boards keep their floor; their building follows from it.
Existing floors stay without a building.

Buildings use the location-structure command store with
project-building.insert/.update/.delete, inverses and persistent Undo/Redo;
deleting a building with assigned floors is rejected. Floor commands carry
buildingId since command version 2. Version 1 floor commands from existing
history predate buildings and are upgraded with buildingId = null before
they are executed and persisted, so forward and inverse keep one version.

Project snapshot schema 7 stores buildings and floor.buildingId; versions
1-6 are upgraded without buildings. Restore and portable transfer include
buildings, and the transfer remaps building ids.

Buildings, floors and rooms move from the project overview to their own
page /projects/:id/struktur with three columns (Gebäude -> Etagen -> Räume)
that filter each other, and a sidebar entry. Floor selects in the board and
room dialogs are grouped by building. Unchanged dialogs close without a
command. Details in docs/building-structure.md; see issue #6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:52:34 +02:00
Grovy311
51cbab1750 Give cards the surface look of the PM app
Cards had a 3px petrol bar on the top edge, and Bootstrap's shadow-sm
class overrode their own shadow with !important. They now use the PM app
surface: a 1px border all around, a 16px radius and a soft diffuse shadow
with a faint inner highlight, with a stronger shadow and a weaker highlight
in dark mode. The shadow-sm classes are removed from the cards so the
shared rule applies. Menus, drawers and dialogs keep their shadows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:20:09 +02:00
Grovy311
79fcb75ffb Create client ids without crypto.randomUUID
crypto.randomUUID() is only defined in secure contexts (HTTPS or
localhost). Opened over plain HTTP from another machine in the LAN, the
circuit list editor failed with "crypto.randomUUID is not a function"
whenever it created a circuit, device row, circuit group or distribution
board component, including typing into the -frei- row.

createClientId() uses crypto.randomUUID() where available and otherwise
builds an RFC 4122 version 4 UUID from crypto.getRandomValues(), which
works in every context. AGENTS.md notes the rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:01:43 +02:00
Grovy311
ced4917a86 Offer the AMEV simultaneity-factor table in the circuit list
The selected GZF cell shows a small table-icon button, and Alt+ArrowDown opens
the same picker from the selected or edited cell; Escape closes it. The
shared GzfPickerModal is reused. The picked mean value is committed through
commitEdit with an explicit target cell, so it is a regular undoable edit on
device rows, compact circuits, reserve circuits and the -frei- row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 11:52:38 +02:00
Grovy311
db4a6c3a2e Add back arrow to the circuit list page
The arrow next to the "Stromkreisliste" heading returns to the project's
distribution board overview.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 11:38:16 +02:00
Grovy311
49488f4e1b Add optional cable-sizing module
Per-circuit cross-section recommendation as a separate module attached to
the circuit list. It never writes project data itself: "Übernehmen" applies
cable type, cross-section and length through the regular circuit.update
command, so revisions and Undo/Redo stay intact.

- Pure domain module (src/cable-sizing) with IEC 60364-5-52:2009 Annex B
  tables for PVC and XLPE, copper and aluminium, methods A1, A2, B1, B2, C,
  D1, D2 and E. Every value was cross-checked against public reproductions;
  where sources differ the lower value is used (docs/cable-sizing-module.md).
- Temperature and grouping between table values round to the safer value;
  values outside the tables return no result instead of a factor of 1.
  Ground methods use B.52.18 (D2) and B.52.19 A (D1).
- Overload protection: circuit-breakers In <= Iz; gG fuses additionally
  I2 <= 1.45 Iz with I2 = 1.6/1.9/2.1 In.
- Inputs prefilled from the circuit: power, phase (group or device rows),
  project voltage, power-weighted cos phi, length and protective device.
- Opened from a "Leitungsberechnung" button in the row actions, not from a
  grid cell, so cable cells keep the spreadsheet behavior.
- Stateless API under /api/cable-sizing; no database table or migration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 11:16:18 +02:00
Grovy311
7692699ee2 Add print cover fields and office profile
- Project settings gain siteAddress, workStage, projectLead and
  projectEditor (project.update-settings schema version 3, migration 0009);
  versions 2 and 1 stay executable and keep the current cover values.
  Snapshot schema 6 carries the fields; older versions upgrade with null.
- Global office profile (office name/address) next to the document logo:
  table document_branding_settings, PUT /api/document-branding/office,
  editable from the print view toolbar.
- Cover page reads all fields; empty values show the "[ergänzen]" marker.
  The Planstände editor column shows the project editor.
- Shared logo constants moved to a dependency-free module so the Next.js
  bundler can import them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:39:18 +02:00
Grovy311
4779e4a1a7 Add print view, board info card and document logo upload
- Seitenansicht (/projects/:projectId/print): tabular cover page, board
  overview with supply structure and power sums, one plan per board with a
  repeating title block; PDF via the browser print dialog with named @page
  rules (A4 portrait cover, A4/A3 landscape plans, page x of y).
- Distribution-board info card (board number, location, fed-from, remark)
  in the board edit dialog, persisted through the additively extended
  distribution-board.update command (migration 0008, snapshot schema 6,
  legacy subtree commands normalized).
- Global document logo upload (PNG/JPEG/SVG, max 2 MB) outside project
  revisions and snapshots.
- fed-from stays free text; the overview hierarchy and cumulated sums are
  preliminary until the feed link is modeled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:38:59 +02:00
Grovy311
d95f0bf5c0 Compact circuit list column headers with filter icons
- Replace the "Filtern" text buttons with a funnel icon next to the column
  label; an active filter is highlighted and shows its value count.
- Header labels no longer break inside words (e.g. "Bemerkung"); hyphens
  are non-breaking and a trailing unit moves to its own line, so all
  headers share one height.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:30:15 +02:00
Grovy311
e394ff93f4 Use icon buttons in the circuit list editor
- New IconButton/IconButtonSeparator component based on lucide-react.
- Toolbar: icon plus text, grouped into history, view and insert blocks.
- Group headers: compact icons for add circuit, upstream fuse (VS), group
  RCD (FI), edit, move up/down, renumber and delete; the header no longer
  overflows the grid.
- Rows: add device, delete circuit (trash) and delete device (ListX).
- The previous German labels remain accessible names and tooltips;
  destructive actions highlight in the danger color.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:23:36 +02:00
2e3e85a8e5 Harden the container runtime and shut down cleanly
Running the stack on built output stopped the idle CPU load, but the
remaining findings from the deployment report were still open.

The Dockerfile is now multi-stage. The prod target runs on node:24-slim as
the "node" user instead of root and carries only its runtime dependencies;
"npm prune --omit=dev" drops tsx, drizzle-kit and typescript. The migration
scripts need drizzle-orm and better-sqlite3, both regular dependencies, so
they keep working. The dev target keeps devDependencies for compose.dev.yaml.

Both compose files get a mem_limit. The server stack also sets memswap_limit
to the same value, so a leak lets the OOM killer replace the container
instead of pushing the host into swap. The Express API is no longer
published on the host: it has no authentication and is reached through the
Next.js rewrite. Development ports are bound to the loopback interface.
Services drop all capabilities and run with no-new-privileges.

SIGTERM and SIGINT now close the HTTP server and the SQLite handle and exit,
instead of only logging the signal and waiting for the container's SIGKILL
ten seconds later. server.closeIdleConnections() releases the keep-alive
sockets the Next.js server holds, which would otherwise keep server.close()
pending for the whole grace period. The compose start commands exec into
node, because otherwise sh stays the foreground process and the signal never
reaches it.

Delete scripts/docker-start.sh rather than fixing its unsupervised
background API: both compose stacks set their own command, so the
single-container entrypoint has no caller left. Also remove drizzle.config.js
(a stray tsc artifact drizzle-kit never reads) and the pre-Next index.html
and styles.css.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:04:34 +02:00
204499d7e4 Add Revit Dynamo diagnostic scripts 2026-08-23 23:13:35 +02:00