Files
survey-bundle/AI_HANDOVER.md
T
admin.juergen c7439e4822 Fix customer-reported survey results and list issues
Behebt die Fehler aus der Kunden-Testrunde (Praktikantin, Juli 2026):

- Ergebnisreihenfolge: Fragen werden vor dem Finalisieren nach _sorting
  sortiert. finalizeQuestionResult entfernt _sorting, daher fiel die
  bisherige Nachsortierung auf den alphabetischen Fallback zurück. Online,
  PDF und Excel folgen jetzt derselben Frage-Sortierung.
- Excel-Export: Eigene Fragetext-Zeile über den Antwortspalten (je Frage
  über die zugehörigen Spalten zusammengeführt). Zuvor fehlte der Fragetext.
- Range-Ergebnis: Verteilung deckt die komplette Skala rangeMin..rangeMax in
  rangeStep-Schritten ab, damit die X-Achse linear und vollständig ist
  (vorher nur tatsächlich vorkommende Werte in gleichen Abständen).
- Teilnahmen/Rücklauf pro Frage als absolute Zahlen ("X von Y beantwortet",
  "Z übersprungen") statt reiner Prozent-Rücklaufquote.
- Freitextantworten gruppiert: jede Antwort einmal mit exakter Häufigkeit,
  ohne Prozentangaben und ohne Doppel-Auflistung.
- Frontend-Liste: "Link kopieren"-Button (absolute Reader-URL) für
  veröffentlichte Umfragen; Aktiv-Umschalter mit Textlabel statt nur Punkt;
  Aktionslinks öffnen im selben Tab statt in neuen Tabs.
- Duplizieren: Titel-Kollisionsprüfung ohne Ausschluss der Quell-ID, damit
  aus "... - Kopie" korrekt "... - Kopie 2" wird statt eines Dubletten-Titels.

Der internalNote-Fehler beim Anlegen/Duplizieren war ein fehlendes
DB-Schema-Update (Spalte tl_survey.internalNote) und wurde per
contao:migrate auf der Testumgebung nachgezogen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 19:30:34 +02:00

21 KiB
Raw Blame History

Survey Bundle AI Handover

Diese Datei beschreibt den aktuell gewünschten und umgesetzten Stand des Bundles. Ziel ist, dass ein KI-Modell oder ein neuer Bearbeiter die Logik, die Zustände und die wichtigsten Einstiegspunkte schnell versteht und darauf weiterarbeiten kann.

Zweck des Bundles

Das Bundle stellt ein Contao-Umfragesystem bereit mit:

  • Frontend-Liste für Redakteure
  • Frontend-Frageneditor
  • Öffentlicher Umfrageansicht über Alias-Link
  • Ergebnisseite im Frontend
  • Excel-Export der Ergebnisse
  • PDF-Export der Ergebnisse über Gotenberg
  • Backend-Verwaltung in Contao-DCA-Listen und Editmasken

Zentrale Zustandsfelder

Die Umfrage arbeitet mit drei relevanten Zuständen in tl_survey:

  • published

    • Fachlich: Die Umfrage wurde veröffentlicht.
    • Frontend: Ab Veröffentlichung darf der Redakteur im Frontend weder Fragen noch Metadaten bearbeiten.
    • Backend: Reversibel erlaubt. Der Admin darf den Status im Backend ändern.
  • isActive

    • Fachlich: Öffentliche Sichtbarkeit an/aus.
    • Gilt unabhängig vom Veröffentlichungsstatus als technischer Sichtbarkeitszustand.
    • Der öffentliche Reader liefert nur Umfragen aus, die published = 1 und isActive = 1 haben.
  • isLocked

    • Fachlich: Struktur wurde bereits benutzt oder veröffentlicht.
    • Wird automatisch gesetzt, wenn die erste Antwort gespeichert wird.
    • Wird beim Veröffentlichen ebenfalls gesetzt.
    • Im Backend gibt es bewusst keine harte Sperre mehr. Das Feld dient vor allem der internen Logik und Historie.

