# HTTP-500-Fehler: Analyse und Code-Anpassungen (TerraFlow)

Dieses Dokument beschreibt die **festgestellten Ursachen** für HTTP-500-Antworten, den **Nachweis in den Logs** und die **konkreten Code-Änderungen**, damit das Verhalten stabil und nachvollziehbar ist.

---

## 1. Symptom und Nachweis

### 1.1 Lizenz-API `GET /api/license/check` → 500 (historisch, in `var/log/dev.log`)

In den Logs (Beispiel Oktober 2025) steht u. a.:

```text
Controller "Plugin\LicenseServerPlugin\Controller\LicenseApiController::checkLicense"
requires that you provide a value for the "$licenseKey" argument.
```

**Bedeutung:** Die Route `/api/license/check` wurde auf eine Controller-Methode gemappt, deren Signatur einen **Pflichtparameter** `$licenseKey` (oder ähnlich) erwartete, der **weder aus der Route noch per Dependency Injection** befüllt wurde. Symfony konnte die Controller-Argumente nicht auflösen → **RuntimeException** → HTTP **500**.

**Aktueller Stand im Repository:** `LicenseApiController::checkLicense` nimmt nur noch `Request $request` entgegen und liest `licenseKey` und `domain` aus der Query-String. Fehlen diese Parameter, liefert die Aktion bewusst **HTTP 400** mit JSON-Fehlertext (kein Serverfehler mehr).

**Verifikation nach den Anpassungen (lokal):**

- `GET /api/license/check` ohne Parameter → **400** mit `{"valid":false,"error":"licenseKey und domain sind erforderlich"}`

---

### 1.2 Symfony-Konsole: Warnung „`mailer.mailer` … removed or inlined“

Beim Aufruf von `php bin/console` trat wiederholt auf:

```text
The "mailer.mailer" service or alias has been removed or inlined when the container was compiled.
You should either make it public, or stop using the container directly …
```

**Ursache:** `GenerateRecurringInvoicesCommand` hat im Konstruktor **`$container->get('mailer.mailer')`** verwendet. In Symfony 6.4 ist der Mailer oft **nicht mehr öffentlich** über den generischen Container-Zugriff abrufbar; der Versuch schlägt bei der **Registrierung der Console-Commands** fehl.

---

### 1.3 `LicenseCheckSubscriber`: `Undefined array key "APP_ENV"`

Bei Requests ohne vollständig befülltes `$_ENV`-Array (z. B. minimale PHP-CLI-Tests) kann

```php
$_ENV['APP_ENV']
```

zu **PHP-Warnungen** führen und ist gegenüber der Kernel-Konfiguration **fehleranfällig**.

**Anpassung:** Die Umgebung kommt aus dem Kernel (`%kernel.environment%`) per Dependency Injection, nicht aus `$_ENV`.

---

### 1.4 `BillingService` und manuelle Command-Registrierung im Plugin

`LicenseServerPlugin::registerCommands()` hat Commands manuell instanziiert. Nach Umstellung der Commands auf echte Konstruktor-Abhängigkeiten war **`$this->container->get(BillingService::class)`** problematisch, solange der Dienst **privat** war.

**Anpassung:** `BillingService` ist als **`public: true`** markiert (nötig für den bewussten Zugriff aus der Plugin-`registerCommands`-Methode). Zusätzlich wird der Mailer in der Service-Definition mit **`@mailer`** referenziert (öffentlicher Symfony-Mailerdienst), nicht mit dem privaten Alias `mailer.mailer`.

---

## 2. Geänderte Dateien (Überblick)

