Two customer decisions from the September feedback round:
- New questions are now optional by default; the mandatory checkbox is
ticked deliberately (backend DCA default and frontend editor model).
Existing questions, templates and duplication are unaffected.
- Yes/no/maybe questions get a per-question display option 'Antworten
als Daumen darstellen' (showThumbs, e.g. for surveys with children):
the reader renders thumb-up/down/sideways SVG icons above the answer
labels. Purely presentational - answers are still stored, evaluated
and exported as yes/no/maybe, and the 'Keine Antwort' card, jump
hints and dim logic are unchanged. Icons are inline SVG in CI colors
(no CDN). Requires contao:migrate for the new column.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pretesters had no way to leave or restart the draft view other than
clicking through every remaining question (customer pretest finding
no. 2). The preview keeps its state exclusively in hidden POST fields,
so a plain GET on the preview URL starts over at question 1 - the new
'Umfragenentwurf von vorn beginnen' button in the preview notice bar
links exactly there and is visible on every draft page including the
completion page. Jump marks remain deliberately unsupported so the
draft view keeps mirroring the real participation flow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Duplicating a survey in the member area used to copy the source's full
editor-assignment list onto the copy. Because templates are assigned to
every member, every copy showed up in everyone's overview (customer
pretest finding no. 1, reconfirmed by Ms. Sturm on 2026-09-08 with a
template shared between two members).
A duplicate triggered from the member area (actor present) now belongs
exclusively to the member who created it and receives that member's
categories, mirroring createSurvey. Backend duplication (no actor) keeps
producing an exact 1:1 copy including all assigned members.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Actions from outdated tabs (survey deleted meanwhile, assignment revoked,
session expired) hit guard clauses that threw RuntimeException and produced
an HTTP 500 error page - seen 11x during the customer pretest on 2026-08-27
(duplicate on a deleted survey, edit link to a deleted survey). All frontend
guards now add a clear flash message and redirect to a freshly loaded view:
- list actions: distinct messages for deleted survey, revoked assignment,
expired session, unknown action
- editor: resolveSurvey redirects to the survey overview; editor POST with
invalid token redirects back to the editor
- reader/preview back button: reload the current question instead of failing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every stale reset link produced a bare 'Ungültiges Token', which sent
users into a loop of requesting ever more e-mails. The overridden core
messages now explain that only the link from the newest e-mail counts,
the auth message template offers a direct 'Neuen Link anfordern' button,
and the change-password page asks for the 'Aktuelles Passwort' with a
hint covering freshly reset passwords.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Symfony's required default forced an answer to every question no matter
what the mandatory checkbox said. Optional choice questions now offer a
dedicated 'Keine Antwort' option, optional range and text questions a
'Keine Angaben machen' checkbox (preselected for ranges, because a slider
always submits a value); the side that is not chosen gets dimmed but stays
clickable. Mandatory ranges start their value display at '?' and reject
the submit until the slider was actually used, so the browser's midpoint
default no longer leaks into the results.
Empty answers are stored as a deliberate 'no answer', kept out of counts,
averages and charts, and reported separately on the results page and in
the PDF export. Also gives the reader textarea its full width and field
styling, adds grid overflow guards for unbreakable content and styles the
form error box.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Quill 2's getSemanticHTML() serializes every space as U+00A0, turning a
whole paragraph into one unbreakable word that stretched the survey cards
far past the viewport. Normalize to plain spaces when sanitizing (which
also heals existing records on every output) and when the editor writes
the serialized HTML back into the textarea.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ergänzt einen beforeunload-Handler im Frontend-Editor: Beim Verlassen der
Seite (Link, Zurück, Tab schließen) wird gewarnt, sobald mindestens ein
Editor-Formular ungespeicherte Änderungen hat. Der Handler koppelt an die
bestehende Dirty-Erkennung (data-survey-dirty-form) und wird nur
registriert, wenn solche Formulare existieren – also nur im Editor, nicht
in Liste/Reader/Ergebnissen.
Ein bewusstes Absenden (Speichern oder Aktion) setzt über einen globalen
submit-Listener ein Flag, sodass der normale Speicher-Flow nicht warnt.
Bewusst kein Auto-Save (getrennte Formulare mit eigenen CSRF-Tokens,
Struktur-Sperre nach Teilnahmen/Veröffentlichung); Dirty-Hinweis plus
beforeunload sind der risikoarme Kompromiss.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zweite Runde Kundenrückmeldung:
- Range-Ergebnisse: Das Diagramm behält die komplette lineare Skala
(rangeMin..rangeMax), aber die Werte-Liste/Tabelle zeigt nur noch die
tatsächlich beantworteten Werte. Sonst würde eine große Skala (z. B. Alter
1-100, Schrittweite 1) die Ergebnisseite mit hunderten Nullzeilen fluten.
Neues Feld distributionRows für die Liste; distribution bleibt fürs Diagramm.
- Große Skalen: X-Achsenbeschriftung wird ausgedünnt (Chart.js autoSkip/
maxTicksLimit, SVG jede n-te Beschriftung), Punkt-Marker verkleinert bzw.
ab >40 Punkten weggelassen. Auch die Y-Ticks im PDF-SVG werden gedeckelt.
- PDF-Range-Tabelle ohne Farb-Swatch-Spalte (nur Wert/Anzahl/Anteil), da die
Kopplung an ein Vollskalen-Diagramm nicht mehr sinnvoll ist.
- Aktionslinks in der Frontend-Liste: Öffentliche Ansicht, Entwurfs-Ansicht
und Ergebnisse anzeigen öffnen wieder im neuen Fenster (target=_blank);
nur Bearbeiten bleibt im selben Tab.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>