Gewollte Produktentscheidung

  • Frontend ist streng:

    • Keine Fragenbearbeitung nach Veröffentlichung
    • Keine Metadatenbearbeitung nach Veröffentlichung
    • Keine Fragenbearbeitung nach ersten Teilnahmen
  • Die Frontend-Sperre für veröffentlichte Umfragen soll bewusst nicht tief im System verankert sein.

    • Für Redakteure genügt das Ausblenden bzw. Deaktivieren der relevanten Buttons und Formulare im Frontend.
    • Es ist ausdrücklich keine zusätzliche harte Systembarriere gewünscht, solange die Redakteursoberfläche den Bearbeitungspfad sauber schließt.
  • Backend ist bewusst toleranter:

    • Ein einzelner Admin darf im Notfall weiter arbeiten
    • Statt harter Sperre gibt es nur einen Warnhinweis in der Liste bei veröffentlichten Umfragen
    • published ist im Backend editierbar
    • isActive ist im Backend per Contao-Toggle schaltbar
  • Bewusster Trade-off zwischen Frontend und Backend:

    • Ein veröffentlichter Survey soll für Frontend-Redakteure praktisch nicht mehr bearbeitbar sein.
    • Im Backend darf der Admin trotz Veröffentlichung weiterhin Änderungen vornehmen, zum Beispiel für Rechtschreibfehler oder kleine Korrekturen.
    • Dadurch bleibt bewusst das Risiko bestehen, dass der Admin auch Fragen oder Strukturen ändert, obwohl bereits Antworten vorliegen.
    • Mögliche Folgen sind verwässerte oder fachlich falsche Ergebnisseiten sowie Inkonsistenzen, wenn bestehende Antworten nicht mehr sauber zur später geänderten Struktur passen.
    • Dieses Risiko wird bewusst akzeptiert und organisatorisch über Briefing/Disziplin des Admins bzw. der zuständigen Redakteure abgefangen, nicht über eine harte technische Sperre im Backend.

Diese Entscheidung ist absichtlich so getroffen und kein Bug.

Datenmodell und wichtige Tabellen

  • tl_survey
    • Umfrage-Stammdaten und Statusfelder
    • Enthält zusätzlich die backend-only gepflegte internalNote
  • tl_survey_content
    • Fragen der Umfrage
  • tl_survey_condition
    • Generische Sprungregeln
  • tl_survey_editor
    • Zugewiesene Frontend-Redakteure
  • tl_survey_submission
    • Umfrage-Durchläufe
  • tl_survey_answer
    • Gespeicherte Antworten inklusive Snapshot-Feldern zur Ergebnisstabilität

Wichtige Snapshot-Felder in tl_survey_answer:

  • questionType
  • questionLabel
  • questionDescription
  • questionSorting

Diese Felder sorgen dafür, dass Ergebnisse auch dann stabil bleiben, wenn Fragen später im Backend verändert oder gelöscht wurden.

Frontend-Module und Controller

1. Redakteursliste

Controller:

  • src/Controller/FrontendModule/MemberSurveyListController.php

Template:

  • contao/templates/frontend/member_survey_list.html.twig

Zweck:

  • Zeigt alle dem eingeloggten Frontend-Mitglied zugewiesenen Umfragen
  • Sortierung ist bewusst fest auf Titel ASC
  • Hier liegen die Redakteursaktionen zur Veröffentlichung und Aktivierung

