Commit graph

64 commits

Author SHA1 Message Date
Grovy311
287da1c0e7 cable-sizing: max length, socket minimum, manual-entry warning, SVG icon
- Cross-section rows now include maxLengthForVoltageDropM, the inverse of
  the voltage-drop formula: the longest single run that stays within the
  requested max voltage drop at the given load/cosPhi/phase. Shown as a KPI
  and in the ok-summary alert.
- Added PRACTICAL_MINIMUM_CROSS_SECTION_MM2 (2.5 mm² for single_phase
  circuits) - a planning convention already named in this projects own
  docs/spec/06-future-sizing-and-calculations.md, not a thermal/
  voltage-drop requirement. Only ever raises a calculated recommendation,
  never lowers one that already needs more. circuitCategory is looked up
  from the circuits section and passed through from the editor.
- The manual cross-section field now warns (not blocks - manual override
  must stay possible per the same spec doc) when the typed value is not a
  standard cross-section, is smaller than the last calculation, or is
  below the practical minimum for single_phase circuits.
- Modal title now includes the circuit displayName next to the equipment
  identifier.
- Replaced the calculator emoji trigger icon with an inline SVG - the emoji
  did not render in at least one tested environment (missing font glyph),
  SVG has no such dependency.
2026-09-25 19:31:36 +02:00
Grovy311
68d2bad6e8 cable-sizing: size for the protective device, not just the load; manual entry; icon position
- calculateCableSizing now selects cross-section against
  designCurrentA = max(operatingCurrentA, existingProtectionRatedCurrentA)
  instead of the load current alone. A breaker only trips at its own rated
  current (In), so a cable sized for the actual load could overheat under
  sustained current below that threshold - the standard In <= Iz rule.
  Voltage-drop calculation still uses the real operating current, only the
  capacity check changed. Alerts and the ok-summary now name the breaker as
  the limiting factor when it is one.
- Added a manual cable type/cross-section entry in the modal itself:
  running a calculation pre-fills these fields as a suggestion, but they
  are the single field that actually gets applied, and stay editable -
  this restores the direct manual-entry capability the modal replaced when
  it took over the cableSummary/cableCrossSection cell click.
- Fixed calculator icon position from a trailing ::after (inconsistent
  position depending on cell text length, easy to miss on empty cells) to
  a fixed-position ::before, so it is always in the same place regardless
  of whether cable data is already filled in.
- No new display for the existing protection device - it already has its
  own Schutz column in this app.
2026-09-25 19:31:35 +02:00
Grovy311
961c96f7a1 cable-sizing: trigger on both cable columns, calculator icon
Trigger now matches cableSummary OR cableCrossSection so it still
shows up regardless of which cable-related column a user has visible
(column visibility is a per-browser preference in this app, not fixed
- see docs/cable-sizing-module.md coupling note). Icon changed to a
calculator glyph.
2026-09-25 19:31:35 +02:00
Grovy311
b6e50539ad cable-sizing: fix trigger column and add visible affordance
The trigger was wired to the cableCrossSection column, which is not in
the default visible column set - the actually visible "Kabel" column
is cableSummary (a computed cableType/cableCrossSection/cableLength
join). Editing cableSummary already maps to the remark field rather
than the underlying cable data (see buildCircuitEditPatch), so this
column was effectively a read-only display already; retargeting the
trigger there loses no existing manual-edit capability. Also adds
.cell-cable-sizing-trigger styling (mirrors .cell-protection-trigger)
so the trigger is visually discoverable, which the initial version was
missing entirely.
2026-09-25 19:31:35 +02:00
906aa751c7 Run the Docker stack on built output instead of dev servers
compose.yaml overrode the image's own entrypoint to start "tsx watch" and
"next dev" with CHOKIDAR_USEPOLLING and WATCHPACK_POLLING enabled. The
built dist/ and .next from the image were never used, and the polling
watchers kept both containers busy around the clock whether or not
anyone used the application.

Split the two use cases: compose.yaml now runs node dist/server/index.js
and next start with no source mounts and no watchers, and the watching
setup moves to compose.dev.yaml.

