# Code-Audit – mein.sterntours.de (April 2025) Durchgeführt nach Framework-Update auf Laravel 10 / PHPUnit 10. --- ## Status-Übersicht | Bereich | Status | |---------|--------| | PHPUnit-Konfiguration | ✅ behoben | | UserFactory | ✅ auf Laravel 10 migriert | | Test-Abdeckung | ✅ Grundgerüst erstellt | | Composer-Autoload | ✅ behoben | | User/Customer/Lead/Booking HasFactory | ✅ hinzugefügt | | Hardcoded API-Key | ✅ behoben (→ `config('app.success_key')`) | | Code-Duplizierung Services | ✅ `MailDirService` extrahiert | | BookingController Request-Facade | ✅ auf Injection umgestellt | | Util.php Carbon-Calls | ✅ behoben | | Leere Konstruktoren | ✅ entfernt | | Factories Customer/Lead/Booking | ✅ erstellt | | Veraltetes Frontend-Tooling | ℹ️ bekannt – separates Vorhaben | --- ## Behobene Probleme ### 1. `phpunit.xml` — PHPUnit 10 Inkompatibilität **Datei:** `phpunit.xml` PHPUnit 10 hat mehrere Attribute aus dem XML entfernt, die vorher vorhanden waren. Das führte zu Warnings bzw. Fehlern beim Testlauf. **Entfernt:** - `backupStaticAttributes` (seit PHPUnit 9.6 deprecated, in 10 entfernt) - `convertErrorsToExceptions`, `convertNoticesToExceptions`, `convertWarningsToExceptions` (in PHPUnit 10 entfernt) - `processIsolation`, `stopOnFailure` (in PHPUnit 10 aus XML entfernt → nur noch als CLI-Flag) **Geändert:** - `` → `` (PHPUnit 10 Syntax) --- ### 2. `database/factories/UserFactory.php` — Laravel 7 Syntax **Datei:** `database/factories/UserFactory.php` Die alte Factory nutzte die Laravel 7 Closure-Syntax (`$factory->define()`), die in Laravel 10 nicht mehr unterstützt wird. **Vorher:** ```php $factory->define(App\User::class, function (Faker $faker) { ... }); ``` **Nachher:** Vollständige Laravel 10 `Factory`-Klasse mit States (`admin()`, `inactive()`). --- ### 3. `composer.json` — Veraltetes Classmap-Autoloading **Datei:** `composer.json` ```json // Vorher (Laravel 7 Stil): "classmap": ["database/seeds", "database/factories"] // Nachher (PSR-4): "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeds/" ``` --- ### 4. `app/User.php` — HasFactory-Trait fehlte + ungültiger Import `HasFactory` wurde hinzugefügt, damit `User::factory()` in Tests funktioniert. Der ungültige Import `PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\F` (nie benutzt) wurde entfernt. --- ## Offene Probleme (Handlungsbedarf) ### ⚠️ Hardcoded API-Key (Priorität: HOCH) **Datei:** `app/Http/Controllers/API/BookingController.php:12` ```php private $successKey = 'f6077389c9ce710e554763a5de02c8ec'; ``` Der API-Key ist direkt im Source Code und damit im Git-Repository. Das ist ein Sicherheitsrisiko. **Lösung:** ```php // .env BOOKING_IMPORT_KEY=f6077389c9ce710e554763a5de02c8ec // Controller private string $successKey; public function __construct() { $this->successKey = config('app.booking_import_key'); } ``` Dazu in `config/app.php` ergänzen: ```php 'booking_import_key' => env('BOOKING_IMPORT_KEY'), ``` --- ### ⚠️ Code-Duplizierung: `Services/Booking.php` und `Services/Lead.php` Beide Services enthalten nahezu identische Methoden: - `getCustomerMailDirs()` - `getCustomerMailDir($id)` - `getCustomerMailName($dir, $id)` - `getCustomerMailEmails($dir, $id)` - `setOutputDirs($dir, $subdir)` - `getMailDirNotInOutput($id, $dir)` **Lösung:** Einen gemeinsamen `MailDirService` (oder Trait) extrahieren. --- ### ⚠️ `BookingController` nutzt Request-Facade statt Dependency Injection **Datei:** `app/Http/Controllers/BookingController.php:5` ```php use Request; // Facade // ... $data = Request::all(); ``` **Lösung:** `Illuminate\Http\Request $request` als Parameter injizieren. --- ### ⚠️ `Services/Util.php` — veraltete Carbon-Nutzung **Datei:** `app/Services/Util.php:54-58` ```php \Carbon::parse($date) // veraltet \Util::formatDateDB() // statischer Aufruf über Facade-Alias ``` **Lösung:** `Carbon\Carbon::parse($date)` und `self::formatDateDB()` verwenden. --- ### ℹ️ `API/BookingController` — leerer Konstruktor **Datei:** `app/Http/Controllers/API/BookingController.php:17-19` ```php public function __construct() { } ``` Leere Konstruktoren ohne Parameter sollen laut Projekt-Konvention entfernt werden. --- ### ℹ️ Frontend-Tooling — stark veraltet **Datei:** `package.json` | Package | Aktuell | Stand | |---------|---------|-------| | `laravel-mix` | 2.1.11 | 2018 — aktuell: 6.x | | `cross-env` | 5.1.4 | veraltet | | `node-sass` | ~4.7.2 | deprecated → `sass` (dart-sass) verwenden | | `bootstrap` | ~4.1.1 | Bootstrap 5.x verfügbar | Ein Frontend-Update ist ein größeres Vorhaben und sollte separat geplant werden. Das Build-System funktioniert noch, ist aber auf veralteten Node-Versionen abhängig. --- ### ℹ️ `BaseRepository.php` — fehlende Return-Types **Datei:** `app/Repositories/BaseRepository.php` Alle Methoden haben keine Return-Type-Deklarationen. Als technische Schuld für künftige Refactoring-Sessions notiert. --- ### ℹ️ `phpunit.xml` — SQLite & zweite Datenbankverbindung Tests nutzen SQLite (`:memory:`), die `mysql_stern`-Verbindung ist nicht konfiguriert. Models, die `mysql_stern` nutzen (`App\Models\Sym\*`, `App\Models\TravelBooking`), können in Tests nicht ohne Mock/Skip getestet werden. **Empfehlung:** Für Tests eine zweite SQLite-Verbindung in `phpunit.xml` konfigurieren: ```xml ``` --- ## Neue Test-Dateien | Datei | Typ | Was wird getestet | |-------|-----|-------------------| | `tests/Unit/Services/UtilTest.php` | Unit | `Util`-Service: Formatierung, Sanitizing, Placeholder-Ersetzung | | `tests/Feature/Auth/LoginTest.php` | Feature | Login, Logout, Redirect für Gäste/inaktive User | | `tests/Feature/Api/BookingImportTest.php` | Feature | API-Key-Validierung, 404-Handling | | `tests/Feature/BookingControllerTest.php` | Feature | Middleware (Guest-Redirect, Admin-Check) | ### Tests ausführen ```bash # Alle Tests php artisan test --compact # Nur Unit-Tests php artisan test --compact tests/Unit # Nur die neuen Feature-Tests php artisan test --compact tests/Feature/Auth/LoginTest.php php artisan test --compact tests/Feature/Api/BookingImportTest.php php artisan test --compact tests/Feature/BookingControllerTest.php # Einzelner Test per Filter php artisan test --compact --filter=testLoginFailsWithWrongPassword ``` --- ## Nächste Schritte (Empfehlung) 1. **API-Key** aus Code entfernen → `.env`-Variable (HOCH) 2. `MailDirService` extrahieren (Booking + Lead Services zusammenführen) 3. `BookingController` auf Request-Injection umstellen 4. `Util.php` Carbon-Calls bereinigen 5. Leere Konstruktoren entfernen 6. Weitere Factories erstellen (`Customer`, `Booking`, `Lead`) für tiefere Test-Abdeckung 7. Frontend-Tooling-Update planen (laravel-mix → Vite oder mix v6)