Aktuelle Button- und Sichtbarkeitslogik pro Umfrage:

  • Bearbeiten
    • Nur klickbar, solange published = 0
    • Nach Veröffentlichung disabled
  • Öffentliche Ansicht
    • Nur sichtbar, wenn published = 1
  • Link kopieren
    • Nur sichtbar, wenn published = 1
    • Kopiert die absolute öffentliche Reader-URL (copyUrl, erzeugt mit UrlGeneratorInterface::ABSOLUTE_URL) über den data-copy-text-Handler in _survey_assets.html.twig.
  • Entwurfs-Ansicht
    • Nur sichtbar, wenn published = 0
  • Ergebnisse anzeigen
    • Immer verfügbar, sofern Results-Seite konfiguriert ist
  • Aktionslinks (Bearbeiten, Öffentliche Ansicht, Ergebnisse anzeigen, Entwurfs-Ansicht) öffnen bewusst im selben Tab (kein target="_blank" mehr), weil der Kunde die vielen neuen Tabs als störend meldete.
  • Umfrage veröffentlichen
    • Eigene Aktion in der Liste
    • Nach Veröffentlichung disabled und textlich als veröffentlicht markiert
  • Duplizieren
    • Legt eine Kopie der Umfrage für den Redakteur an
    • Titelvergabe ist fortlaufend: Titel - Kopie, danach Titel - Kopie 2, Titel - Kopie 3 usw.
    • Bestehende - Kopie-Suffixe werden fachlich normalisiert, damit keine Titel wie ... - Kopie - Kopie mehr neu entstehen
    • Wichtig: Die Titel-Kollisionsprüfung (SurveyEditorService::buildDuplicateTitle) prüft ohne Ausschluss der Quell-ID gegen titleExists. Sonst würde beim Duplizieren einer bereits ... - Kopie-Umfrage erneut derselbe Titel vergeben statt ... - Kopie 2 (früherer Bug).
  • Aktiv-Umschalter (grauer/grüner Punkt mit Textlabel „Aktiv"/„Deaktiviert")
    • Schaltet isActive
    • Ist bewusst kein Auge mehr
    • Das Textlabel wurde ergänzt, weil der reine Punkt ohne Beschriftung für den Kunden unklar war (survey-visibility-toggle in _survey_assets.html.twig).
    • Bei isActive = 0 ist der öffentliche Reader-Link deaktiviert: SurveyRepository::findByPublicAlias verlangt published = 1 UND isActive = 1, sonst liefert der Reader die Leer-/Hinweisseite.

Wichtiger technischer Punkt (CSRF):

  • Jedes Frontend-Aktionsformular (Liste und Editor) sendet bewusst zwei Tokens:
    • REQUEST_TOKEN ({{ contao.request_token }}) nötig für Contaos globalen Frontend-POST-Gate; fehlt er, lehnt Contao den POST schon vor dem Controller mit HTTP 400 ab.
    • _token ({{ csrf_token('<aktion>-' ~ id) }}) wird im Controller mit isCsrfTokenValid('<aktion>-'.$id, $token) geprüft (session-basierter Symfony-Token).
  • Beide sind erforderlich. Frühere Stände hatten nur einen davon das führte zu „Ungültiger CSRF-Token" (500) bzw. Bad Request (400). Der Listen-Controller spiegelt jetzt exakt die Token-Mechanik des Editors.
  • Der Contao-REQUEST_TOKEN allein reicht nicht als Controller-Prüfung: Er ist cookie-gebunden und bei anonymen/fragmentierten Frontend-Requests nicht stabil (Contao setzt das CSRF-Cookie dort teils gar nicht). Deshalb die zusätzliche session-basierte _token-Prüfung.

2. Frontend-Editor

Controller:

  • src/Controller/FrontendModule/MemberSurveyEditController.php

Template:

  • contao/templates/frontend/member_survey_edit.html.twig

Zweck:

  • Anlegen neuer Umfragen
  • Bearbeiten der Metadaten vor Veröffentlichung
  • Bearbeiten der Fragenstruktur

Aktueller Aufbau:

  • Bei neuer Umfrage:
    • Titel und Beschreibung
  • Bei bestehender, nicht veröffentlichter Umfrage:
    • Metadatenformular oberhalb des Frageneditors
    • Frage-für-Frage-Editor im Akkordeon
    • Neue Frage anlegen
    • Sprungregelübersicht rechts/unten je nach Breakpoint
  • Bei veröffentlichter Umfrage oder bei isLocked = 1:
    • Fragen im Frontend nicht mehr änderbar
    • Metadaten im Frontend ebenfalls nicht mehr bearbeitbar

