Dieser Artikel ist ein Gedankenexperiment. Er setzt voraus, was in der Realität selten gegeben ist: ausreichend Zeit, ausreichend Ressourcen und das Mandat, wirklich neu zu denken – nicht nur neu zu schreiben.
Wir haben in dieser Serie viel über Geduld gesprochen. Über schrittweise Migration, über Composer Packages, über den Wert des akkumulierten Wissens. Über createFieldMap() und ihre 13 Jahre alten Kommentare. Über den Expression Manager, der 15 Jahre unberührt blieb, weil ihn niemand anfassen konnte.
All das war die Perspektive von jemandem, der im laufenden System arbeitet. Pragmatisch, schrittweise, respektvoll gegenüber dem, was da ist.
Heute wechseln wir die Perspektive.
Nicht als Plan. Sondern als Denkexperiment darüber, welche Fragen wir bisher vielleicht nie gestellt haben.
Was wäre, wenn wir nicht im laufenden System arbeiten müssten? Was wäre, wenn die Frage nicht lautet „wie verbessern wir, was da ist“ – sondern „was soll dieses System eigentlich sein?“
Der Unterschied zwischen Rewrite und Neudenken
Ein Rewrite fragt: „Wie bauen wir dasselbe neu?“
Ein Neudenken fragt: „Was soll dieses System wirklich sein?“
Das ist kein semantischer Unterschied. Es ist ein fundamentaler. Ein Rewrite mit Feature-Parity als Ziel übernimmt alle Entscheidungen des alten Systems – die guten und die schlechten. Er übernimmt das horizontale Datenmodell, das Antworttabellen mit tausenden Spalten erzeugt. Er übernimmt die Vermischung von Core-Funktionalität und Plugin-Logik. Er übernimmt die Annahme, dass ein Survey-System zugleich Reporting-System, Participant-Management-System und Tutorial-System sein muss.
Ein Neudenken beginnt mit einer anderen Frage: Was ist der unverzichtbare Kern? Was gehört dazu – und was nicht?
Feature-Parity wäre dabei nicht das Ziel. Domänen-Klarheit wäre es.
Was aus dem Core verschwindet
LimeSurvey hat über die Jahre vieles in den Core gezogen, was dort vermutlich nie bewusst verortet wurde – nicht aus schlechter Absicht, sondern weil der Core der bequemste Ort für das nächste Feature war. Dasselbe Muster, das createFieldMap() zu einer God Function gemacht hat, hat das System schrittweise zu einem Monolithen wachsen lassen.
Teilnehmer sind eine der fundamentalsten Entscheidungen im Datenmodell – und genau deshalb gehören sie in den Core. Aber sie müssen neu gedacht werden.
Das aktuelle Modell: jede Umfrage bekommt eine eigene lime_tokens_XXXXXX-Tabelle. Das hat Vorteile – Isolation, einfaches Löschen, klare Datenzugehörigkeit pro Survey. Und Nachteile – Skalierungsprobleme, Schema-Migrations-Aufwand bei jeder Aktivierung und schwierige Cross-Survey-Queries.
Hinter diesem Modell steckt eine implizite Designentscheidung, die vermutlich nie explizit getroffen wurde: ein Teilnehmer ist eine Eigenschaft einer Umfrage. Er existiert nur in ihrem Kontext.
Die alternative Frage lautet: Ist ein Teilnehmer eine eigenständige Entität, die an einer Umfrage teilnimmt?
Das sind zwei völlig unterschiedliche Datenmodelle – mit unterschiedlichen Konsequenzen für Datenschutz, Performance, Anonymisierung und Flexibilität. Ein neu gedachtes System müsste diese Frage bewusst beantworten, statt sie durch das Datenbankschema implizit festzulegen.
Die Central Participant Database hingegen wirkt wie eine eigene Domäne: ein systemweites Adressbuch, das nicht jede Installation benötigt. Als Plugin mit klarer Schnittstelle zum Core wäre sie vermutlich besser aufgehoben als als Bestandteil desselben.
Der Unterschied ist subtil, aber entscheidend:
wie Teilnehmer einer Umfrage gespeichert werden ist eine Core-Entscheidung.
ob es ein systemweites Adressbuch gibt ist eine Plugin-Entscheidung.
Tutorials wirken rückblickend wie Dokumentation, die im falschen Medium gelandet ist.
Advanced Reporting überschreitet schnell die Grenzen des eigentlichen Survey-Kerns. Eine grundlegende Auswertung – Antwortübersicht, Exportformate, einfache Statistiken – gehört dazu. Alles darüber hinaus bildet eine eigene Domäne, die als Plugin oder sogar als separates Produkt existieren könnte.
Was übrig bleibt, ist kleiner. Klarer. Und gerade deshalb robuster.
Was neu entstehen könnte
Fragetypen als echtes Strategy-Pattern.
Heute sind Fragetypen tief im Core verankert – createFieldMap(), Expression Manager und Frontend kennen jeden einzelnen Typ. Ein neuer Fragetyp bedeutet Eingriffe an vielen Stellen gleichzeitig.
Ein neu gedachtes System würde stattdessen definieren, was ein Fragetyp können muss: wie er sich registriert, wie er rendert, wie Antworten gespeichert und validiert werden. Eigene Fragetypen ohne Core-Eingriff wären weniger eine technische Verbesserung als eine veränderte Haltung gegenüber Erweiterbarkeit.
Twig-Integration von Anfang an.
Nicht als nachträgliche Modernisierung, sondern als ursprüngliche Designentscheidung. Templates bleiben Templates; Logik bleibt Logik.
REST-API first.
Das System denkt nicht in Views, sondern in Ressourcen. Die API wäre keine Erweiterung, sondern die primäre Schnittstelle. Headless wäre damit kein Sonderfall mehr, sondern der Normalzustand.
Eine bulletproof SurveyRuntime.
Der Teil des Systems, der wirklich zuverlässig funktionieren muss: starten, navigieren, Antworten speichern, abschließen. Dieser Kern verdient maximale Simplizität, maximale Testabdeckung und besondere Zurückhaltung gegenüber Komplexität.
Architektur als Denkmodell
Domain-Driven Design bietet hier ein hilfreiches Denkmodell: klar abgegrenzte Bounded Contexts, die unterschiedliche Verantwortlichkeiten tragen könnten:
survey-core– Fragebogenstruktur und Fragetypensurvey-runtime– Ausführung einer Umfrageresponse– Speicherung und Validierung von Antwortenreporting– minimal, erweiterbarparticipant– als eigenständige Erweiterung
Man könnte sich jeden dieser Kontexte als eigenes Composer Package vorstellen – unabhängig versionierbar, testbar und mit expliziten Abhängigkeiten statt globalem State.
Hexagonale Architektur würde bedeuten, dass der Core keine Infrastruktur kennt. Datenbank, Mail oder Storage wären austauschbare Adapter. Clean Architecture würde verlangen, dass Abhängigkeiten nach innen zeigen und die Domäne keine Frameworks kennt.
Und eine Screaming Architecture würde schließlich dafür sorgen, dass bereits die Verzeichnisstruktur verrät, dass es sich um ein Survey-System handelt – nicht um eine Framework-Anwendung.
Die Programmiersprache als offene Frage
PHP ist dabei nicht selbstverständlich gegeben. Die Frage „was ist heute das richtige Werkzeug für dieses Problem?“ verdient eine ehrliche Betrachtung.
PHP hat sich stark verändert. PHP 8.x mit Enums, Readonly Properties und moderner Tooling-Landschaft unterscheidet sich fundamental von dem PHP, in dem LimeSurvey ursprünglich entstand. Ein modernes PHP-System kann ein solides Fundament sein.
Aber ein Gedankenexperiment darf diese Frage offen lassen.
Was das für den Endnutzer bedeutet
Für den Endnutzer sollte sich wenig revolutionär anfühlen. Die grundlegenden Konzepte bleiben vertraut: Fragen, Gruppen, Antworten, Teilnehmer.
Die Veränderung wäre subtiler: ein aufgeräumtes Backend, nachvollziehbare Abläufe und ein System, das sich konsistent verhält.
Unsichtbar bleibt, dass hinter dieser Oberfläche ein System steht, dessen primäres Designziel kognitive Einfachheit ist. Neue Features entstehen, ohne bestehende zu destabilisieren. Erweiterungen leben in eigenen Packages statt im Herzen des Systems.
Für Entwickler würde das bedeuten, was wir in Wann hört Legacy auf, Legacy zu sein? beschrieben haben: Der Code behindert die Arbeit nicht. Wissen steckt im System selbst statt in einzelnen Köpfen. Und der nächste Schritt bleibt jederzeit möglich.
Nicht Perfektion wäre das Ziel. Sondern ein stabiler Aggregatzustand.
Was dieses Gedankenexperiment lehrt
Selbst als hypothetische Übung hat dieses Neudenken einen Wert: Es macht explizit, was lange implizit geblieben ist.
Was sind die unverzichtbaren Domänen? Was gehört wirklich in den Core? Welche Teile verdienen maximale Stabilität – und welche bewusst lose Kopplung?
Diese Fragen sind nicht nur für ein hypothetisches Neubauprojekt relevant. Sie wirken als Kompass für jede schrittweise Migration. Wer weiß, in welche Richtung sich ein System entwickeln soll, kann auch kleine Schritte bewusst ausrichten.
Vielleicht ist das die eigentliche Erkenntnis:
Das Ziel muss nicht erreichbar sein, um nützlich zu sein.
Es muss nur klar sein.