eeg_portal/AGENTS.md
Bernhard Müller 975f76dbd3 feat(community): add metering data upload and query with XLSX support
Implement complete metering data management for energy communities:

- MeteringData entity with unique constraint (metering_point_id, interval_start, data_type)
- Bulk upload via JSON or XLSX (multipart) with validation
- XLSX parser using Apache POI with comma-decimal support
- Ownership check on GET endpoints (userId must match metering point owner)
- Deduplication: existing records overwritten on re-upload
- DataSource tracking (EMAIL_XLSX, API, MANUAL)
- Query endpoints: by metering point, by type, by upload batch

Additional fixes:
- MapStruct annotation processor: add to execution-level annotationProcessorPaths
  (Spring Boot parent POM was overriding plugin-level config)
- EnergyCommunityMapper + MeteringDataMapper: componentModel=spring
- UserMapper: ignore passwordResetToken/Expiry (unmapped target policy ERROR)
- TariffService: add TariffInviteRepository dependency + invitation check
- TariffServiceTest: add missing @Mock for TariffInviteRepository
- SecurityConfig: permit /actuator/health and /actuator/info
- pom.xml: add poi-ooxml, postgresql, spring-boot-starter-actuator
- .gitignore: add *.log, survey/, backend.log

Tests: 137/137 passing
2026-07-22 12:42:27 +02:00

5.8 KiB

AGENTS.md - EEG Portal

Projektübersicht

EEG Portal - Portal zur Verwaltung von Energiegemeinschaften in Österreich. Behandelt: Benutzerregistrierung, Messpunkt-Consent-Workflows (MaKo), EDA-Topologieprüfungen, Energiegemeinschaftsverwaltung, Mitgliedschaften, Tarife und Messdaten-Verwaltung.

Architektur

Modularer Monolith - Designed für spätere Domänen-Extraktion als Maven-Module.

Backend (Spring Boot)

  • Java 21, Spring Boot 4.0.6
  • Datenbank: H2 (Dev) / PostgreSQL 16 (Prod)
  • ORM: Spring Data JPA + Hibernate (ddl-auto: update)
  • Annotation Processing: Lombok + MapStruct (mit unmappedTargetPolicy=ERROR)
  • Pakete:
    • iam/ - Identitäts- und Zugriffsverwaltung (Auth, Users, Security)
    • community/ - Energiegemeinschaften, Mitgliedschaften, Messpunkte, Messdaten
    • mako/ - EDA-Kommunikation (Consent, Topologie)
    • tariff/ - Tarifverwaltung (nur Domain-Entity, noch kein Service)
    • dashboard/ - Dashboard-Statistiken
    • common/ - Events, Exceptions, gemeinsame Types

Frontend (Angular)

  • Angular 21, TypeScript 5.9, Tailwind CSS 4, Angular Material
  • API-Client wird aus OpenAPI-Spec generiert (npm run generate-api)
  • Test-Framework: Vitest
  • Code-Style: Prettier (100 Zeichen, Single Quotes, Angular HTML Parser)
  • API-URL über src/environments/environment.ts konfigurierbar (nicht hardcodiert)

Entwicklung starten

# Backend
.\mvnw spring-boot:run -pl eeg_backend -Dspring-boot.run.arguments=--spring.profiles.active=dev

# Frontend
cd eeg_frontend && ng serve

Wichtig: Backend muss zuerst laufen (port 8080), da Frontend auf localhost:8080 proxyt.

Tests

# Backend: Alle Tests
.\mvnw test -pl eeg_backend

# Backend: Einzelnen Test laden
.\mvnw test -pl eeg_backend -Dtest=MembershipServiceTest

# Backend: OpenAPI-Spec generieren (startet Backend + schreibt nach eeg_frontend/openapi.yaml)
.\mvnw test -pl eeg_backend -Dtest=OpenApiGeneratorTest

# Frontend: Alle Tests
cd eeg_frontend && ng test

Test-Pattern:

  • Backend: JUnit 5 + Mockito (@ExtendWith(MockitoExtension.class))
  • Frontend: Vitest (nicht Karma/Jasmine)
  • Keine Integrationstests mit echter DB (H2 in-memory für Tests)