Wichtige Entscheidung:

  • Die Header-Badges im Fragen-Akkordeon wurden bewusst entfernt.

    • Typ, Pflicht usw. sollen nicht schon im Header gezeigt werden.
    • Die Details sieht man erst nach dem Aufklappen.
  • Die Sprungziel-Dropdowns im Frontend zeigen Positionsnummern der Umfrage (1. ..., 2. ...) statt globaler Datenbank-IDs.

    • Die aktuell bearbeitete Frage wird dort nicht als eigenes Sprungziel angeboten.

3. Öffentliche Umfrageansicht

Controller:

  • src/Controller/FrontendModule/ShowSurveyController.php

Services:

  • src/Service/SurveyFlowService.php
  • src/Service/SurveySubmissionService.php

Zweck:

  • Öffentliche Teilnahme an Umfragen
  • Zusätzlich Entwurfsansicht per ?preview=1

Wichtige Regeln:

  • Öffentliche Ansicht findet eine Umfrage nur, wenn:
    • published = 1
    • isActive = 1
  • Entwurfsansicht arbeitet ohne Speicherung
  • Öffentliche Ansicht speichert Antworten und erstellt/führt Submission fort
  • Rückwärtsnavigation ist implementiert
  • Nach Abschluss zeigt der gleiche Browser-Token für eine kurze Cooldown-Zeit (RESTART_COOLDOWN_SECONDS = 60) die Danke-Seite; danach darf dieselbe Session erneut teilnehmen (SurveySubmissionService::isRestartAllowed).

Saubere Link-URLs (Reader und Ergebnisseite):

  • Die Umfrage wird über den Alias als Pfad-Segment adressiert: /<reader-seite>/<alias> statt ?auto_item=<alias>.
  • URL-Erzeugung: per Route-Platzhalter ['parameters' => '/'.$alias] (Frontend-Liste MemberSurveyListController, Backend SurveyDcaListener::buildSurveyPageUrl), nicht ['auto_item' => $alias].
  • Auslesen im Controller: $this->getContaoAdapter(Input::class)->get('auto_item'). Wichtig: Input::get markiert den Route-Parameter als benutzt sonst wirft Contaos LegacyRouteParametersListener eine 404 wegen „unbenutzter Parameter". Ein reines $request->query->get('auto_item') reicht für Pfad-URLs nicht.

4. Ergebnisseite

Controller:

  • src/Controller/FrontendModule/ShowSurveyResultsController.php

Service:

  • src/Service/SurveyResultsViewService.php

Template:

  • contao/templates/frontend/show_survey_results.html.twig

Zweck:

  • Aggregierte Auswertung pro Frage
  • Anzeige von Anzahl Teilnahmen, Rücklauf und Frageergebnissen

Aktuelle Ergebnislogik:

  • yes_no_maybe
    • Optionsstatistik plus Kreisdiagramm
  • choice
    • Optionsstatistik plus Kreisdiagramm
  • range
    • Minimum, Maximum, Durchschnitt plus Verteilung und Linienchart
    • Die Verteilung deckt die komplette Skala von rangeMin bis rangeMax in rangeStep-Schritten ab (inkl. Werte ohne Antworten), damit die X-Achse linear und vollständig ist. Antworten außerhalb der konfigurierten Grenzen erweitern die Skala. Siehe SurveyResultsViewService::buildRangeScale.
  • text
    • Kein Pie-Chart
    • Gruppierte Freitextantworten: jede unterschiedliche Antwort einmal mit exakter Häufigkeit (responseSummary, häufigste zuerst, kein Top-5-Limit). Prozentangaben und die frühere Doppel-Auflistung wurden bewusst entfernt.

Pro Frage werden statt einer reinen Prozent-Rücklaufquote absolute Zahlen ausgewiesen:

  • totalAnswers und completedSubmissionCount als „X von Y beantwortet".
  • skippedCount (= completedSubmissionCount - totalAnswers) als „Z übersprungen", nur wenn > 0. So sind per Sprungregel übersprungene Fragen sichtbar, statt überall die volle Teilnehmerzahl zu zeigen.

