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

187 lines
5.8 KiB
Markdown

# 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
```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: `<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](https://www.conventionalcommits.org/) 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)
```bash
# .env erstellen
cp .env.example .env
nano .env
# Starten
docker compose up -d
# Logs
docker compose logs -f
```
### Docker (lokale Entwicklung)
```bash
# Mit H2 (Standard)
docker compose up -d
# Mit PostgreSQL
docker compose --profile postgres up -d
```
Siehe `DEPLOYMENT.md` für detaillierte Anleitung.