# 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 und Tarife. ## 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 im PostgreSQL-Modus (`jdbc:h2:file:./eegportal;MODE=PostgreSQL`) - **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 - `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 ```bash # 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 ```bash # 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: ```bash # 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: `(): ` (feat/fix/docs/style/refactor/test/chore) - Scopes: `iam`, `community`, `mako`, `tariff`, `dashboard`, `common`, `frontend` ## Conventional Commits Ab jetzt werden [Conventional Commits](https://www.conventionalcommits.org/) verwendet: ``` (): [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 ```