Reihenfolge:

  • Die Frageergebnisse werden vor dem Finalisieren nach _sorting sortiert. Wichtig: finalizeQuestionResult entfernt die internen _sorting-Werte würde man erst danach sortieren (früherer Bug), fiele die Reihenfolge auf den alphabetischen Fallback zurück. Online-Ansicht, PDF und Excel folgen dadurch derselben Frage-Sortierung.

Wichtig:

  • Die Ergebnisse werden aus den Antwort-Snapshots aufgebaut, nicht nur aus den aktuellen Fragen.
  • Dadurch bleiben historische Ergebnisse stabil.

Sprunglogik

Relevante Services/Repos:

  • src/Service/SurveyFlowService.php
  • src/Repository/SurveyConditionRepository.php
  • src/Controller/FrontendModule/MemberSurveyEditController.php

Reihenfolge der Navigation:

  1. Direkter Ja/Nein-Sprung über jumpOnYes / jumpOnNo
  2. Generische Bedingung aus tl_survey_condition
  3. Nächste Frage nach Sortierung

Wichtiger Detailpunkt:

  • In der Sprungregelübersicht im Frontend-Editor werden bewusst die Positionsnummern innerhalb der Umfrage angezeigt, nicht die globalen Datenbank-IDs der Fragen.
  • Gleiches gilt für die Sprungziel-Dropdowns in Backend und Frontend.

Wichtige technische Eigenschaft:

  • jumpOnYes, jumpOnNo und generische Bedingungen referenzieren Ziel-Fragen intern immer über die Frage-ID, nicht über die Position.
  • Dadurch bleiben Sprünge bei einer reinen Umordnung der Fragen fachlich stabil an dieselbe Frage gebunden.
  • Wenn eine Ziel-Frage an eine andere Position verschoben wird, zeigt die Oberfläche danach automatisch die neue Positionsnummer an.

Excel-Export

Controller:

  • src/Controller/SurveyResultsExportController.php

Service:

  • src/Service/SurveyResultsExportService.php

Bibliothek:

  • phpoffice/phpspreadsheet

Zweck:

  • Export aller abgeschlossenen Teilnahmen in eine XLSX-Datei

Aktuelle Spaltenlogik:

  • Ja/Nein/Vielleicht:
    • pro Antwortoption eigene Spalte
  • Choice:
    • pro Antwortoption eigene Spalte
  • Range:
    • eine Wertespalte
  • Text:
    • eine Textspalte

Wichtige Eigenschaft:

  • Die Spalten orientieren sich an den aktuell vorhandenen Fragen im Survey.
  • Die Zeilen enthalten nur abgeschlossene Submissions.
  • Über den Antwortspalten steht eine eigene Fragetext-Zeile (F1: <Fragetext>, F2: ...). Je Frage werden die Zellen dieser Zeile über alle zugehörigen Antwortspalten zusammengeführt (mergeCells). Zuvor fehlte der Fragetext im Excel komplett der Kunde sah nur F1 ja, F1 nein usw. Reihenfolge: Titel (Zeile 1), Fragetexte (Zeile 2), Spaltenköpfe (Zeile 3), Daten ab Zeile 4; Freeze-Pane auf A4.
  • Diagramme gibt es im Excel bewusst nicht (dafür ist der PDF-Export da).

PDF-Export

Controller:

  • src/Controller/SurveyResultsExportController.php

Service:

  • src/Service/SurveyResultsPdfService.php

Template:

  • src/Resources/views/pdf/survey_results.html.twig

Externe Abhängigkeit:

  • Gotenberg über surveyGotenbergUrl in den Contao-Einstellungen

Zweck:

  • Serverseitiger PDF-Export der Ergebnisse

Aktuelle Logik:

  • HTML wird serverseitig mit Twig gerendert
  • Diagramme werden als SVG/Data-URI vorbereitet
  • Gotenberg rendert daraus das PDF
  • Ist keine Gotenberg-URL gesetzt, wird im Frontend kein PDF-Download angeboten

Backend-Aufbau

tl_survey