API-Vertrag generieren

Wenn sich Backend-Controller ändern, muss die OpenAPI-Spec aktualisiert werden:

# 1. Backend laufen lassen oder Test ausführen
.\mvnw test -pl eeg_backend -Dtest=OpenApiGeneratorTest

# 2. Frontend-API-Client generieren
cd eeg_frontend && npm run generate-api

Die Datei eeg_frontend/openapi.yaml wird vom Backend-Test (OpenApiGeneratorTest) generiert - nicht manuell pflegen.

Wichtige Patterns

Event-basierte Kommunikation

Domänen kommunizieren über Spring Application Events:

UserRegisteredEvent → UserApprovedEvent → InitiateMakoConsentEvent
EdaTopologyCheckEvent → EdaTopologyCompletedEvent / EdaTopologyFailedEvent
MakoConsensApprovedEvent / MakoConsensRejectedEvent / MakoConsensTechnicalFailedEvent

MaKo-Zustandsautomat (MeteringPoint.fireTrigger())

NEW → WAITING_FOR_CONSENT → CONSENT_GRANTED → ACTIVE
                                    ↓
                               REJECTED / ERROR

EDA-Simulation

  • AT-Nummer endet mit "REJECT" → Ablehnung
  • AT-Nummer endet mit "ERROR" → technischer Fehler
  • Sonst: automatische Zustimmung
  • Simulierte Services haben kein @Profile - sie sind immer aktiv (auch in prod)
  • Konfigurierbar: eda.simulation.consent-delay-ms (default: 3000ms)

Sicherheit

  • JWT-basiert (HS256), 2h Ablauf
  • Rollen: ADMIN, MEMBER (aus JWT-Claim role)
  • Admin-Endpunkte: /api/community/admin/**, /api/iam/admin/**, /api/mako/admin/**
  • @Profile("dev") nur für: AdminDataInitializer, ConsoleMailService
  • @Profile("prod") für: SmtpMailService

Wichtige Dateien

Datei Beschreibung
eeg_backend/.../community/domain/MeteringPoint.java:fireTrigger() MaKo-Zustandsautomat
eeg_backend/.../community/event/listener/MakoConsentListener.java Consent-Event-Handler
eeg_backend/.../mako/event/listener/EdaCommuncationEventListener.java EDA-Kommunikation
eeg_backend/.../iam/config/AdminDataInitializer.java Initialer Admin-User (dev)
eeg_backend/.../OpenApiGeneratorTest.java Generiert OpenAPI-Spec
eeg_frontend/openapi.yaml API-Vertrag für Frontend-Generierung
eeg_frontend/src/environments/environment.ts API-URL Konfiguration
eeg_frontend/src/app/app.routes.ts Frontend-Routing (alle Pages)

Regeln

  • Fehlernachrichten sind auf Deutsch
  • Explizite isEnabled()-Überschreibung in User.java nötig (Lombok/Spring Security Konflikt)
  • Conventional Commits: <type>(<scope>): <description> (feat/fix/docs/style/refactor/test/chore)
  • Scopes: iam, community, mako, tariff, dashboard, common, frontend

Conventional Commits

Ab jetzt werden Conventional Commits verwendet:

<type>(<scope>): <description>

[optional body]

[optional footer]

Typen

  • feat: Neue Funktion
  • fix: Bugfix
  • docs: Dokumentation
  • style: Formatierung (keine Code-Änderung)
  • refactor: Code-Refactoring ohne Funktionsänderung
  • test: Tests hinzugefügt/ergänzt
  • chore: Build-Prozess, Abhängigkeiten, Konfiguration

Beispiele

feat(iam): add user profile management
fix(mako): handle consent rejected event correctly
docs: update AGENTS.md with conventional commits
test(iam): add UserService unit tests

Deployment

Docker (Produktion)

# .env erstellen
cp .env.example .env
nano .env

# Starten
docker compose up -d

# Logs
docker compose logs -f

Docker (lokale Entwicklung)

# Mit H2 (Standard)
docker compose up -d

# Mit PostgreSQL
docker compose --profile postgres up -d

Siehe DEPLOYMENT.md für detaillierte Anleitung.