next build writes the rewrite destinations from next.config.mjs into
.next/routes-manifest.json, so next start cannot pick up API_INTERNAL_URL
at runtime the way next dev does. Pass it as a build argument.

Give the web container its own probe. The healthcheck hit "/", which
redirects to "/projects", and fetch follows redirects, so every probe
rendered two pages every five seconds. "/health" could not serve as the
probe because next.config.mjs rewrites it to the API. Add "/web-health"
as a route handler, exclude it from the proxy matcher, and relax both
intervals to 30s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 18:25:06 +02:00
a17e2e3f4b Merge remote-tracking branch 'origin/feature/amev-picker-and-collapsible-sidebar' 2026-08-06 22:01:54 +02:00
64ccd1f829 Add dark mode toggle in the sidebar
Adds a persistent dark/light theme toggle (localStorage +
data-bs-theme on <html>) so it applies globally, including the
circuit editor route which has no visible sidebar. An inline
beforeInteractive script sets the theme before hydration to avoid a
flash of the wrong theme.

Bootstrap components pick up data-bs-theme automatically; the custom
circuit-grid CSS previously used ~150 hardcoded hex colors, all
converted to semantic tokens in globals.css with light/dark values.

Verified with a headless-browser pass across the project list, project
detail page, circuit editor, project-device drawer and a settings
modal in both themes; no console errors.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 21:56:21 +02:00
b45dc5002d Fix code-review findings across domain, persistence, server and frontend
Full-codebase review turned up five real correctness/security bugs and
a dozen smaller inconsistencies; all are fixed here with matching test
coverage:

- BMK uniqueness silently allowed German-umlaut duplicates ("Ä1" vs
  "ä1") because the DB's normalized index only folds ASCII case. Added
  a shared Unicode-aware pre-check used by every circuit/component
  insert and rename path (one of which had no pre-check at all).
- CircuitDeviceRow.simultaneityFactor had no upper bound at the row
  level (command model and snapshot/restore schema), unlike every
  sibling entity, letting a bad value silently corrupt power totals.
- Grid cell editing silently misread German thousands-separator input
  ("1.500" parsed as 1.5); "." is now rejected outright with a clear
  message instead of guessing.
- The editor's shared command runner (runCommand/applyHistory) had no
  re-entrancy guard, so a double click/drop could fire the same
  command twice and race a BMK collision or revision conflict. Added a
  synchronous ref guard plus isSaving on the buttons that lacked it.
- GET .../next-identifier leaked circuit-numbering state for sections
  in other projects (no ownership check, 400 instead of 404). Moved
  under /projects/:projectId and scoped it.

Also: added the missing circuits.section_id / circuit_device_rows.
circuit_id indexes (migration 0006), gave FormModal a focus trap /
Escape-to-close / focus restore and rebuilt ProjectSettingsModal on
top of it instead of duplicated markup, removed dead code (3 orphaned
domain model files, an unused persistence helper, a wrapper only used
by its own test), pointed the project page at GET /projects/:id
instead of listing+filtering client-side, closed the gap between the
documented 18 MB CSV limit and the ~17.17 MiB actually enforced, added
missing upper bounds on several free-text fields, filled in nine
missing German labels in the revision timeline, replaced a
key-order-fragile JSON.stringify equality check with a real field
comparison, made an implicit sort-order assumption in three
renumbering helpers explicit, cleared the sidebar's target selection
when it no longer resolves after a tree reload, and fixed
updateGlobalDevice to check-then-write instead of write-then-check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 21:31:16 +02:00
Grovy311
9bd22dfcb7 Add AMEV Gleichzeitigkeitsfaktor-Auswähler und einklappbare Seitenleiste
- Gzf-Picker-Modal mit AMEV-Tabelle 3 (Planungshilfe für elektrische
  Leistungsbilanzen) im Projektgerät-Modal und im globalen Geräteformular
- Docker-Deploy-Tooling (docker-start.sh, run-migrations.js) für den
  produktiven Container
