Enth\u00e4lt gemischt: Laravel-10-Upgrade + Phase 1 (Contacts-Modul, Duplicats-Commands, Soft-Delete+Merge-Fields) + Phase 2 Code-Umstellungen (inquiry_id, $table='contacts'/'inquiries') + Offers-Modul (Migrationen, Models, offer_id in Booking, offer-Disk in filesystems.php). Phase 2 + Offers werden im folgenden Commit nach dev/backups/phase2-offers-2026-04-17/ verschoben, damit der Workspace auf Phase-1-only (= Test-System-Stand) reduziert ist und direkt auf Live deploybar wird. Tarball-Backup zus\u00e4tzlich unter: ../backups-safety/workspace-pre-phase1-rollback-2026-04-17.tar.gz Made-with: Cursor
242 lines
6.9 KiB
Markdown
242 lines
6.9 KiB
Markdown
# 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:**
|
||
- `<filter><whitelist>` → `<coverage><include>` (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
|
||
<env name="DB_CONNECTION_STERN" value="sqlite" force="true"/>
|
||
<env name="DB_DATABASE_STERN" value=":memory:" force="true"/>
|
||
```
|
||
|
||
---
|
||
|
||
## 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)
|