specs for rewrite

This commit is contained in:
2026-05-03 19:15:46 +02:00
parent 60771b5929
commit 49190c5d7e
10 changed files with 1534 additions and 359 deletions
+144 -359
View File
@@ -1,452 +1,237 @@
# AGENTS.md
## Project Context
This repository contains a web application for creating, editing, calculating, and documenting electrical power balances for building-services electrical planning.
The application is intended for small internal use by approximately 23 concurrent users. It should support practical planning workflows, not an over-engineered enterprise architecture.
## Project Goal
The domain is electrical building planning, especially German TGA / ELT planning. Important concepts include:
Build a spreadsheet-like electrical distribution board circuit list editor.
- Power balance / Leistungsbilanz
- Distribution boards / Verteilungen
- Electrical consumers / Verbraucher
- Installed power / installierte Leistung
- Demand factor / Gleichzeitigkeitsfaktor
- Calculated demand power / berechnete Leistung
- Voltage, current, phases, cos phi
- Device groups and individual devices
- Project-based calculation and documentation
The editor is used for electrical planning in execution design.
Use English identifiers in code, database fields, interfaces, classes, and file names. German wording is allowed and preferred in UI labels, reports, and domain-facing text.
It must support circuits, device rows, project devices, drag-and-drop restructuring, stable equipment identifiers and later electrical sizing logic.
## Main Goal
## Critical Domain Rules
Build a maintainable web application that allows users to:
- A circuit is not the same thing as one device row.
- A circuit contains zero, one or multiple device rows.
- A single-device circuit may be displayed as one compact row.
- A multi-device circuit must be displayed with a circuit summary row and indented device rows.
- Equipment identifiers belong to circuits, not to every device row.
- Device rows inside a circuit do not have their own equipment identifiers.
- Protection and cable data belong to the circuit, not to individual devices.
- Device-level values include quantity, power per unit, simultaneity factor, cosPhi, room data, cost group and category.
- Circuit total power is the sum of all device rows in that circuit.
- Existing equipment identifiers must never be changed automatically.
- Renumbering is always an explicit user action.
- Create and manage projects
- Define electrical distributions or calculation areas
- Add individual electrical consumers
- Add grouped consumers with quantity
- Assign technical parameters to consumers
- Calculate installed and demand power
- Structure consumers by project, distribution, area, system, or category
- Export or print a usable power-balance report later
## Existing Codebase Rule
The application should be practical for electrical planners and should keep the data model understandable.
There is an existing codebase.
## Technology Direction
Do not blindly continue old assumptions.
Preferred stack:
Do not blindly delete the codebase.
- TypeScript
- Node.js backend
- SQLite database for the initial version
- ORM is allowed and preferred if it improves type safety and maintainability
- Drizzle ORM is preferred for a more explicit SQL-oriented approach
- Prisma is acceptable if the project already uses it
- Frontend may be React-based if a UI is implemented
- Docker support for local development is desired
First audit current code against the specification.
Do not introduce unnecessary infrastructure such as PostgreSQL, Redis, Kubernetes, microservices, message queues, or complex event systems unless explicitly requested.
Keep working parts if they match the target model.
SQLite is sufficient for the expected initial workload.
Refactor or replace parts that conflict with the target model.
## Architecture Principles
Before large changes, summarize:
Keep the application modular, but avoid excessive abstraction.
- what is kept
- what is changed
- what is removed
- why
Preferred structure:
## Implementation Discipline
```text
src/
├─ domain/
│ ├─ models/
│ ├─ services/
│ └─ calculations/
├─ db/
│ ├─ schema/
│ ├─ migrations/
│ └─ repositories/
├─ server/
│ ├─ routes/
│ ├─ controllers/
│ └─ middleware/
├─ frontend/
│ ├─ components/
│ ├─ pages/
│ └─ utils/
└─ shared/
├─ types/
└─ validation/
```
Work in phases.
The exact structure may be simplified if the project is still small.
Do not implement unrelated future features while working on a phase.
Use object-oriented design where it is useful for domain behavior, but do not force everything into classes.
Before coding, briefly state:
Good candidates for classes:
- files to change
- data model impact
- UI impact
- risks
- Project
- PowerBalance
- DistributionBoard
- Consumer
- ConsumerGroup
- CalculationService
- ReportGenerator
Prefer small, reviewable changes.
Good candidates for interfaces/types:
Do not rewrite the whole app unless the current architecture blocks the required domain model.
- DTOs
- API request/response shapes
- ORM result types
- Configuration objects
- Form data
- Validation schemas
Avoid duplicating the same model excessively across domain, database, API, and frontend. Some separation is acceptable, but keep mappings simple and explicit.
## Naming Conventions
## Naming
Use English names in code.
Examples:
Use clear domain names:
- `Project`
- `PowerBalance`
- `ProjectDevice`
- `DistributionBoard`
- `Consumer`
- `ConsumerGroup`
- `installedPower`
- `demandFactor`
- `demandPower`
- `ratedCurrent`
- `powerFactor`
- `CircuitSection`
- `Circuit`
- `CircuitDeviceRow`
- `equipmentIdentifier`
- `displayName`
- `phaseType`
- `quantity`
- `voltage`
- `phaseCount`
- `powerPerUnit`
- `simultaneityFactor`
- `cosPhi`
- `rowTotalPower`
- `circuitTotalPower`
Use PascalCase for classes, interfaces, React components, and types.
Avoid ambiguous names like:
Use camelCase for variables, properties, functions, and methods.
- `item`
- `thing`
- `entry`
- `rowData`
Use kebab-case for file names unless the local framework convention requires otherwise.
Use them only for local UI variables where the context is obvious.
Examples:
## Numbering Rules
```text
power-balance.service.ts
consumer.model.ts
distribution-board.repository.ts
calculation-utils.ts
```
Default sections:
## Domain Model Guidelines
- Lighting: prefix `-1F`
- Single-phase circuits: prefix `-2F`
- Three-phase circuits: prefix `-3F`
A consumer must still have a quantity. This allows the same structure to represent either a single device or a grouped device entry.
New circuit identifier:
Example:
- highest existing number in the section + 1
```ts
type Consumer = {
id: string;
projectId: string;
distributionBoardId?: string;
name: string;
category?: string;
quantity: number;
installedPowerPerUnit: number;
installedPowerTotal: number;
demandFactor: number;
demandPower: number;
voltage?: number;
phaseCount?: 1 | 3;
powerFactor?: number;
note?: string;
};
```
Do not fill gaps automatically.
The calculated fields may either be persisted or calculated dynamically. Prefer dynamic calculation first unless persistence is needed for reporting, auditability, or performance.
Do not renumber after insert, delete, move, sort or drag-and-drop.
## Calculation Rules
Renumber only when the user explicitly triggers "Renumber section".
Keep calculation logic centralized.
## UI Rules
Do not spread electrical formulas across route handlers, UI components, or database repositories.
The circuit list table should behave like a spreadsheet.
Use dedicated calculation services or pure functions.
Cells show static text by default.
Examples:
Inline edit starts by:
```text
src/domain/calculations/power-calculation.ts
src/domain/services/power-balance.service.ts
```
- double click
- Enter
- typing
- F2
Typical calculation concepts:
Keyboard behavior:
- Installed power total = quantity × installed power per unit
- Demand power = installed power total × demand factor
- Current calculation depends on voltage, phase count, and power factor
- Enter confirms
- Escape cancels
- Tab / Shift+Tab navigates editable cells
- Arrow keys navigate cells when not editing
When implementing formulas, add comments for the electrical meaning, especially where three-phase and single-phase calculations differ.
Support Ctrl+Plus and Ctrl+Shift+Plus for insertion.
Always be careful with units.
## Drag-and-Drop Rules
Preferred base units:
Dragging from the circuit identifier / circuit handle moves the whole circuit.
- Power: kW
- Current: A
- Voltage: V
- Demand factor: decimal number from 0 to 1
Dragging from the device area moves device rows.
If other units are added later, implement explicit conversion helpers.
Project devices can be dragged from a sidebar into the circuit list.
## Database Guidelines
Drop onto a free placeholder creates a new circuit.
Use SQLite initially.
Drop onto an existing circuit adds the device to that circuit.
Keep schema clear and readable.
Moving a device recalculates affected circuit totals.
Avoid premature normalization. Normalize where it prevents real inconsistency, not just for theoretical purity.
Moving rows never renumbers circuits automatically.
Recommended core tables:
Show clear visual drop indicators.
- projects
- power_balances
- distribution_boards
- consumers
- consumer_categories or system_types, if needed later
Reject invalid drop targets or require confirmation.
Use migrations. Do not manually modify the database schema without creating a migration.
## Sorting and Filtering
Use repositories or database access modules. Do not place raw database queries directly in UI components or high-level route handlers.
Filtering should work through column headers.
## API Guidelines
Sorting should work through column headers.
Keep API routes resource-oriented.
Sorting moves complete circuits as blocks.
Example routes:
Sorting must not split device rows away from their circuit.
```text
GET /api/projects
POST /api/projects
GET /api/projects/:projectId
PUT /api/projects/:projectId
DELETE /api/projects/:projectId
Sorting does not renumber.
GET /api/projects/:projectId/power-balances
POST /api/projects/:projectId/power-balances
The user may explicitly renumber after sorting.
GET /api/power-balances/:powerBalanceId/consumers
POST /api/power-balances/:powerBalanceId/consumers
PUT /api/consumers/:consumerId
DELETE /api/consumers/:consumerId
```
## Linked Project Devices
Validate all incoming API data.
Circuit device rows may be linked to project devices.
Use shared validation schemas if possible.
`displayName` is copied on insert but not synchronized automatically.
## UI Guidelines
When a project device changes, show affected linked rows and let the user choose which fields to sync.
The UI should be practical and data-entry friendly.
Never silently overwrite local changes.
Prioritize:
Allow disconnecting linked rows from project devices.
- Tables for consumers
- Inline editing where useful
- Clear grouping by distribution board or area
- Totals at group and project level
- German UI labels
- Consistent units in column headers
- Minimal clicks for adding multiple consumers
## Manual Rows
Use German labels such as:
Manual rows are allowed and common.
- Projekt
- Leistungsbilanz
- Verteilung
- Verbraucher
- Anzahl
- Leistung je Stück
- Installierte Leistung
- Gleichzeitigkeitsfaktor
- Berechnete Leistung
- Bemerkung
Manual rows can later be saved as project devices.
Code identifiers must remain English.
After saving, the row becomes linked to the new project device.
## Testing Guidelines
## Undo / Redo
Add tests for calculation logic.
Implement undo/redo for structural and destructive operations.
Calculation tests are more important than superficial UI tests.
Required operations:
At minimum, test:
- insert circuit
- insert device
- delete circuit
- delete device
- move circuit
- move device
- multi-row move
- renumber section
- edit cell value
- edit equipment identifier
- synchronization changes
- Total installed power calculation
- Demand power calculation
- Quantity handling
- Single-phase current calculation, if implemented
- Three-phase current calculation, if implemented
- Edge cases such as quantity 0, demand factor 0, and missing optional values
## Future Sizing
Do not change formulas without updating or adding tests.
Do not implement full cable/protection sizing unless explicitly requested.
## Docker and Development
Keep the structure ready for it.
The project should be runnable in a local development environment, including on Windows with Docker Desktop.
Future sizing will need:
If Docker is used, provide:
- circuit total power
- phase type
- voltage
- cosPhi
- cable length
- cable type
- cable cross-section
- protection rated current
- control requirement such as DALI
- `Dockerfile`
- `docker-compose.yml`
- clear volume handling for SQLite database files
- documented development commands
Users must be able to override sizing suggestions.
Avoid configurations that only work on Linux unless explicitly documented.
## Response Style for Codex
## Documentation Expectations
Be concise.
Keep documentation short but useful.
Do not restate the whole specification.
Document:
Reference the relevant file and section.
- How to install dependencies
- How to start the dev server
- How to run migrations
- How to run tests
- Basic domain assumptions
- Important formulas
When uncertain, choose the simplest implementation that preserves the domain model.
Prefer concise Markdown documentation.
Do not add libraries unless there is a clear reason.
## Development Progress Documentation
Document the current implementation status in dedicated Markdown files whenever regular status updates are requested.
- Keep status tracking explicit with `TODO`, `WIP`, and `DONE` sections.
- For each relevant module or feature area, document:
- what it does,
- how it works,
- which files/functions are involved,
- why important design choices were made,
- current limitations or open points.
- Break larger features into small sub-sections so someone new can read through and understand the flow.
- Update these Markdown status documents incrementally during implementation so progress can be tracked clearly over time.
- Prefer understandable, step-by-step explanations over overly brief summaries when needed for clarity.
## Coding Style
Write clear, explicit TypeScript.
Prefer readability over cleverness.
Avoid:
- unnecessary generic abstractions
- magic numbers
- hidden side effects
- large files with unrelated responsibilities
- mixing UI, database, and calculation logic
Use meaningful names even if they are longer.
## Safety and Data Integrity
Do not delete user data without explicit confirmation in the UI or API design.
Use soft-delete only if the project introduces audit or recovery requirements.
Validate numeric values carefully:
- quantity must not be negative
- demand factor should normally be between 0 and 1
- installed power must not be negative
- voltage must be positive
- phase count should be limited to valid values
## Agent Behavior
When modifying this repository:
1. Inspect the existing structure before adding new files.
2. Reuse existing patterns unless they are clearly wrong.
3. Keep changes small and focused.
4. Do not introduce large framework changes without explicit instruction.
5. Do not silently change the database technology.
6. Do not silently change the ORM.
7. Keep domain terms consistent.
8. Add or update tests when changing calculation logic.
9. Update this `AGENTS.md` if a new recurring project rule is established.
10. Prefer practical implementation over theoretical perfection.
## Out of Scope Unless Explicitly Requested
Do not implement the following unless explicitly requested:
- Multi-tenant user management
- Role-based permissions
- Cloud deployment
- PostgreSQL migration
- Realtime collaboration
- Complex report designer
- Full BIM integration
- GAEB integration
- Revit integration
- Authentication providers
- Enterprise audit logging
## Preferred First Milestone
The first useful milestone should be:
- Create a project
- Create one power balance
- Add distribution boards
- Add consumers with quantity
- Calculate installed power and demand power
- Show totals in the UI
- Persist data in SQLite
- Provide basic tests for calculation logic
Do not start with advanced reporting before the core data and calculation workflow works.
## Current UI Workflow Requirements
Implement and preserve the following navigation and workflow structure:
1. A dedicated project page that lists all projects and allows creating new projects.
2. On the same project page, users can configure global devices/consumers.
3. Inside a project, users first see all distribution boards and can open a selected board.
4. Circuit lists are edited in a dedicated view where up to 3 circuit lists can be opened in parallel.
5. Users must be able to copy circuit entries/consumers between the open circuit lists with minimal clicks.
6. In the circuit-list view, exactly 1 list is open by default. Users can add/remove list panels dynamically with a minimum of 1 and a maximum of 3 open lists.
When implementing frontend changes, keep this structure as the default interaction model unless the user explicitly requests a different UX.
## Language and Text Rules
Use proper German umlauts (ä, ö, ü, Ä, Ö, Ü, ß) in all new or changed German UI texts and documentation text, unless technical constraints explicitly prevent this.
## Responsiveness Rule
Frontend implementations must remain fully responsive by default across mobile, tablet, laptop, and wide desktop breakpoints.
Layouts with dynamic panel counts (for example 1-3 parallel circuit-list panels) must adapt so available horizontal space is used appropriately instead of leaving fixed empty columns.
## Language and Text Rules (Enforced)
Use proper German umlauts (, , , , , , ) in all new or changed German UI texts and documentation text, unless technical constraints explicitly prevent this.
## Project Voltage and Columns Rules
- Project properties must include default single-phase and three-phase voltages. Use 230 V for single-phase and 400 V for three-phase by default, and allow users to change both values in project settings.
- In circuit lists, when a consumer is single-phase and has no explicit voltage override, calculations use the project single-phase default voltage. When a consumer is three-phase and has no explicit voltage override, calculations use the project three-phase default voltage.
- When creating a new consumer/device entry, the standard input fields should be: consumer display name, quantity, unit power, demand factor, and total power.
- By default, the table should initially hide: power factor (cos phi), phase count, and current.
- Users must be able to add any available attribute as a table column at any time, and must be able to reorder column positions.
## Encoding Rule
- All text files must be saved as UTF-8.
- German UI text must never contain mojibake artifacts (for example geöffnet, wählen, Übernehmen, ←, →).
- If such artifacts appear, they must be corrected immediately before merge or handoff.
Do not introduce global state management unless needed.