mivita/dev/2026-08-26-logs/ANALYSE.md
Kevin aa52b02a2a Doku: Plaene, Kundenbriefe, Log-Analyse und Ledger-Plan versioniert, Stand 23.09.
- September-Plan: B2, E1 (Gleichstand, Zahlungsdatum), A07 und die
  Abo-Warnung nachgetragen; Audit-Stand A07 erledigt.
- Bisher nur im Arbeitsbaum: Entwicklungsplan und Kundenbrief vom 07.09.
  samt PDF, Tickets vom 08.09., Log-Analyse 26.08., Ledger-Plan,
  August-Anerkennungen. E-Mail-Adressen von Kunden und Beratern durch
  Platzhalter bzw. Namen ersetzt.

Nicht versioniert (personenbezogene Daten): Kundenliste CSV/XLSX und die
Produktions-Logs in dev/2026-08-26-logs/*.log.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:45:10 +00:00

26 KiB
Raw Permalink Blame History

Log-Analyse 26.08.2026

Auswertung von 94 Logdateien (abo_order, cleanup, cron, dhl, laravel, order_controller, payment, stripe) aus dev/2026-08-26-logs/. Zeitraum: 05.04.2026 – 26.08.2026 (Schwerpunkt 27.07.–26.08.2026, laravel.log reicht ungedreht bis April zurück).

Umsetzungsstand (26.08.2026)

Alle Code-Fixes sind umgesetzt. Der Testlauf zeigt unveraendert 89 Vorbestandsfehler (BusinessPlan, InvoiceService, ConcurrentPayment – alle bereits vor diesen Aenderungen rot), bestandene Tests stiegen von 893 auf 914: die 21 neuen Tests laufen, keine Regression.

# Punkt Status
P0-1 contains() auf Array erledigt
P0-2 V53PAK → V53WPAK erledigt
P0-3 Zolldaten Schweiz CH/GB/US/NO gesperrt, ExportDocument offen (eigenes Ticket)
P1-1 Log-Channel userabo erledigt
P1-2 Portal-Alias user_order_detail erledigt
P1-3 delete--E-Mail-Kollision erledigt
P1-4 Nicht-ASCII-E-Mails erledigt
P1-5 DHL-Felder normalisieren erledigt
P2-1 Mailversand in die Queue erledigt
P2-2 PAYONE-Fehlerbilder keine Codeaenderung – Kartenablehnungen sind Geschaeftsvorfaelle, 923/950 treten nicht mehr auf
P2-3 DHL-Tracking Retry erledigt
P2-4 Stripe-Webhook-Rauschen erledigt
P2-5 KasController Fatal offen: Serverseitig – Datei ist im Branch bereits geloescht, Deploy-Stand pruefen
P2-6 ImageMagick PDF-Policy offen: Serverseitig – policy.xml auf dem Server anpassen
P2-7 Passport Grant Type Logging entschaerft; ob der password-Grant aktiviert werden soll, ist noch zu klaeren
P2-8 Logrotation / Cron-Rauschen erledigt (Rotation loest sich mit P1-1, Erinnerungs-Logs auf debug + Zusammenfassung)

Nach dem Deploy noch zu tun

  1. php artisan view:clear – die kompilierte Blade-View des Abo-Checks liegt im Cache.
  2. Benutzer 1212 einmalig manuell aufraeumen, damit user:cleanup sauber durchlaeuft.
  3. Bestehende Umlaut-Adressen pruefen: SELECT id, email FROM users WHERE email <> CONVERT(email USING ASCII); und dasselbe fuer shopping_users.billing_email.
  4. ENV auf dem Server: DHL_ACCOUNT_NUMBER_V53PAK → DHL_ACCOUNT_NUMBER_V53WPAK (der alte Name wird als Fallback weiterhin gelesen, muss also nicht sofort umgestellt werden).
  5. Die 16 im Log genannten Auslandsbestellungen brauchen neue Labels.

Fehlerverteilung (aggregiert)

Vorkommen Meldung Quelle
109 Unable to create configured logger (Log [userabo] is not defined) laravel
89 UserMakeAboOrder::makeOrder / makePayment Error response laravel
66 DHL HTTP 400 – davon 33× „The product entered is unknown" dhl
53 Call to a member function contains() on array laravel
24 [DHL Service] Shipment creation failed (sync) laravel
21 [DHL Tracking Service] Unified API returned unexpected status (HTTP 500) laravel
18 AboRetryPaymentService::retry / makePayment Error laravel
17 Stripe-Webhook ohne zuordenbare Zahlung stripe
9 SOAP-ERROR: Parsing WSDL ... kasapi.kasserver.com laravel
9 Route [user_order_detail] not defined. laravel
7 deleteInactiveUsers failed ... Duplicate entry 'delete-…' cleanup
5 The authorization grant type is not supported (Passport) laravel
3 [DHL Controller] Failed to dispatch: shipping phone darf maximal 20 Zeichen haben laravel
2 Non-ASCII-Zeichen im local-part der E-Mail-Adresse payment / abo_order

P0 – Muss sofort behoben werden

P0-1 · Abo-Anlage im Portal wirft 500 (contains() on array)

Belege: 53×, davon 43× am 24.08. und 10× am 25.08. – der mit Abstand häufigste harte Fehler. Betroffen sind echte Kunden (userId 1039, 1174, …).

production.ERROR: Call to a member function contains() on array
  at resources/views/portal/abo/_create_check.blade.php:128

Ursache: _create_check.blade.php:128 ruft ->contains(...) auf dem Rückgabewert von getContentByOrder() auf. Yard.php:695-709 liefert aber ein PHP-Array, keine Collection:

public function getContentByOrder()
{
    $ret = [];
    // …
    $ret = array_merge($ret, $comp);
    return $ret;   // ← Array, nicht Collection
}

Eingeschleppt mit Commit 50d55f4 („Abo: Einmalprodukte bereits bei der Abo-Anlage", 21.07.2026) – seitdem bricht die Prüf-/Bestätigungsseite der Abo-Anlage ab, sobald sie gerendert wird. Der Kunde kann das Abo nicht abschließen.

Lösungsvorschlag (minimal-invasiv, keine Signaturänderung):

@php($hasOneTimeRows = collect(Yard::instance('subscription')->getContentByOrder())
    ->contains(fn ($item) => (bool) ($item->options->abo_addon ?? false)))

Alternative (sauberer, aber breitere Wirkung): getContentByOrder() auf Illuminate\Support\Collection umstellen und Rückgabetyp deklarieren. Dann müssen die weiteren Aufrufer geprüft werden – CheckoutRepository.php:134, AboController.php:784, OrderPaymentService.php:203, PaymentHelper.php:114, UserMakeOrder.php:303 sowie AboHelper::aboHasBaseProduct().

Empfehlung: Erst den Blade-Fix ausliefern (Hotfix), die Typvereinheitlichung separat mit Test. Test: Feature-Test, der die Abo-Anlage bis zum Schritt „check" durchspielt.


P0-2 · Kein einziges Auslandslabel wird erzeugt – falscher DHL-Produktcode

Belege: 33 von 33 Anfragen mit "product":"V53PAK" scheitern mit

"validationMessages":[{"property":"product","validationMessage":"The product entered is unknown."}]

Durchgehend seit mindestens 27.07.2026, betroffene Bestellungen im Log-Zeitraum: 59704, 59893, 59909, 60011, 60246, 60335, 60342, 60403, 60431, 60534, 60574, 60599, 60628, 60630, 60734, 60945. Zielländer: 27× AUT, 4× CHE, 2× ESP.

Ursache: Der Produktcode V53PAK existiert in der DHL Parcel DE Shipping API v2 nicht. Korrekt ist V53WPAK. Das steht wörtlich in der im Repo abgelegten API-Spezifikation, parcel-de-shipping-v2_2.yaml:1231:

* V01PAK: DHL PAKET;
* V53WPAK: DHL PAKET International;
enum: [V01PAK, V53WPAK, V54EPAK, V62WP, V62KP, V66WPI]

Der Rest der Anwendung verwendet bereits korrekt V53WPAK – nur der Versand-Pfad nicht. Das ist die eigentliche Inkonsistenz:

Verwendet V53WPAK (korrekt) Verwendet V53PAK (falsch)
ModalController.php:288 DhlProductResolver.php:15 INTERNATIONAL_PRODUCT_CODE
admin/dhl/create.blade.php:172, :383 config/dhl.php:99, :107
resources/lang/{de,en,es,fr}/dhl.php:27 SettingController.php:143, :152
DhlShipmentWeightCalculator.php:16
DhlModalService.php:319-320, :335

Nebenwirkung: Weil die Admin-Maske V53WPAK sendet, der Resolver aber V53PAK erwartet, wirft DhlProductResolver::resolveProductCode() für manuell angelegte Auslandssendungen zusätzlich "Produkt V53WPAK ist fuer DHL-Versand in das Zielland … nicht erlaubt."

Lösungsvorschlag:

  1. DhlProductResolver::INTERNATIONAL_PRODUCT_CODE = 'V53WPAK'.
  2. Konfig-Keys in config/dhl.php (account_numbers, dimensions) auf V53WPAK umbenennen, ENV-Namen DHL_ACCOUNT_NUMBER_V53WPAK mit Fallback auf DHL_ACCOUNT_NUMBER_V53PAK.
  3. In normalizeProductCode() einen Alias ergänzen, analog zum bestehenden V62WP → V62KP in SettingController::normalizeDhlProductCode():
    $productCode = match ($productCode) {
        'V53PAK' => 'V53WPAK',
        'V62WP'  => 'V62KP',
        default  => $productCode,
    };
    
    Damit bleiben Alt-Settings (dhl_account_v53pak in der settings-Tabelle) und gespeicherte Sendungen lauffähig.
  4. DhlShipmentWeightCalculator, DhlModalService und SettingController nachziehen.
  5. Tests anpassen: tests/Unit/Dhl/DhlProductResolverTest.php, ShippingServiceProductCodeTest.php, DhlSanitizeLoggingTest.php.

Die Abrechnungsnummer 63144073555301 ist korrekt (EKP 6314407355 + Produkt 53 + Teilnahme 01) und muss nicht geändert werden.


P0-3 · Auslandssendungen in die Schweiz brauchen zusätzlich Zolldaten

Beleg: 4 der gescheiterten Sendungen gehen nach CHE. Die Schweiz liegt außerhalb der EU-Zollunion.

Ursache: Für V53WPAK in Drittländer verlangt die DHL-API einen customs-Block (ExportDocument/CN23) – siehe parcel-de-shipping-v2_2.yaml:1059. Im gesamten Code existiert kein customs/exportDocument-Aufbau (grep customs app/ packages/ → nur VIES-VAT).

Lösungsvorschlag: Nach dem Fix aus P0-2 wird ein Teil der Sendungen weiterhin scheitern. Entweder (a) ExportDocument in ShippingService::buildPayload() ergänzen (Positionen aus den Bestellzeilen: Beschreibung, Zolltarifnummer, Menge, Wert, Gewicht, Ursprungsland), oder (b) CH vorerst aus DEFAULT_INTERNATIONAL_COUNTRIES / dem Setting dhl_international_countries nehmen und dort manuell versenden.

Empfehlung: (b) als Sofortmaßnahme, (a) als eigenes Ticket – nicht mit dem Hotfix vermischen.


P1 – Wichtig, sollte zeitnah behoben werden

P1-1 · Log-Channel userabo existiert nicht → 109 EMERGENCY-Einträge

Beleg:

laravel.EMERGENCY: Unable to create configured logger. Using emergency logger.
  InvalidArgumentException: Log [userabo] is not defined.

Ursache: MyLog::writeLog('userabo', …) wird an drei Stellen aufgerufen, aber config/logging.php kennt den Channel nicht (definiert sind: order_controller, abo_order, domain, payone, stripe, cleanup, payment, cron, dhl).

Folge: Jeder Zahlungsfehler erzeugt zwei Einträge statt einem, landet im Fallback-laravel.log statt in einer eigenen Datei und verschleiert die eigentliche Meldung.

Lösungsvorschlag: An allen drei Stellen wird direkt darüber bereits sauber geloggt:

\Log::channel('abo_order')->error('UserMakeAboOrder: Zahlungsfehler', [...]);   // existiert
MyLog::writeLog('userabo', 'error', '…', $response);                            // Channel fehlt

Der MyLog-Aufruf dient hier nur noch dem Mailversand. Sauberste Variante: 'userabo' durch 'abo_order' ersetzen – dann fällt die doppelte Datei weg und der Mailversand bleibt erhalten. Wer die Trennung will, ergänzt stattdessen einen userabo-Daily-Channel in config/logging.php.


P1-2 · Route [user_order_detail] not defined im Portal

Beleg: 9× am 14.08.2026, userId 930. Stack: resources/views/portal/abo/my_abo.blade.php:136 → resources/views/admin/abo/_executions.blade.php:68.

Ursache: Multi-Tenant-Routing. user_order_detail ist nur in routes/domains/crm.php:196 definiert. Die geteilte View admin.abo._executions wird aber auch auf der Portal-Domain gerendert, wo diese Route nicht geladen ist. In routes/domains/portal.php steht sogar der passende Kommentar:

// Routen-Aliase für shared Views (admin.abo._detail, admin.abo._executions)
Route::get('portal/my-data/edit/{id?}', …)->name('user_customer_edit');
Route::get('portal/my-orders/detail/{id}', …)->name('user_shop_order_detail');
// ← 'user_order_detail' fehlt

Der Alias für is_for === 'ot' wurde angelegt, der für is_for === 'me' vergessen.

Lösungsvorschlag: Alias in routes/domains/portal.php ergänzen:

Route::get('portal/my-orders/own-detail/{id}', [OrderController::class, 'myOrderShow'])->name('user_order_detail');

Zusätzlich in _executions.blade.php defensiv absichern (@if (Route::has('user_order_detail'))), da die View domainübergreifend genutzt wird.


P1-3 · user:cleanup scheitert seit 7 Tagen an derselben E-Mail-Kollision

Beleg: Täglich seit 20.08.2026, immer user_id: 1212:

SQLSTATE[23000]: Duplicate entry 'delete-kundin@beispiel.de'
for key 'users.users_email_unique'

Ursache: UserUtil::deleteUser() präfixt die E-Mail fest mit delete-:

$user->email = 'delete-'.$user->email;

War dieselbe Adresse bereits einmal soft-deleted, kollidiert der zweite Lauf mit dem Unique-Index. Der Cleanup bricht für diesen User ab und wiederholt den Fehler jede Nacht – der Datensatz bleibt dauerhaft ungelöscht.

Lösungsvorschlag: Präfix eindeutig machen und das Zurücksetzen anpassen. str_replace('delete-', '', …) reicht dann nicht mehr:

// UserUtil::deleteUser()
$user->email = 'delete-'.$user->id.'-'.$user->email;

// neuer Helper
public static function stripDeletePrefix(string $email): string
{
    return preg_replace('/^delete-(\d+-)?/', '', $email);
}

Anzupassende Stellen: UserUtil.php:211 (checkEmailExists), UserUtil.php:229 (restoreUser), AdminUserCleanupController.php:138, AdminUserController.php:302.

Zusätzlich: Länge der users.email-Spalte prüfen, das Präfix wächst um bis zu 13 Zeichen. Für User 1212 einmalig manuell aufräumen, damit der Cronlauf sauber durchläuft. Test: Unit-Test „zweimaliges Löschen derselben Adresse".


P1-4 · E-Mail-Adressen mit Umlauten im local-part brechen Mailversand und Abo-Erinnerung

Belege:

payment-2026-08-05.log:
  ERROR: Invalid billing email at shopping_order 59690 {"billing_email":"rüdiger.beispiel@web.de"}

abo_order-2026-08-02.log:
  ERROR: AboSendExecutionReminder: Versand fehlgeschlagen
  {"abo_id":519,"error":"Invalid addresses: non-ASCII characters not supported in local-part of email."}

Ursache: Solche Adressen kommen ins System, weil bei der Registrierung/Bestellung nicht gegen ASCII validiert wird. filter_var(FILTER_VALIDATE_EMAIL) und Symfony Mailer lehnen sie später ab.

  • Payment.php:349-352 fängt den Fall ab und schickt an config('app.checkout_mail') – der Kunde erhält seine Zahlungsbestätigung nie.
  • AboSendExecutionReminder fängt ihn nicht ab, die Ausführungserinnerung fällt komplett aus.

Lösungsvorschlag:

  1. Bei der Eingabe validieren – eigene Rule AsciiEmail, angewandt auf Registrierung, Checkout und Profil-Bearbeitung. Verhindert neue Fälle.
  2. AboSendExecutionReminder genauso absichern wie Payment::paymentStatusSendMail() (try/catch + Log), damit ein Datensatz nicht den ganzen Lauf abbricht.
  3. Bestand einmalig prüfen: SELECT id, email FROM users WHERE email <> CONVERT(email USING ASCII); und die Betroffenen anschreiben bzw. korrigieren.

P1-5 · Versand scheitert an zu langen Feldern statt sie zu bereinigen

Belege:

3× [DHL Controller] Failed to dispatch shipment creation
   {"error":"shipping phone darf maximal 20 Zeichen haben.","order_id":"59996"/"60027"/"60837"}
1× [DHL Service] Shipment creation failed (sync)
   {"order_id":60496,"error":"consignee.name2 darf maximal 50 Zeichen haben."}
3× DHL: "Parameter refNo (Shipment reference number) must be between 8 and 35 characters long."
   → gesendet wurde refNo "NL" (2 Zeichen)
2× DHL: "Please enter a valid phone number."
   → gesendet wurde z. B. "03301717813888"

Ursache: Die Telefonnummer ist für DHL ein optionales Feld. Trotzdem bricht DhlShipmentController.php:301 ('shipping_phone' => 'nullable|string|max:20') die komplette Sendungserstellung ab, wenn der Kunde die Nummer mit Leerzeichen/Bindestrichen/Vorwahl-Klammern eingegeben hat. Bei refNo fehlt umgekehrt die Mindestlänge – ein manuell eingetragenes „NL" geht ungeprüft an die API.

Lösungsvorschlag: In DhlAddressValidator bzw. DhlModalService::prepareAddressForApi() normalisieren statt validieren:

  • Telefon: Sonderzeichen entfernen (preg_replace('/[^\d+]/', '', $phone)), auf 20 Zeichen kürzen; ist das Ergebnis unplausibel (< 6 Ziffern), Feld weglassen statt die Sendung scheitern zu lassen.
  • name2/name1: auf die API-Grenzen kürzen (Str::limit(…, 50, '')).
  • refNo: Fallback Order-{id} verwenden, sobald die eingegebene Referenz kürzer als 8 Zeichen ist; 'reference' => 'nullable|string|min:8|max:35' als Validierung ergänzen (DhlShipmentController.php:289).

Grundsatz: Ein schlecht formatiertes optionales Feld darf keinen Versand blockieren.


P2 – Optimierungen / Log-Rauschen

P2-1 · MyLog::writeLog() verschickt Mails synchron

MyLog.php:31-33:

if ($mail) {
    Mail::to(config('app.exception_mail'))->send(new MailLog(...));   // blockierend
}

MailLog nutzt bereits das Queueable-Trait, wird aber mit send() statt queue() verschickt. Bei jedem Zahlungsfehler wartet der Cron auf den SMTP-Roundtrip.

Sichtbare Folge: UserMakeAboOrder läuft an Abrechnungstagen 250 s (20.08.) bzw. 234 s (25.08.), an allen anderen Tagen ~50 ms. Und am 25.08. um 04:00 kippte genau dort der SMTP-Server weg: Connection to "w017f6e4.kasserver.com:587" has been closed unexpectedly.

Lösungsvorschlag: Mail::to(...)->queue(new MailLog(...)) – Horizon läuft ohnehin. Zusätzlich den Aufruf in try/catch kapseln, damit ein Mailfehler nie den Zahllauf abbricht.


P2-2 · PAYONE-Fehlerbilder aus den Zahlläufen

89 Fehlerantworten in UserMakeAboOrder, 18 in AboRetryPaymentService. Nach Ursache getrennt:

Code Anzahl Bewertung
923 Payment type not available for this currency or card type 39 Alle am 05.04.2026, danach nie wieder → einmaliges Konfigurationsproblem, erledigt
950 Desired status change not possible for this payment process 20 Letzter Fall 22.07.2026 → durch das PAYONE-Refactoring offenbar behoben; nach Deploy des aktuellen Branch beobachten
5 / 4 / 43 / 56 / 132 Authorization declined, Card stolen … 22 Normale Kartenablehnungen, kein Bug
cardexpiredate faulty 3 Abgelaufene Karte – hier wäre eine proaktive Erinnerung vor Ablaufdatum sinnvoll
Stripe card_declined / insufficient funds 4 Normale Ablehnung

Optimierung: Kartenablehnungen sind Geschäftsvorfälle, keine Anwendungsfehler. Sie sollten als warning in abo_order laufen und nicht per Mail an exception_mail gehen – sonst geht der Blick für echte Fehler verloren. Nur „technische" Codes (923, 950, HTTP-/Timeout-Fehler) sollten alarmieren.

Zusätzlich: Ein Job, der Abos mit demnächst ablaufender Karte erkennt und den Kunden vorab zur Aktualisierung auffordert, würde die 3 cardexpiredate-Fälle und einen Teil der Wiederholungsläufe vermeiden.


P2-3 · DHL-Tracking: 21 HTTP-500 der DHL-Unified-API

WARNING: [DHL Tracking Service] Unified API returned unexpected status
{"tracking_number":"003404350651331…","status_code":500,
 "detail":"The server encountered an unexpected condition…"}

Fremdsystemfehler, kein eigener Bug. Aktuell wird pro Versuch geloggt, ohne Backoff.

Lösungsvorschlag: Retry mit exponentiellem Backoff (Http::retry(3, 200)), erst nach dem letzten Fehlversuch als warning loggen. Sendungen, die dauerhaft 500 liefern, in ein Feld tracking_last_error schreiben statt jeden Lauf neu zu protokollieren.


P2-4 · Stripe-Webhooks ohne zuordenbare Zahlung

17× checkout.session.expired, ausnahmslos ohne metadata.shopping_payment_id. StripeWebhookHandler.php:181-188 loggt das als warning und gibt korrekt true zurück (Event gilt als verarbeitet).

Abgelaufene Checkout-Sessions ohne zugehörige Zahlung sind der Normalfall bei abgebrochenen Bestellungen – kein Fehler.

Lösungsvorschlag: Für checkout.session.expired (und checkout.session.async_payment_failed) auf info herabstufen, warning nur für Eventtypen, bei denen eine Zahlung existieren muss.


P2-5 · KasController läuft auf dem Server in einen Fatal Error

Beleg: 9× am 24./25.08.2026:

FatalError: SOAP-ERROR: Parsing WSDL: Couldn't load from
'https://kasapi.kasserver.com/soap/wsdl/KasAuth.wsdl'
at app/Http/Controllers/Api/KasController.php:75

Zwei Punkte:

  1. Die Datei existiert im aktuellen Branch nicht mehr – sie wurde mit Commit d4e9d10 entfernt und liegt nur noch unter dev/app-bak/. Auf dem Server ist sie also noch deployt. Deploy-Stand prüfen.
  2. Der Code behandelt SOAP-Fehler mit trigger_error(..., E_USER_ERROR) (dev/app-bak/.../KasController.php:60) – das erzeugt einen nicht abfangbaren Fatal Error statt einer 5xx-Antwort. Falls der Controller wieder gebraucht wird: SoapFault per try/catch fangen und eine JSON-Fehlerantwort liefern.

Kontext: Alle Vorfälle liegen im Fenster 24.08. 23:35 – 25.08. 00:25, zeitgleich mit Connection could not be established with host "w017f6e4.kasserver.com:587" und [payment:check-uptime] Outage-Incident #4 für payone (24.08. 23:50). → Eine Netzwerkstörung beim Hoster, kein Anwendungsfehler. Nur die fehlende Fehlerbehandlung ist unser Problem.


P2-6 · ImageMagick verbietet PDF-Verarbeitung

Beleg: 13.08.2026, 10:31:

ERROR: PDF Verarbeitung fehlgeschlagen: attempt to perform an operation
       not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/426
ERROR: Thumbnail creation failed: …

Ursache: Serverkonfiguration, nicht Code. Die ImageMagick-Policy (/etc/ImageMagick-6/policy.xml) sperrt den PDF-Coder – Standard seit CVE-2018-16509.

Lösungsvorschlag: Auf dem Server das PDF-rights="none" in der Policy auf read|write setzen und Ghostscript aktuell halten. Im Code zusätzlich prüfen, ob die PDF-Verarbeitung verfügbar ist, und bei fehlender Berechtigung ein Platzhalter-Thumbnail liefern statt zu scheitern.


P2-7 · Passport: nicht unterstützter Grant Type

5 Vorfälle (17.08., 22.08. 04:03 und 05:53, …): Laravel\Passport\Exceptions\OAuthServerException: The authorization grant type is not supported.

Kein Stacktrace bis in Anwendungscode. Vermutlich ein API-Client, der einen nicht aktivierten Grant (z. B. password) anfordert, oder Scan-Traffic auf /oauth/token.

Lösungsvorschlag: In AuthServiceProvider prüfen, welche Grants freigeschaltet sind, und mit den API-Clients abgleichen. Falls es Fremdtraffic ist: /oauth/token als 4xx behandeln und nicht als ERROR loggen (Rate-Limit ergänzen).


P2-8 · Logrotation und Log-Rauschen

laravel.log ist 572 KB groß und enthält Einträge von 05.04.2026 bis 25.08.2026 – die tägliche Rotation greift hier nicht, weil MyLog über nicht existierende Channels in den Fallback schreibt (siehe P1-1). Nach dem Fix von P1-1 löst sich das mit auf; zusätzlich LOG_CHANNEL=daily und LOG_DAILY_DAYS prüfen.

laravel-2026-08-24.log ist 972 KB bei nur 50 Fehlern – 5.868 von 6.054 Zeilen sind Stacktraces. Die 43 identischen contains()-Traces machen den Großteil aus; mit P0-1 verschwindet das.

Cron-Rauschen: Die Zahlungserinnerungen loggen jeden geprüften Benutzer auf INFO:

Anzahl Meldung
488 Prüfe Zahlungserinnerungen für Benutzer
429 Erinnerung bereits gesendet für Benutzer
189 Zweite Erinnerung für Benutzer
146 Inaktives Konto für Benutzer

Über 1.200 Zeilen pro Woche für ~59 tatsächlich versandte Mails. Lösungsvorschlag: „geprüft"/„bereits gesendet"/„inaktiv" auf debug setzen, am Ende des Laufs eine Zusammenfassung auf INFO schreiben (geprüft: X, versendet: Y, übersprungen: Z). Tatsächlich versandte Erinnerungen bleiben auf INFO.


Hinweise ohne Handlungsbedarf

  • BusinessStoreOptimized: NOT EXECUTED - wrong day (expected: 1, today: N) – korrektes Verhalten, die Provisionsberechnung läuft nur am 1. des Monats. Der Eintrag könnte auf debug.
  • User #… attempted to create customer abo but one is already initiated (16× in order_controller) – die Schutzlogik greift wie vorgesehen. Auffällig ist nur, dass mehrere User es zweimal versuchen; ggf. ist die Rückmeldung in der Oberfläche zu unauffällig.
  • Shipping country not found for user #1056, country: (leer) – 2×, Stammdaten ohne Land. Einzelfall, Datensatz korrigieren.
  • SponsorBuyingPointsRepair: VP-Buchung liegt bei anderem Berater — manuell pruefen (Umhaengung?) (26.08., shopping_order_id: 58797, buyer_id: 1426, current_sponsor_id: 1241, booked_sponsor_id: 6) – bewusst als Warnung ausgelegt, verlangt fachliche Prüfung, keinen Code-Fix.
  • payments:check-accounts läuft täglich in 0–2 s durch, ohne Fehler.

Empfohlene Reihenfolge

# Maßnahme Aufwand Wirkung
1 P0-1 collect() im Blade Minuten Abo-Anlage im Portal funktioniert wieder
2 P0-2 V53PAK → V53WPAK ~1 h inkl. Tests Auslandsversand funktioniert wieder
3 P1-3 delete--Kollision ~1 h Nächtlicher Cleanup läuft wieder durch
4 P1-1 Log-Channel userabo Minuten 109 EMERGENCY-Einträge weg, saubere Logs
5 P1-2 Portal-Alias user_order_detail Minuten Kein 500 mehr auf „Meine Abos"
6 P1-5 DHL-Felder normalisieren ~2 h Keine blockierten Sendungen durch Telefonnummern
7 P1-4 ASCII-Validierung E-Mail ~2 h Kunden erhalten ihre Bestätigungen
8 P2-1 Mailversand in die Queue ~30 min Zahllauf von 250 s auf Sekunden
9 P0-3 Zolldaten CH eigenes Ticket Schweiz-Versand
10 P2-3/4/8 Log-Level und Retries ~2 h Auswertbare Logs