Dateien:

  • contao/dca/tl_survey.php
  • contao/languages/de/tl_survey.php
  • contao/languages/en/tl_survey.php

Wichtige Listenoperationen:

  • Fragen bearbeiten
  • Umfrage bearbeiten
  • isActive als Contao-Toggle
  • Warnsymbol bei veröffentlichten Umfragen
  • Link kopieren
  • Ergebnisse anzeigen

Aktuelle Listen- und Filterlogik:

  • Die mehrspaltige Umfragenliste zeigt aktuell:
    • Titel
    • Zugewiesene Benutzer
    • Vorlage
    • Interne Notiz
  • Kategorien wurden bewusst aus der mehrspaltigen Liste und aus der rechten Filterspalte entfernt.
  • Die Spalte Zugewiesene Benutzer wird in der Listenmetadatenlogik gekürzt:
    • maximal 3 Namen direkt sichtbar
    • danach Zusatz wie ... und X weitere
  • internalNote
    • backend-only Feld in tl_survey
    • nur im Backend bearbeitbar
    • in der mehrspaltigen Liste sichtbar
    • bei Duplikaten wird der Wert mitkopiert
  • In der rechten Suchspalte ist Interne Notiz suchbar.
  • ID wurde für die Umfragenliste bewusst aus dem Suchfeld entfernt.
    • Das geschieht über einen kleinen backend-spezifischen JS-Workaround, weil Contao id im Core für DC_Table hart ergänzt.

Aktuelle Backend-Entscheidung:

  • Das Warnsymbol genügt als Hinweis bei veröffentlichten Umfragen
  • Es gibt bewusst keine harte Sperre für Fragen im Backend

Child-Tabellen

  • tl_survey_content
  • tl_survey_condition
  • tl_survey_editor

Hinweis:

  • isLocked wird in den Child-Headerfeldern nicht mehr angezeigt, weil der Backend-Lock bewusst keine führende Benutzerfunktion mehr ist.
  • In tl_survey_content ist der Fragenlisten-Header zusätzlich reduziert:
    • nur noch Titel und Veröffentlicht
    • kein öffentlicher Link-Schlüssel mehr
    • die rechte Header-Leiste mit Aktionen ist im Normalzustand ausgeblendet
    • im aktiven Verschiebe-/Clipboard-Modus wird sie wieder eingeblendet, damit Neu oben bzw. die Einfügepositionen erreichbar bleiben

Fragenliste tl_survey_content:

  • Direkt sichtbare Primäraktion pro Frage:
    • Bearbeiten-Stift
  • Verschieben:
    • erfolgt im Backend über den normalen Contao-Paste-/Move-Flow
    • die Aktion Verschieben liegt bewusst nur unter den drei Punkten
    • dort wird der Contao-Pfeil mover.svg verwendet, nicht die blaue Schere
    • nach Aktivierung des Clipboard-Zustands erscheinen die üblichen Einfügeziele wie Nach dem Element ... einfügen

Systemeinstellungen

Datei:

  • contao/dca/tl_settings.php

Wichtige Settings:

  • surveyReaderPage
  • surveyResultsPage
  • surveyGotenbergUrl

Aktuelle Produktregeln in Kurzform

  • Frontend-Liste:
    • Titel alphabetisch
    • Veröffentlichung und Aktivierung in der Liste
  • Frontend-Editor:
    • Metadaten nur vor Veröffentlichung
    • Fragenbearbeitung nur solange nicht veröffentlicht und keine Teilnahmen vorliegen
  • Öffentliche Ansicht:
    • Nur published = 1 und isActive = 1
  • Backend:
    • published reversibel erlaubt
    • isActive per Standard-Contao-Toggle
    • nur Warnsymbol statt Backend-Sperre
    • Admin darf Fragen auch nach Veröffentlichung oder nach vorhandenen Antworten umsortieren

Wichtige Dateien nach Themengebiet

Frontend-Liste:

  • src/Controller/FrontendModule/MemberSurveyListController.php
  • contao/templates/frontend/member_survey_list.html.twig