- Seitenleiste ist jetzt einklappbar (Icon-only, Zustand in localStorage)
2026-08-03 17:07:14 +02:00
bc2bc7ece5 Add Revit catalog creation flow 2026-08-02 18:08:18 +02:00
a9d6301753 Add Revit CSV project dialog 2026-08-02 16:59:18 +02:00
facf788ce8 Remove circuit structure preview 2026-07-31 14:52:37 +02:00
1eed19ef6b Add editable project floors and rooms 2026-07-31 14:46:06 +02:00
5bee3cb103 Add distribution board copy and delete controls 2026-07-31 12:03:52 +02:00
bd8dd09f79 Open circuit protection from grid cell 2026-07-31 10:02:11 +02:00
f4bfef9071 Merge branch 'main' into feature/multiplesections 2026-07-31 09:00:39 +02:00
756e307bd8 Manage distribution board components 2026-07-31 07:29:25 +02:00
31589875b5 Render protected circuit structure 2026-07-31 07:22:26 +02:00
Grovy311
704f4df2a8 Apply Petrol/Volt/Kupfer design system and project sidebar
Bring the Econsult-family design tokens (see design-system-econsult.md)
into leistungsbilanz-ts and add a persistent sidebar for the projects
area, mirroring elt-planung-suite / Einsatz-Orga. The sidebar lists all
projects and, inside a project, jumps to its sections; the tree editor
stays sidebar-free since it needs the full width. The projects overview
page is decluttered to a single stacked column (create/import/global
devices) now that the project list lives in the sidebar.
2026-07-30 17:40:11 +02:00
9ea081179d Add distribution power summaries 2026-07-29 19:02:18 +02:00
602ae6da0b Compact circuit grid columns 2026-07-29 11:12:24 +02:00
096ba8aa1c Standardize phase type labels 2026-07-29 10:46:00 +02:00
084103bf54 Derive device voltages from project settings 2026-07-29 09:53:58 +02:00
b1a11397b3 Add configurable distribution supply types 2026-07-29 09:31:20 +02:00
194bc9c0b1 Add project overview import 2026-07-29 08:36:57 +02:00
0180f768ac Improve editor totals and formatting 2026-07-29 08:26:03 +02:00
edf245a21c Use full-width editor device drawer 2026-07-28 20:43:08 +02:00
feec814dc5 Add project transfer controls 2026-07-28 19:36:26 +02:00
5fa2a701dc Streamline project management UI 2026-07-28 18:30:44 +02:00
d77cfbeb49 Add versioned project settings modal 2026-07-28 18:16:22 +02:00
ac465a1cc0 Persist project locations 2026-07-26 10:56:29 +02:00
1cf26a932e Persist distribution board setup 2026-07-25 23:41:27 +02:00
59d442593f Expose project-wide history controls 2026-07-25 23:16:46 +02:00
b2763f72d5 Persist project settings updates 2026-07-25 23:08:07 +02:00
d00ae30bda Expose project version history 2026-07-25 22:56:51 +02:00
3977a6e6e1 Persist project device synchronization 2026-07-24 11:47:03 +02:00
e930cb75b8 Route project devices through history 2026-07-24 10:57:50 +02:00
04c299e3f2 Remove legacy consumer UI 2026-07-23 19:23:53 +02:00
e4fd7e0df6 Translate remaining frontend 2026-07-22 23:25:53 +02:00
7257deacdc Redesign and translate grid controls 2026-07-22 23:19:21 +02:00
fafccca50f Redesign grid filter menu 2026-07-22 23:04:03 +02:00
d1615bcfee Clarify active grid filters 2026-07-22 22:57:25 +02:00
d0b8239085 Contain circuit editor scrolling 2026-07-22 22:44:49 +02:00
b3a7ff79da Confirm cross-section device moves 2026-07-22 20:31:55 +02:00
f8802fecdb Harden grid deletion and BMK validation 2026-07-22 20:27:01 +02:00
b2f5ce77a5 Make device sync atomic and undoable 2026-07-22 19:47:10 +02:00
6f8b292b6b Add explicit project device sync 2026-07-22 19:38:21 +02:00
9d07ed9856 Align project devices with circuit model 2026-07-22 19:31:08 +02:00
689cfd3c65 Route boards to circuit-first editor 2026-07-22 19:23:30 +02:00
b1e19a88d5 Started multiline manipulations 2026-05-05 21:20:09 +02:00