Commit Graph
3 Commits
Author SHA1 Message Date
kantarciandClaude Opus 5 a40c2bb27e SEO, Weiterleitungen und strukturierte Daten (Arbeitspaket E)
Migration 20260912000800 ergänzt page.robots, page.og_media_id,
website.settings und die Tabelle redirect.

Alles Maschinenlesbare wird aus dem veröffentlichten Bestand
abgeleitet, nichts separat gepflegt: die Sitemap listet nur
veröffentlichte, indexierbare Seiten samt Beitragsübersicht und
Begriffsarchiven, und dieselbe Einstellung setzt auch das
noindex-Meta - beide Aussagen können nicht auseinanderlaufen.

Strukturierte Daten entstehen nur aus gepflegten Werten: ohne
Angaben wird kein leerer Organization-Block ausgegeben. JSON-LD ist
ein Datenblock, kein Skript, daher bleibt script-src 'none'
unberührt.

Weiterleitungen greifen vor dem 404, aber nach der Seitensuche: eine
vorhandene Seite gewinnt immer, sonst könnte ein alter Eintrag eine
neue Seite unerreichbar machen. Ketten werden abgewiesen. robots.txt
nimmt zusätzliche Zeilen nur nach festem Muster an, damit ein
Eintrag die Datei nicht umdeuten kann. llms.txt ist standardmäßig
aus.

Geprüft: 128 PHP-Tests / 507 Assertions unter PHP 8.2.12 und 8.4.22,
14 JavaScript-Modelltests, Lint/Format/Container. Dazu eine reine
Sichtprüfung im Browser auf einer lokalen Demoseite - weiterhin
keine axe- oder Lighthouse-Messung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 12:43:00 +02:00
kantarciandClaude Opus 5 d43bd91069 Formulare mit Validierung, Einwilligung und Spamschutz (Arbeitspaket D)
Migration 20260912000700 legt form und form_submission an. Der
Formularblock im Seiteninhalt enthält nur die Adresse: Felder,
Empfänger und Einwilligungstext liegen in der Datenbank, damit ein
gespeichertes Dokument nicht ändern kann, wonach gefragt wird oder
wohin eine Anfrage geht.

Serverseitige Validierung mit einer Meldung je Feld über
aria-describedby und aria-invalid; eine Ablehnung rendert die Seite
mit HTTP 422 und allen Eingaben neu, eine gültige Absendung wird mit
HTTP 303 zurückgeleitet. Alles ohne JavaScript.

Spamschutz ohne Dienst Dritter: Honeypot, signierter Zeitstempel
gegen zu schnelle und zu alte Absendungen, fünf Absendungen je
Absender und Stunde. Ein erkannter Bot bekommt dieselbe Antwort wie
ein Erfolg. Die Absenderadresse wird nie gespeichert, nur ein Hash.

Gespeichert wird vor dem Versand, damit ein kaputter Mailversand
keine Anfrage verliert. Kein CSRF-Token auf dem öffentlichen Weg,
weil das eine Sitzung und damit ein Cookie auf jeder öffentlichen
Seite bedeuten würde; Begründung in ADR 017. Dateiuploads fehlen
bewusst.

Ein echter Fehler von den Tests gefunden: das Stundenfenster des
Limits entstand aus lokaler Zeit, die Zeitstempel aber aus UTC - auf
einer Uhr vor UTC hätte das Limit nie gegriffen.

Geprüft: 117 PHP-Tests / 450 Assertions unter PHP 8.2.12 und 8.4.22,
14 JavaScript-Modelltests, Lint/Format/Container, composer audit.
Der E-Mail-Versand wurde nie wirklich ausgeführt; keine Browser- oder
Lighthouse-Läufe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 11:51:07 +02:00
kantarciandClaude Opus 5 de9d6e3da8 Menüs ersetzen die fest verdrahtete Navigation (Arbeitspaket A)
Migration 20260912000500 legt eine Tabelle menu an: ein Menü je Platz
(header, footer) und Sprache, Elementbaum als JSON, Version für
dieselbe Konflikterkennung wie bei Seiten.

Ein Eintrag verweist auf eine Seite, auf ein Sprungziel innerhalb
einer Seite oder auf eine Adresse (HTTPS, lokaler Pfad, mailto:,
tel:). Seitenverweise speichern die Seiten-ID, nie den Pfad - ein
Eintrag folgt damit einer umbenannten Seite. Beim Rendern fallen
Einträge zu gelöschten oder unveröffentlichten Seiten heraus, ohne
den gespeicherten Baum zu ändern und ohne die übrigen Einträge zu
verlieren.

Die Verwaltung nutzt eine nummerierte Zeilenliste statt Drag-and-drop
und funktioniert damit vollständig ohne JavaScript; Untermenüs in der
Ausgabe über details/summary.

tests/bootstrap.php verwirft var/cache/test je Lauf. Ohne Debug prüft
Symfony weder den kompilierten Container noch die Vorlagen auf
Aktualität, was zweimal ein falsches Testergebnis erzeugt hat.

Geprüft: 79 PHP-Tests / 285 Assertions unter PHP 8.2.12 und 8.4.22,
11 JavaScript-Modelltests, Lint/Format/Container, Migration zuerst
gegen eine Datenbankkopie, wiederholtes Seeding. Keine Browser- oder
Lighthouse-Läufe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 10:59:23 +02:00