6.9 KiB
Report: Code-Review-Fixes — Kritische und hohe Befunde
Status: DONE
Alle 3 kritischen und 5 hohen Befunde wurden implementiert, getestet und gemerged. Build und Tests gruen (313/313). Post-Merge-Review ergab 2 wichtige und 1 minor Empfehlung (nicht blockierend).
What Was Built
8 Code-Review-Befunde im EEG Portal Backend behoben — 3 Sicherheitsfixes (KRITISCH) und 5 Code-Qualitäts-Verbesserungen (HOCH):
| # | Schwere | Befund | Dateien |
|---|---|---|---|
| 1 | KRITISCH | EnergyCommunityAdminController — @PreAuthorize("hasRole('ADMIN')") auf Klassenebene |
EnergyCommunityAdminController.java |
| 2 | KRITISCH | NotificationService.markAsRead — IDOR-Fix: @CurrentUserId + Ownership-Check |
NotificationController.java, NotificationService.java |
| 3 | KRITISCH | GlobalExceptionHandler — MethodArgumentNotValidException-Handler (400 mit komma-separierten Feldfehlern) |
GlobalExceptionHandler.java |
| 4 | HOCH | Exception-Unification — ResponseStatusException durch IllegalArgumentException/IllegalStateException ersetzt |
AdminIamService.java, EnergyCommunityService.java |
| 5 | HOCH | TariffService — validateUserTariffRequest() private Methode extrahiert (~30 Zeilen Deduplizierung) |
TariffService.java |
| 6 | HOCH | AtNumberAlreadyExistsException-Handler — ex.getMessage() statt hardcoded String |
GlobalExceptionHandler.java |
| 7 | HOCH | MeteringPoint.memberships — orphanRemoval = true hinzugefuegt |
MeteringPoint.java |
| 8 | HOCH | ddl-auto Prod-Default — von update auf validate geaendert |
application-prod.yml |
Tests neu/hinzugefuegt:
GlobalExceptionHandlerTest— 8 Tests fuer alle Handler-PfadeNotificationServiceTest— 3 neue Tests fuer Ownership-Check und Not-FoundAdminIamServiceTest— rejectUser-Tests aktualisiert (Exception-Typen)EnergyCommunityServiceTest— Exception-Typen angepasst
Architecture
Die Aenderungen betreffen ausschliesslich das Backend (Java/Spring Boot). Die Architektur-Aenderungen:
-
Exception-Strategie vereinheitlicht: Services werfen
IllegalArgumentException(→ 400) oderIllegalStateException(→ 409).GlobalExceptionHandlermapped diese konsistent.ResponseStatusExceptionwird nur noch in Controllern verwendet (nicht in Services). -
Authorization auf Klassenebene:
EnergyCommunityAdminControllererhaelt@PreAuthorize("hasRole('ADMIN')")— konsistent mitAdminIamController. -
IDOR-Verhinderung:
NotificationController.markAsReaderhaelt@CurrentUserIdParameter. Service prueft Ownership vor Statusaenderung. -
Validierung konsolidiert:
TariffService.validateUserTariffRequest()bündelt 6 Validierungspruefungen (source/target ACTIVE, Community-Tarif vorhanden, Preis <= Max, beide User aktive Members).
Design Decisions
-
@PreAuthorizeauf Klassenebene (nicht pro Methode): Konsistent mitAdminIamController. Vorteil: neue Endpunkte sind automatisch gesichert. Nachteil:@PreAuthorize("permitAll()")noetig fuer einzelne Methoden, falls gewuenscht (hier nicht der Fall). -
validateUserTariffRequest()return:voidstattPair: Die geladenen MeteringPoints werden fuer den Ownership-Check inupdateUserTariffnicht gebraucht (Ownership basiert auftariff.getSourceMeteringPointId()).voidbleibt simpel; die redundanten DB-Queries (Review-Finding) sind ein bekanntes, toleriertes Trade-off. -
orphanRemoval = truedefensive: Kein aktueller Delete-Endpoint, aber das Flag verhindert konsistente DB-Zustaende bei zukuenftigen Loesch-Workflows. -
ddl-auto: validatestattnone:validateprueft Schema-Konsistenz beim Start, ohne es zu aendern. Kompromiss zwischenupdate(Schema-aendernd) undnone(keine Pruefung). -
Post-Merge-Review-Findings (nicht blockierend):
TariffServicelaedt MeteringPoints doppelt (invalidateUserTariffRequest+ danach fuer Ownership/Invite-Check). Redundant aber korrekt — Refactoring aufPair-Rueckgabe empfohlen, aber nicht kritisch.TariffServiceverwendet fully-qualifiedorg.springframework.security.access.AccessDeniedExceptionstatt Import. Konsistenz-Problem, nicht funktional.
Usage
Kein Nutzungs-Interface-Aenderung. Die Aenderungen sind intern:
@Valid-Fehler geben jetzt konsistentesErrorResponse-JSON zurueck (statt Spring-Default)- Admin-Endpoints verlangen explizit
ADMIN-Rolle (vorher: nur URL-basiert gesichert) Notification.markAsReadverlangt Besitz der Notification- Exception-Messages aus
GlobalExceptionHandlersind informativer (enthalten AT-Nummer etc.)
Verification
| Metrik | Wert |
|---|---|
| Typecheck | OK |
| Backend Tests | 206 passed, 0 failed |
| Frontend Tests | 107 passed, 0 failed |
| Build | OK |
| Total Tests | 313 passed, 0 failed |
Journey Log
-
Spec & Plan: 8 Findings analysiert, technische Abhaengigkeiten identifiziert (Findings 3+6 vor Finding 4), 14 Tasks aufgeteilt.
-
Implementierung (Attempt 1): Alle 14 Tasks (T1–T14) abgeschlossen. TDD fuer T10, T11, T12. 206 Backend-Tests + 107 Frontend-Tests gruen. Frontend: 107 Tests fehlgeschlagen (vitest TestBed-Init-Problem — nicht unsere Aenderung).
-
Merge & Verify (Attempt 1): Tasks T1–T8, T10, T11, T14 gemerged. T2, T3, T5, T6, T7, T9, T12, T13 pristine (identisch mit master). Build erfolgreich.
-
Frontend-Fix (Attempt 2): Vitest TestBed-Infrastruktur repariert. API-Client fuer
deleteUserTariffmituserId-Parameter neu generiert. Alle 313 Tests gruen. -
Post-Merge-Review: 2 wichtige Findings (TariffService redundant Queries, fully-qualified Exception) und 1 minor (source != target Duplizierung) dokumentiert. Ready-to-Merge.
Source Materials
docs/compose/specs/code-review-critical-fixes.md— Ausgangslage, Befund-Detail, Scopedocs/compose/plans/code-review-critical-fixes.md— 14 Tasks mit Akzeptanzkriterieneeg_backend/src/main/java/at/mueller/eeg/backend/common/exception/GlobalExceptionHandler.java— Validierungs-Handler + AtNumber-Handlereeg_backend/src/main/java/at/mueller/eeg/backend/community/api/EnergyCommunityAdminController.java— @PreAuthorizeeeg_backend/src/main/java/at/mueller/eeg/backend/common/api/NotificationController.java— @CurrentUserIdeeg_backend/src/main/java/at/mueller/eeg/backend/common/service/NotificationService.java— Ownership-Checkeeg_backend/src/main/java/at/mueller/eeg/backend/iam/service/AdminIamService.java— rejectUser IAE/ISEeeg_backend/src/main/java/at/mueller/eeg/backend/community/service/EnergyCommunityService.java— update/delete IAE/ISEeeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffService.java— validateUserTariffRequesteeg_backend/src/main/java/at/mueller/eeg/backend/community/domain/MeteringPoint.java— orphanRemovaleeg_backend/src/main/resources/application-prod.yml— ddl-auto: validate