c7439e4822
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>
522 lines
21 KiB
Markdown
522 lines
21 KiB
Markdown
# 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` |