Frontend-Editor:

  • src/Controller/FrontendModule/MemberSurveyEditController.php
  • contao/templates/frontend/member_survey_edit.html.twig

Öffentliche Umfrage:

  • src/Controller/FrontendModule/ShowSurveyController.php
  • src/Service/SurveyFlowService.php
  • src/Service/SurveySubmissionService.php

Ergebnisse:

  • src/Controller/FrontendModule/ShowSurveyResultsController.php
  • src/Service/SurveyResultsViewService.php
  • contao/templates/frontend/show_survey_results.html.twig

Exporte:

  • src/Controller/SurveyResultsExportController.php
  • src/Service/SurveyResultsExportService.php
  • src/Service/SurveyResultsPdfService.php

Backend:

  • contao/dca/tl_survey.php
  • src/EventListener/SurveyDcaListener.php

Technische Validierung, die in diesem Projekt gut funktioniert

  • php -l auf die geänderten PHP-Dateien
  • ddev exec php bin/console lint:yaml ...
  • ddev exec php bin/console cache:clear

Offene technische Punkte / Deployment-Hinweise

  • Neue DB-Spalte in tl_survey:

    • internalNote
    • Typ aktuell: varchar(255) NOT NULL default ''
    • Für andere Umgebungen muss diese Spalte per Migration/SQL vorhanden sein, sonst fehlen Backend-Feld, Listenanzeige und Suchfunktion fachlich bzw. führen zu Inkonsistenzen.
  • Nach Änderungen an DCA, Backend-CSS oder Backend-JS ist in dieser Installation typischerweise nötig:

    • php vendor/bin/contao-console assets:install public --symlink --relative
    • php vendor/bin/contao-console cache:clear --env=prod
  • Es gibt aktuell zwei bewusst eingebaute backend-spezifische UI-Workarounds über Bundle-Assets:

    • In der Umfragenliste wird ID aus dem Suchfeld per JS entfernt, weil Contao das Feld im Core von DC_Table hart ergänzt.
    • In der Fragenliste (table=tl_survey_content) wird die rechte Parent-Header-Leiste per CSS/JS im Normalzustand ausgeblendet und nur im aktiven Clipboard-/Verschiebe-Modus wieder eingeblendet.
  • Lokale DDEV-Besonderheit, die bei Fehleranalyse relevant sein kann:

    • Das Bundle läuft hier als Path-Repository/Symlink.
    • Wenn Backend-Übersetzungen oder Assets trotz korrektem Code unerwartet fehlen, zuerst Bundle-Pfad, veröffentlichte Assets und Prod-Cache prüfen.

Bekannte bewusste Trade-offs

  • Backend kann veröffentlichte Umfragen technisch weiterhin verändern.
    • Das ist bewusst akzeptiert, weil nur ein Admin arbeitet.
  • isLocked bleibt als internes Logikfeld bestehen, obwohl der Backend-Lock nicht mehr durchgesetzt wird.
  • PDF-Export hängt von Gotenberg ab und ist absichtlich optional.
  • Eine reine Umordnung von Fragen ist für Sprungziele logisch unkritisch, weil Sprünge an Frage-IDs hängen.
  • Ergebnisse vorhandener, weiterhin existierender Fragen folgen bei der Anzeige jedoch der aktuellen Sortierung der Frage.
    • Historische Antwort-Snapshots speichern zwar questionSorting, die Ergebnisansicht sortiert vorhandene Fragen aber primär nach der aktuellen Frage-Sortierung.
    • Das ist im toleranten Backend-Modell ein bewusst akzeptierter Side-Effect.

Empfohlene Einstiegspunkte für künftige Änderungen

  • Status-/Sichtbarkeitslogik: SurveyRepository, SurveyEditorService, MemberSurveyListController
  • Fragerouting: SurveyFlowService, SurveyConditionRepository
  • Ergebnisdarstellung: SurveyResultsViewService
  • Exportlogik: SurveyResultsExportService, SurveyResultsPdfService
  • Backend-Operationen und DCA-Verhalten: tl_survey.php, SurveyDcaListener