| Datei | Zweck der Änderung |
|--------|---------------------|
| `src/EventSubscriber/LicenseCheckSubscriber.php` | Umgebungsprüfung über `%kernel.environment%` statt `$_ENV['APP_ENV']`. |
| `plugin/LicenseServerPlugin/Command/GenerateRecurringInvoicesCommand.php` | `BillingService` per Konstruktor injizieren; kein `new BillingService(...)` und kein `$container->get('mailer.mailer')` mehr. |
| `plugin/LicenseServerPlugin/Command/CreateDefaultPlansCommand.php` | `EntityManagerInterface` per Konstruktor injizieren; kein `ContainerInterface` mehr. |
| `plugin/LicenseServerPlugin/Resources/config/services.yaml` | Command-Argumente angepasst; `BillingService` mit `public: true`; Mailer-Referenz `@mailer`. |
| `plugin/LicenseServerPlugin/src/LicenseServerPlugin.php` | `registerCommands()` übergibt `doctrine.orm.entity_manager` bzw. `BillingService` passend zu den neuen Konstruktoren. |

---

## 3. Technische Details der Anpassungen

### 3.1 `LicenseCheckSubscriber`

- **Neu:** Parameter `#[Autowire('%kernel.environment%')] string $kernelEnvironment`.
- **Ersetzt:** `if ($_ENV['APP_ENV'] !== 'prod')` durch `if ($this->kernelEnvironment !== 'prod')`.

Damit entspricht die Logik der **tatsächlichen Symfony-Umgebung** und vermeidet direkten Zugriff auf `$_ENV`.

### 3.2 `GenerateRecurringInvoicesCommand`

- **Vorher:** Manuelle Erzeugung von `BillingService` mit `$container->get('doctrine.orm.entity_manager')`, `$container->get('mailer.mailer')`, `$container->get('twig')`.
- **Nachher:** Ein einziges Konstruktor-Argument `BillingService $billingService` (entspricht Symfony Best Practice und funktioniert mit privatem Mailer).

### 3.3 `CreateDefaultPlansCommand`

- **Vorher:** `ContainerInterface` und `$container->get('doctrine.orm.entity_manager')`.
- **Nachher:** `EntityManagerInterface $entityManager` im Konstruktor.

### 3.4 `services.yaml` (LicenseServerPlugin)

- **Commands:** Explizite Argumente `$entityManager` bzw. `$billingService` wie oben.
- **BillingService:** `public: true`; `$mailer: '@mailer'`.

### 3.5 `LicenseServerPlugin::registerCommands()`

- **Vorher:** `new CreateDefaultPlansCommand($this->container)` / `new GenerateRecurringInvoicesCommand($this->container)`.
- **Nachher:** `new CreateDefaultPlansCommand($this->container->get('doctrine.orm.entity_manager'))` und `new GenerateRecurringInvoicesCommand($this->container->get(BillingService::class))`.

---

## 4. Deployment-Hinweise für den Betrieb

1. **Cache leeren** nach dem Deployment (z. B. `php bin/console cache:clear --env=prod`), damit der Container die geänderten Service-Definitionen lädt.
2. **Lizenz-API:** Clients, die `GET /api/license/check` aufrufen, müssen **`licenseKey` und `domain` als Query-Parameter** mitsenden; andernfalls ist **400** korrekt (kein 500).
3. Falls auf einem Server noch **alter Code** ohne `Request`-basierte `checkLicense`-Methode liegt, dort deployen oder mindestens die im Log beschriebene Controller-Signatur-Anpassung nachziehen.

---

## 5. Kurzfassung für das Team

- **500 auf `/api/license/check`** entstand durch **nicht auflösbare Controller-Argumente** (ältere Plugin-Version laut Log). Die **korrekte** Implementierung liest Parameter aus dem **Request** und antwortet mit **400**, wenn etwas fehlt.
- **Console-Warnungen/Fehler** kamen vom **direkten Zugriff auf `mailer.mailer`** und wurden durch **Dependency Injection** und eine **öffentliche `BillingService`-Definition** behoben.
- **`LicenseCheckSubscriber`** nutzt **`kernel.environment`** statt `$_ENV`, um Warnungen und Randfälle zu vermeiden.

---

*Stand der Dokumentation: 2026-03-24 (Repository-Pfad: TerraFlow-Projektroot).*
