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
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, Messdatenmako/- EDA-Kommunikation (Consent, Topologie)tariff/- Tarifverwaltung (nur Domain-Entity, noch kein Service)dashboard/- Dashboard-Statistikencommon/- 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.tskonfigurierbar (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-Claimrole) - 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 inUser.javanö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 Funktionfix: Bugfixdocs: Dokumentationstyle: Formatierung (keine Code-Änderung)refactor: Code-Refactoring ohne Funktionsänderungtest: Tests hinzugefügt/ergänztchore: 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.