mein-sterntours/dev/audit-april-2025.md
Phase-1-Rollback-Agent e3dc1afd8e WIP: Sicherheitsnetz vor Phase-1-R\u00fcckbau
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
2026-04-17 13:40:31 +00:00

242 lines
6.9 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)