
Internes Portal
Ein Laravel-Portal, das den Alltagsbetrieb eines Bildungsanbieters unter einem Dach zusammenführt: Kurse und Stundenpläne, Aufgaben- und Prüfungsabläufe, Ankündigungen, Helpdesk, Dateiverwaltung und Buchhaltungsanbindung. Archiv — die aktive Entwicklung endete Ende 2025.
Der Bildungsbetrieb bestand aus Arbeit, die zusammenhing, aber in getrennten Werkzeugen lief: der Stundenplan an einem Ort, Aufgaben an einem zweiten, Videoaufzeichnungen in einem dritten Dienst, die Rechnungsstellung in einem vierten. Jedes Werkzeug funktionierte für sich; was riss, waren die Verbindungen dazwischen. Wenn die Kurszugehörigkeit einer studierenden Person, ihr Zugriff auf die Aufzeichnung und der Stand ihrer Zahlung an drei Orten liegen, verbindet die drei nur das menschliche Gedächtnis. Die Aufgabe des Portals war nicht, eine neue Funktion hinzuzufügen, sondern diese Verbindungen an einer Stelle herzustellen.
Vier Rollen, vier Sichtbarkeitsstufen. Studierende: sehen den eigenen Plan, die eigenen Aufgaben und die Kursaufzeichnung; fremde Daten sind nicht erreichbar. Lehrende: verwalten eigene Kurse, Prüfungen und Teilnehmerlisten. Administration: führt Anmeldung, Planung, Ankündigungen und Supportanfragen. Super-Administration: erreicht alles, einschließlich Konfiguration und Benutzerverwaltung. Der Rollenunterschied liegt nicht nur im Menü, sondern im Datenzugriff.
Als Entwickler den größten Teil des Portals: Datenmodell, Rollen- und Berechtigungsstruktur, die meisten Module, die Anbindungen an externe Dienste und die geplanten Jobs.
Ein serverseitig gerenderter Monolith auf Laravel 10. Eine Anfrage läuft Route → Controller → Blade-View; der Datenzugriff erfolgt über Eloquent. Die Struktur ist in modulbezogene Controller geteilt: Kurse und Unterricht, Studierende und Lehrende, Prüfungen, Ankündigungen, Helpdesk, Dateiverwaltung, Karriere, Finanzen und Konfiguration. Externe Dienste sind in eigenen Controllern gebündelt — Videokonferenz, Video-Hosting, Dateispeicher, Aufgabenverfolgung, Buchhaltung, Messung und E-Mail. Für Sitzungen kommt Sanctum zum Einsatz; API-Routen liegen in einer eigenen Datei getrennt von den Web-Routen. Wiederkehrende Arbeiten sind in einer einzigen Klasse für geplante Jobs gebündelt. Auf der Berichtsseite werden PDF- und Tabellenausgaben direkt aus dem Portal erzeugt.
Das Portal spricht mit sieben externen Diensten, und jeder hat eigene Authentifizierung, eigenes Fehlerformat und eigene Ratenbegrenzung. Statt Dienstaufrufe durch die Fachlogik zu streuen, wurde jeder Dienst an einem eigenen Einstiegspunkt gebündelt; um das Verhalten eines Dienstes zu verstehen, genügt eine Datei.
KompromissDie Trennung blieb auf Dateiebene statt auf Schichtebene: Die Aufrufe stehen in den Controllern, ohne Servicelayer dahinter. Denselben Dienst von einer zweiten Stelle aufzurufen, lädt daher zum Kopieren ein, und ein Anbieterwechsel bedeutet Änderungen an mehreren Stellen.
Die vier Rollen sehen unterschiedliche Bildschirme, doch darum geht es nicht: Studierende dürfen fremde Datensätze nicht erreichen, Lehrende keine Listen außerhalb der eigenen Kurse. Die Berechtigungsprüfung wurde auf Routen- und Controller-Ebene umgesetzt, nicht bloß in der Oberfläche versteckt.
KompromissDa die Prüfung über die Anwendungsschicht verteilt ist, muss jeder neue Endpunkt sie neu aufbauen; die Regel wird auf Datenbankebene nicht erzwungen. Vergisst jemand beim Hinzufügen eines Moduls die Prüfung, fängt das nichts ab.
Die Leitung brauchte regelmäßig PDF- und Tabellenausgaben. Das einem externen Werkzeug zu überlassen, hätte Export und manuelle Aufbereitung bedeutet — also jeden Bericht von Hand. Die Ausgabeerzeugung wurde ins Portal geholt.
KompromissDie Berichtserzeugung läuft im Request-Response-Zyklus; eine große Ausgabe verlängert die Antwortzeit unmittelbar. Einen Weg über eine Warteschlange gibt es nicht.
Laravel wurde wegen der Summe dessen gewählt, was es in diesem Umfang fertig mitbringt: Authentifizierung, Berechtigungen, Migrationsverwaltung, geplante Jobs, E-Mail und eine Template-Engine in einem Framework. Serverseitiges Rendern erlaubte es, ohne eine getrennte Frontend-Anwendung und einen API-Vertrag zu arbeiten — bei Arbeit, die eine einzelne Person führt, halbiert das die Zahl beweglicher Teile. Sanctum lieferte tokenbasierten Zugriff für API-Routen, ohne einen schweren Autorisierungsserver aufzusetzen. Würde ich dieselbe Arbeit heute machen, entschiede ich mich für die Next.js-Seite; die damalige Entscheidung fiel im Kontext des Teams und der übernommenen Codebasis.
Die Authentifizierung läuft über Laravels eigene Schicht, Sitzung und API-Zugriff sind getrennt. Berechtigungsprüfungen greifen auf Routen- und Controller-Ebene, und der Unterschied zwischen den vier Rollen zeigt sich im Datenzugriff. Schlüssel externer Dienste liegen in Umgebungsvariablen. Das Portal ist ein geschlossenes System: Es hat keine öffentliche Seite, die Anmeldung führt die Verwaltung. In dieser Fallstudie wird kein echter Screenshot veröffentlicht — jeder Bildschirm trägt Daten von Studierenden und Personal.
Da es sich um ein geschlossenes System handelt, liegt keine gespeicherte, mit Datum versehene Messung vor, und es steht hier kein Score. Strukturell werden die Seiten auf dem Server erzeugt und als vollständige Seiten gesendet; auf dem Client wird keine schwere Anwendungsschicht mitgeführt. Der Preis dafür ist, dass jede Interaktion ein vollständiges Neuladen bedeutet. Auch die Berichtserzeugung läuft im Anfragezyklus, sodass die Antwortzeit mit großen Ausgaben unmittelbar wächst.
Die teuerste Lücke dieses Portals war das Fehlen automatischer Tests, und in einem System mit sieben Anbindungen zahlt man dafür: Ändert ein Anbieter sein Antwortformat, bemerkt den Fehler nur eine Nutzerin. Heute würde ich zumindest die Aufrufe externer Dienste hinter einen Servicelayer legen und diesen mit gefälschten Antworten testen — solange die Aufrufe in Controllern stehen, entsteht keine testbare Grenze. Der zweite Punkt ist die Berechtigung: Die Prüfungen blieben über die Anwendungsschicht verstreut, und jeder neue Endpunkt musste sie neu aufbauen. Eine härtere Variante desselben Musters habe ich bei Taxilos gesehen, wo die Regel an 45 Stellen wiederholt wurde und ein einziger Prädikatsfehler alle Tore öffnete. Der dritte Punkt ist die Berichterstellung: Ich würde die Ausgabeerzeugung aus dem Anfragezyklus in eine Warteschlange verlagern; heute wartet, wer einen großen Bericht anfordert, auf das Ende dieser Anfrage.
Sagen Sie mir, was Sie bauen wollen; ich sage Ihnen vorab, wie lange es dauert und wo man anfängt.