Die häufigste Ursache für eine Laravel-Anwendung, die nach zwei Jahren niemand mehr anfassen will,
ist immer dieselbe: Controller, in denen alles steckt — Validierung, Rechteprüfung, Fachlogik,
Datenbankzugriff, E-Mail-Versand. Das funktioniert bis zur dritten Änderungsanfrage. Deshalb ziehen
wir die Schichten von Anfang an auseinander: Der Controller nimmt die Anfrage entgegen und gibt eine
Antwort zurück — mehr nicht. Die Fachlogik liegt in Services und
Actions, also in Klassen mit einer Aufgabe und einem Namen, der sie verrät.
Alles, was von außen kommt, wird vorher gefiltert. Eingaben laufen durch
Form Requests — ein Ort pro Formular, an dem die Regeln und die deutschen
Fehlermeldungen stehen, statt verstreut über Controller und Template. Berechtigungen liegen in
Policies: „Darf dieser Nutzer diesen Datensatz bearbeiten?" wird einmal
beantwortet und überall gleich geprüft, im Controller wie im View. Das Datenmodell selbst führen
wir über Migrations, damit lokal, Staging und Produktion denselben Stand
aufbauen und keine Änderung von Hand nachgeklickt wird.
Alles Langsame verlässt den Request: PDF-Erzeugung, Bildverarbeitung, Mailversand, der Aufruf einer
fremden API wandern in Queues. Der Nutzer bekommt sofort eine Antwort, ein
Worker erledigt die Arbeit nebenläufig, fehlgeschlagene Jobs landen nachvollziehbar in der
Fehlertabelle statt still zu verschwinden. Wiederkehrende Aufgaben — nächtliche Importe, Reports,
Aufräumläufe — bauen wir als eigene Artisan-Befehle und hängen sie in den
Scheduler.
Abgesichert wird das über Tests: nicht flächendeckend, sondern dort, wo Geld, Rechte oder Daten im
Spiel sind. Diese Tests laufen bei jedem Push über
Git und GitHub Actions, bevor irgendetwas
live geht. Beim Schreiben helfen uns Copilot, Cursor und Claude — jeder Stand wird von einem
Menschen gelesen, bevor er gemergt wird. Wie wir mit
KI-gestützter Entwicklung arbeiten,
steht im eigenen Stack-Kapitel.