Kant CMS: Grundgerüst, visueller Editor, Mediathek
Symfony 7.4 / Twig / Doctrine DBAL auf herkömmlichem PHP-Webhosting. Versionierte Blockdokumente (v1-v3) mit unveränderlichen Revisionen, getrennten Entwürfen/Veröffentlichungen und optimistischer Konflikterkennung. Visueller Editor mit Strukturbaum, Live-Vorschau, responsiven Gerätewerten, Abschnittsvorlagen, Bildmediathek, Galerien und Effekten. Öffentliche Ausgabe ohne Editor-JavaScript. Geprüft: 41 PHP-Tests / 155 Assertions, 10 JavaScript-Modelltests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
commit
82b07820bc
87 files changed
+14463
No files matched your search
@@ -0,0 +1,106 @@
|
||||
# Architekturentscheidungen
|
||||
|
||||
Stand: 12.09.2026. Arbeitstitel Kant CMS; Produktname offen.
|
||||
|
||||
## ADR 001 – PHP-Webhosting, Symfony 7.4
|
||||
|
||||
Umut hat im laufenden Auftrag ausdrücklich herkömmliches PHP-Webhosting gewählt. Deshalb PHP statt des zunächst aus dem Ordnernamen vermuteten Django-Stacks. Symfony 7.4 LTS benötigt PHP ab 8.2 und bringt Routing, Dependency Injection, Konfiguration und später anschließbare Sicherheitskomponenten mit. Twig maskiert Inhalte standardmäßig. Doctrine DBAL und Migrations übernehmen Datenbankzugriff und Migrationen. Keine eigene Authentifizierung erfinden: vor HTTP-Schreibzugriffen Symfony Security, CSRF-Schutz und serverseitige Rollen ergänzen.
|
||||
|
||||
Eine Kundeninstallation ist eine Anwendung mit eigenem Datenbestand. Es gibt keine Abhängigkeit von einem dauerhaften Node-, Python- oder Queue-Prozess. Öffentliche Dateien liegen in `public/`, der Projektstamm muss außerhalb des Webroots bleiben. Konkreter Hostinganbieter, PHP-Version, Datenbank und CLI-/Deploymentmöglichkeiten sind noch offen.
|
||||
|
||||
Alternativen: Django passt nicht zum gewählten PHP-Profil. Laravel ist möglich, Symfony wurde wegen der LTS-Linie und modularen Grundlage gewählt. Ein selbst geschriebenes Mini-Framework würde Standardfunktionen unnötig neu implementieren.
|
||||
|
||||
Quellen bei Einrichtung geprüft: [Symfony 7.4 Setup](https://symfony.com/doc/7.4/setup.html), [Symfony-Versionen](https://symfony.com/releases). Exakte installierte Versionen stehen im Composer-Lockfile; PHP-Untergrenze wird im Composer-Resolver auf 8.2.12 simuliert. Auf dem Server dennoch aktuellen Sicherheits-Patchstand verwenden.
|
||||
|
||||
## ADR 002 – Versionierte Inhalte und Veröffentlichung
|
||||
|
||||
Dokumentschema v1: `schemaVersion`, `title`, `description`, `blocks`. Jeder Block hat eine stabile `id`, einen `type`, inhaltsbezogene `props`, optionale tokenbasierte `layout`-Werte und bei Containern `children`. Globale Designwerte gehören zum Website-/Template-Vertrag, nicht zu Texten. Die erste feste CSS-Vorlage nutzt bereits getrennte Designvariablen; konfigurierbare Themes folgen später.
|
||||
|
||||
Unterstützte Blöcke: section, row, column, heading, text, image, button. Alle bilden einen Baum; Layoutwerte sind Allowlist-Tokens, kein beliebiges CSS. Texte sind Klartext. Links erlauben lokale absolute Pfade, Fragmente oder HTTPS. Bilder benötigen Abmessungen und eine explizite Aussage, ob sie dekorativ sind. Begrenzungen: 256 KiB Dokument, 300 Blöcke, Tiefe 10, eindeutige IDs, genau eine Hauptüberschrift. Die aktuellen Textgrenzen zählen UTF-8-Bytes. Medienoptimierung/Uploads sind noch nicht enthalten.
|
||||
|
||||
Unbekannte Schemaversionen und Blocktypen werden beim Schreiben abgewiesen; die ursprüngliche Revision bleibt erhalten. Der Renderer enthält einen Platzhalter, aber der derzeit strikte Lesevalidator lässt unbekannte Blöcke noch nicht bis dorthin gelangen. Ein erhaltender Plugin-Fallback samt Registry ist ausdrücklich Phase 4, nicht bereits funktionsfähig.
|
||||
|
||||
Revisionen sind über den Repository-Vertrag unveränderlich. Die Datenbank schützt die Referenzen Website→Seite und Seite→Revision mit Fremdschlüsseln. Revisionszeiger auf einer Seite werden wegen des Einfügezyklus im Repository geprüft; zusätzlich fordert der öffentliche JOIN dieselbe Seiten-ID. Externe direkte Datenbankänderungen sind kein unterstützter Schreibweg.
|
||||
|
||||
Jedes Speichern/Publizieren erhöht `page.version`. Ein bedingtes UPDATE mit erwarteter Version erkennt veraltete Schreibversuche; Revisionseinfügung und Zeigeränderung laufen in einer Transaktion. Dadurch bleibt bei einem Konflikt auch keine verwaiste Revision zurück. Publizieren einer historischen Revision stellt deren Inhalt wieder her, der aktuelle Entwurf bleibt unabhängig erhalten.
|
||||
|
||||
## ADR 003 – Datenmodell
|
||||
|
||||
| Entität | Bereits implementiert / vorgesehener Vertrag |
|
||||
| --- | --- |
|
||||
| Website | ID, Name, Standardsprache, JSON-Theme-Konfiguration; aktuell eine Installation mit ID `default`. |
|
||||
| Seite | ID, Website-ID, Slug, Sprache, Entwurfs-/Veröffentlichungszeiger, Schreibversion; Slug je Website und Sprache eindeutig. |
|
||||
| Revision | ID, Seiten-ID, vollständiges versioniertes Dokument, UTC-Erstellungszeit; nächste Ausbaustufe: Benutzer/Änderungsnotiz. |
|
||||
| Block | Innerhalb des Dokuments mit stabiler ID; keine Einzelblocktabelle. |
|
||||
| CMS-Benutzer | ID, eindeutiger normalisierter Benutzername, Passwort-Hash, Rollen; hinzugefügt durch Migration 20260912000200. |
|
||||
| Medium (Entwurf) | ID, Originaldatei, MIME-Typ, Maße, Varianten, Prüfsumme; Alt-Text kontextbezogen pro Verwendung. Noch keine Tabelle. |
|
||||
| Menü (Entwurf) | ID, Website, Sprache, stabile Menüpunkt-IDs und Seitenreferenzen statt hart codierter Ziel-URLs. Aktuell feste Navigation. |
|
||||
| Template (Entwurf) | Manifest-ID, Version, unterstützte Block-/Schemaschnittstellen, Design-Tokens; derzeit feste Twig-/CSS-Vorlage. |
|
||||
|
||||
Sprachkennung und entsprechende Eindeutigkeit sind gespeichert; öffentliche Sprachwahl und Übersetzungsoberfläche fehlen. Seitentitel/Beschreibung sind Teil der Revision, damit Entwurfsmetadaten nicht öffentlich durchsickern. Sitemap, strukturierte Daten, Weiterleitungen und umfassende SEO-Einstellungen folgen später.
|
||||
|
||||
## ADR 004 – Ausgabe, Cache und Ressourcen
|
||||
|
||||
Twig rendert vollständiges semantisches HTML auf dem Server. Der öffentliche Pfad lädt nur lokales CSS und ein SVG-Favicon, kein JavaScript. Der Editor unter `/admin` hat separate CSS-/JS-Ressourcen. Sein geschützter Preview-Endpunkt rendert `page.html.twig` mit demselben validierten Blockbaum wie die öffentliche Seite.
|
||||
|
||||
Aktuell kein Inhaltscache: pro Anfrage wird die veröffentlichte Revision gelesen und `Cache-Control: no-store` gesetzt. Damit gibt es keine veralteten Seiten nach Veröffentlichung. Twig-/Containercache enthält nur Programmstruktur. Ein späterer Inhaltscache muss Revisions-IDs im Schlüssel und gezielte Invalidierung für Navigation/Sitemap berücksichtigen; die entsprechenden Tests sind dann auszubauen.
|
||||
|
||||
Canonical entsteht aus konfiguriertem `SITE_ORIGIN`, nicht dem ungeprüften Request-Host. `/home` leitet auf `/` um. Unbekannte oder unveröffentlichte Seiten liefern 404. Die öffentlichen Routen akzeptieren keine Schreibmethoden. Die geschützten Admin-Endpunkte sind in ADR 006 beschrieben.
|
||||
|
||||
## ADR 005 – Migrationen und Reproduzierbarkeit
|
||||
|
||||
`Version20260912000100` ist das erste Schema. Doctrine erzeugt plattformspezifisches SQL. SQLite lokal getestet; MySQL-Smokejob in CI vorbereitet, noch nicht tatsächlich ausgeführt. MariaDB ist noch nicht getestet. Keine Behauptung identischer Transaktions- oder Hostingbedingungen ohne Prüfung.
|
||||
|
||||
Alle künftigen Datenbankänderungen erhalten eine neue Migration; diese erste Migration später nicht nachträglich umschreiben. Dokumentänderungen brauchen explizite `vN → vN+1`-Konverter und Roundtrip-/Erhaltungstests. Die erste Migration verweigert ein zerstörerisches `down`: Rückkehr durch geprüftes Datenbankbackup und dazu passenden Code. MySQL-DDL ist nicht vollständig transaktional; vor Migrationen sichern und Wiederherstellung separat testen.
|
||||
|
||||
Lockfiles sind versionierbar, lokale DB/Secrets/Abhängigkeiten und Messartefakte ausgeschlossen. Kein Git-Remote, kein externer Dienst und keine Veröffentlichung eingerichtet.
|
||||
|
||||
## ADR 006 – Anmeldung und geschützter Editor (12.09.2026)
|
||||
|
||||
Symfony Security übernimmt Formularanmeldung, Passwortprüfung/-Upgrade, Session-Fixation-Schutz, Logout und Login-Throttling (fünf Versuche pro Minute gemäß Framework-Limiter). Der DBAL-UserProvider lädt lokale Benutzer. Beim automatischen Passwort-Rehash werden Datenbank und In-Memory-Benutzer synchron aktualisiert, damit die nächste Sessionprüfung nicht das gerade angemeldete Konto abmeldet. `EquatableInterface` vergleicht ID, Name, Passwort-Hash und Rollen; Änderungen der Berechtigungen oder Zugangsdaten invalidieren eine bestehende Sitzung.
|
||||
|
||||
Firewall nur für `/admin`: öffentliche Seiten starten keine Session und erhalten keinen Editorcode. Cookies gelten für `/admin`, mit HttpOnly, SameSite=Lax und Secure abhängig von HTTPS. Sessions liegen außerhalb von `public` unter `var/sessions/`. Alle Adminantworten, auch Fehler und Redirects, erhalten `no-store` und `noindex`. Ein initiales Konto entsteht über ein lokales CLI-Kommando mit verdeckter Passwortabfrage. Keine offene Registrierung, keine Default-Zugangsdaten, keine Browser-Passwortänderung oder vollständige Benutzerverwaltung.
|
||||
|
||||
Rollen: `ROLE_EDITOR` darf Entwürfe lesen, vorschauen und speichern. `ROLE_PUBLISHER` darf zusätzlich veröffentlichen. `ROLE_ADMIN` erbt beide Rollen. Aktuell alle Seiten einer einzelnen Installation, noch keine Rechte je Seite oder Website. HTTP-POSTs erfordern einen Symfony-CSRF-Token. Veröffentlichung prüft Rolle, erwartete Version und die konkrete gespeicherte Entwurfsrevision. Veraltete Stände liefern HTTP 409. Rückmeldungen enthalten die durch diese Anfrage geschriebene Revision, statt möglicherweise einen unmittelbar danach fremd gespeicherten Stand als eigenen Erfolg zurückzugeben.
|
||||
|
||||
Die neue Migration ergänzt `cms_user`, ohne Inhaltstabellen umzuschreiben. Der erste Editor nutzte ausschließlich Dokumentformat v1. Den nachfolgenden Ausbau zu v2 beschreibt ADR 008.
|
||||
|
||||
## ADR 007 – Editorzustand und Vorschau
|
||||
|
||||
Kleiner Editor als lokale JavaScript-Module ohne Framework. Dokumentzustand, Tree-Operationen und Undo/Redo stehen getrennt in `editor-model.js`, DOM/Netzwerk in `editor.js`. Bis zu 100 vollständige lokale Undo-Stände; aufeinanderfolgende Eingaben in dasselbe Feld werden zu einem Schritt zusammengefasst. Das gespeicherte Dokument wird inhaltlich verglichen; Undo über einen Speicherpunkt zeigt dadurch wieder „ungespeichert“. Neuladen beendet den lokalen Verlauf. Serverseitige Revisionen sind davon unabhängig.
|
||||
|
||||
Die HTML-Vorschau läuft in einem Iframe mit `sandbox="allow-same-origin"` ohne `allow-scripts`. Der Elterneditor darf die Auswahl markieren und Klicks zuordnen; Inhalte können keine eigenen Skripte, Navigationen oder Formulare ausführen. Preview-Antworten werden bei neueren Änderungen sofort als veraltet markiert, laufende Requests abgebrochen und Eingaben kurz zusammengefasst. Bei Validierungsfehlern bleibt die letzte gültige Vorschau stehen. Gespeichert wird nur nach serverseitiger Validierung. Während Speichern/Veröffentlichen sind Bearbeitungsaktionen gesperrt.
|
||||
|
||||
Bei HTTP-/Netzwerkfehlern oder 409 bleibt der lokale Dokumentzustand erhalten. JSON-Export und expliziter Server-Neuladedialog ermöglichen die Konfliktauflösung ohne stilles Überschreiben. Der Export liegt als nutzerinitiierter Download außerhalb des Repositories. Kein Autosave und kein automatischer Merge.
|
||||
|
||||
Die Browserprüfungen nutzen eine eigene Datenbank und zufällige Testzugänge. axe benötigt Skriptausführung im geprüften Frame, die Sandbox erlaubt dies absichtlich nicht: daher Adminoberfläche ohne Frameinhalt prüfen und den identischen veröffentlichten Renderer separat prüfen. Die Sandbox wird nicht für Tests abgeschwächt. Klickauswahl/Rendering im echten Frame werden durch Playwright funktional getestet.
|
||||
|
||||
## ADR 008 – Responsive Gestaltung und Dokumentformat v2
|
||||
|
||||
v2 ergänzt optional `block.layout.design` mit den Bereichen `desktop`, `tablet` und `mobile`. Die bestehenden Inhalte, IDs, Baumstruktur sowie `tone` und `width` bleiben unverändert. Erlaubte Eigenschaften, Blocktypen und Werte stehen zentral in `public/assets/design-tokens.json`: Ausrichtung, Schriftgröße/-stärke, Zeilenhöhe, Innen-/Außenabstände, Spaltenzahl/-abstand und Ecken. Der PHP-Validator und die Editorfelder lesen dasselbe Manifest. `npm run build:design` erzeugt daraus die eingecheckte `design.css`; ein Test erkennt abweichende generierte Dateien. Beliebige CSS-Werte und unbekannte Geräteschlüssel werden vor dem Speichern abgewiesen.
|
||||
|
||||
Vererbung: Desktop ist die Basis auf allen Breiten. Tablet überschreibt bis einschließlich 1024 px, Mobil bis einschließlich 650 px. Fehlende Eigenschaften übernehmen den Wert des größeren Geräts oder die ursprünglichen Theme-Regeln. „Übernehmen“ entfernt genau eine Überschreibung; „Werte zurücksetzen“ entfernt die Werte des gewählten Geräts am gewählten Block. Größere Geräte und andere Blöcke bleiben erhalten. Alle Aktionen nehmen an Undo/Redo teil. Farben und Sektionsbreite bleiben globale Blockeinstellungen im Inhaltbereich.
|
||||
|
||||
Migration v1 → v2: `upgradeDocument` in `editor-model.js` ist ein idempotenter Konverter innerhalb einer geklonten History-Transaktion. Er ändert ausschließlich die Versionsnummer; `setDesign` ergänzt anschließend den gewählten Wert. Die erste Designänderung oder eine Vorlage mit responsiven Werten löst die Umstellung aus. Öffnen, reine Texteingaben und unverändertes Speichern migrieren v1 nicht. Erst ein explizites erfolgreiches Speichern schreibt eine neue v2-Revision. Keine Datenbankmigration oder automatische Umschreibung bestehender Revisionen. Der neue Server liest, rendert und schreibt beide Versionen. Unbekannte Zukunftsversionen werden abgewiesen.
|
||||
|
||||
Rückweg: Undo der ersten Designänderung stellt auch das ursprüngliche v1-Dokument wieder her. Historische v1-Revisionen bleiben unverändert verfügbar. Ein Code-Downgrade auf einen reinen v1-Server darf erst nach Wiederherstellung passender v1-Revisionszeiger oder eines geprüften Backups erfolgen; v2-Dokumente niemals durch bloßes Entfernen der Versionsnummer als v1 ausgeben. Nach Reset aller Werte bleibt ein gespeichertes v2-Dokument v2.
|
||||
|
||||
Twig bildet validierte Tokens auf statische Klassen ab. Nur v2-Seiten laden die zusätzliche CSS-Datei; die öffentliche Ausgabe enthält weiter kein JavaScript oder Inline-CSS. Vorschau und Veröffentlichung haben denselben Renderer und dieselben Media Queries. Die Vorschau besitzt echte Layoutbreiten von 1240/768/390 px und wird bei kleiner Editorfläche visuell skaliert. Die Skalierung betrifft nur die Editoroberfläche und verändert die CSS-Breakpoints im Iframe nicht.
|
||||
|
||||
Drei lokale Abschnittsvorlagen erzeugen gewöhnliche, vollständig bearbeitbare Blöcke mit neuen IDs und H2/H3 statt einer zweiten H1. Das ist keine Plugin- oder globale Template-API. Werkzeugkasten und Struktur lassen sich einklappen; Suche zeigt passende Elemente einschließlich ihrer Vorfahren. Suchzustand, Panelwahl und eingeklappte Knoten sind reine Oberflächenzustände und werden nicht im Dokument gespeichert.
|
||||
|
||||
## ADR 009 – Bilder, Galerie und Effekte (Dokumentschema v3)
|
||||
|
||||
Migration `20260912000300` ergänzt ausschließlich die Tabelle `media`: stabile ID, Titel, vorgeschlagener Alt-Text, unveränderliche Varianten, Archivstatus, Schreibversion und UTC-Erstellungszeit. Die lokale SQLite-Datenbank wurde vor Anwendung über `VACUUM INTO` konsistent gesichert. Keine Seiten oder Benutzer wurden umgeschrieben. Ein Restore muss künftig Datenbank **und** Medienverzeichnis gemeinsam wiederherstellen.
|
||||
|
||||
Uploads und Metadatenänderungen verlangen `ROLE_EDITOR` und einen eigenen CSRF-Token. Metadaten nutzen erwartete Versionen; konkurrierende Änderungen liefern 409. Bildtitel/Alt-Text im Medienkatalog sind Vorlagen für künftiges Einfügen. Bereits gespeicherte Seiten behalten ihre kontextbezogenen Texte, Beschriftungen und Bildvarianten. Archivieren blendet Bilder aus der normalen Auswahl aus und ist umkehrbar; bestehende URLs, Seiten und Undo-Stände bleiben funktionsfähig. Es gibt noch keine physische Löschung, Nutzungsübersicht, Ordner oder Katalog-Paginierung.
|
||||
|
||||
Nur tatsächlich decodierbare JPEG-, PNG- und WebP-Dateien werden angenommen. Dateinamen und vom Browser gemeldete MIME-Typen bestimmen weder Speicherpfade noch Dateiformat. Maximal 8 MiB, 12 Millionen Pixel und 8000 px pro Kante; zusätzlich konservative Prüfung gegen das PHP-Speicherlimit. GD decodiert und erzeugt WebP-Varianten bis 480/960/1600 px Breite ohne Hochskalieren. Das hochgeladene Original wird nicht übernommen; Metadaten und angehängte Nutzdaten werden nicht in die Varianten kopiert. EXIF-Orientierung wird bei JPEG berücksichtigt, sofern die EXIF-Erweiterung vorhanden ist. Transparenz wird erhalten; animierte Bilder/Dateianhänge/SVG gehören nicht zum unterstützten Uploadvertrag. Grundlage: [PHP-Bilddecodierung](https://www.php.net/manual/en/function.imagecreatefromstring.php).
|
||||
|
||||
Dateien liegen unter `MEDIA_DIRECTORY`, standardmäßig `var/media` außerhalb des Webroots. Nur zufällige IDs und bekannte Variantengrößen gelangen über `/media/{id}/{width}` mit festem `image/webp`, `nosniff` und unveränderlichem Langzeitcache nach außen. Erweiterungslose URLs funktionieren auch über die Frontcontroller-Weiterleitung des lokalen PHP-Servers; Pfade mit nicht vorhandenen `.webp`-Dateien wurden dort als statische 404 behandelt. Bild-URLs sind öffentlich, auch vor Veröffentlichung einer Seite und nach Archivieren; der Uploaddialog benennt dies. Die Katalog-API bleibt geschützt. Dies ist keine private Dokumentablage.
|
||||
|
||||
Schema v3 ergänzt den Container `gallery`, dessen Kinder ausschließlich Bildblöcke sein dürfen. Bestehende Baumaktionen (Auswahl, Verschieben, Löschen, Duplizieren, Undo) gelten auch für Galerieelemente; unpassende Verschiebeziele werden bereits im Modell und zusätzlich vom Server abgewiesen. Bilder dürfen `mediaId`, `sources` und eine Klartext-`caption` enthalten. Quellen für `srcset` werden einzeln auf URL und Breite geprüft. Die Ausgabe verwendet `figure`/`figcaption`, reale Maße, verzögertes Laden und responsive Quellen. Galerie-Spalten und Abstände nutzen dieselben responsiven Tokens wie Zeilen. Keine Lightbox oder Slideshow in diesem Schritt.
|
||||
|
||||
`layout.effects` erlaubt nur vordefinierte Schatten, Hover-Anheben/Bildzoom sowie Einblenden beim Laden. Effekte gelten geräteübergreifend. Die CSS-Datei wird nur für v3-Seiten eingebunden; es wird kein öffentliches JavaScript ergänzt. Bewegungsregeln gelten ausschließlich bei `prefers-reduced-motion: no-preference`. Inhalte bleiben ohne Animation lesbar; Einblendung ist keine scrollgesteuerte Animation.
|
||||
|
||||
Der idempotente Konverter unterstützt nun v1/v2 → v3 und verhindert Downgrades. Erst Einfügen einer Galerie/eines Katalogbildes, eine Bildbeschriftung oder Effektänderung hebt den lokalen Entwurf auf v3. Die Umstellung ist Teil derselben Undo-Transaktion; Speichern erzeugt eine neue Revision. v1/v2 bleiben les- und schreibbar. Kein Massendatenupdate. Rückweg über alte Revisionen oder gemeinsames Backup plus passenden Code; ältere v1/v2-Software darf keine v3-Revisionen laden. Die neue Medientabelle darf beim Rückweg nicht unbedacht gelöscht werden.
|
||||
@@ -0,0 +1,78 @@
|
||||
# Qualitätsbericht – erster ausführbarer Prototyp
|
||||
|
||||
## Ergänzung: Medienverwaltung, Galerie und Effekte, 12.09.2026
|
||||
|
||||
- **41 PHP-Tests / 155 Assertions** unter PHP 8.2.12 und 8.4.22 sowie **10 JavaScript-Modelltests** bestanden. Neu: geschützte Medien-API/CSRF, als JPEG getarnte SVG-Abweisung, tatsächliche Bilddecodierung/Neuencodierung, entfernte angehängte Nutzdaten, drei WebP-Varianten, Metadata-CAS/409, Archivieren/Wiederherstellen und weiter erreichbare Bilddateien. Zusätzlich ungültige Effekt-/Schemaschlüssel, Galerie-Kindtypen und `srcset`-Quellen sowie v3-Undo und Galerie-Verschieberegeln geprüft.
|
||||
- Isolierter Browserablauf mit eigenen Datenbanken/Medienordnern bestanden: Upload von zwei lokal erzeugten Testillustrationen, Titel und Alt-Texte speichern, Mehrfachauswahl per Tastatur mit Fokus-Erhalt, Galerieeinfügen, Bildbeschriftung, Sortieren/Undo, responsive Spalten, Schatten/Hover/Einblendung und Bewegungsreduktion. Archivieren erhält URLs, Wiederherstellen erlaubt erneute Auswahl. Bilder und Bildquellen bleiben nach Speichern/Neuladen/Publizieren funktionsfähig. Bestehende Rechte-, Netzwerk-/Konflikt- und Editorprüfungen weiterhin erfolgreich.
|
||||
- Keine axe-Verstöße in Medienauswahl und mobiler Mediathek sowie den bisherigen Login-/Seiten-/Editor- und öffentlichen Prüfungen. Desktop- und Mobil-Mediathek und öffentliche Galerieseite anhand der Screenshots geprüft. Alle drei bestehenden öffentlichen Seiten erneut mit/ohne JavaScript und bei 1440/390 px geprüft. Sandbox-Prüfgrenze weiterhin wie unten beschrieben; keine vollständige manuelle Screenreader-Abnahme.
|
||||
- **Lighthouse 13.4.1: drei mobile und drei echte Desktopläufe auf der veröffentlichten v3-Galerieseite; alle fünf Kategoriescores in jedem Lauf 100.** LCP-Median mobil **937 ms**, Desktop **279 ms**, CLS **0**, TBT **0 ms**. PHP 8.2.12, SQLite, lokaler Produktionsmodus, GD-generierte Landschaftsillustrationen mit WebP-Varianten statt realer Kundenfotos. Rohdaten `reports/lighthouse-editor`, Metadaten `docs/quality/editor-media-lighthouse.json`, Browserbericht `docs/quality/editor-media-browser.json`. Reproduktion über `npm run test:editor -- --audit`.
|
||||
- Migration 003 zuerst in Tests, anschließend lokal nach konsistentem SQLite-Backup angewendet. Keine Umschreibung echter Seitendokumente, keine Testuploads in den echten Medienordner, kein Browser-Neuladen des Nutzerentwurfs. Lokaler PHP-Prozess anschließend mit 8M Upload-/10M POST-/256M Speicherlimit gestartet. PHP-Format-, Twig-/YAML-/Container-, Composer- und Produktionsbuild-Prüfungen bestanden; Composer meldet keine bekannten Advisories.
|
||||
|
||||
Die öffentlichen Medien-URLs waren im ersten Browserlauf wegen des lokalen PHP-Servers mit `.webp`-Suffix nicht an den Frontcontroller weitergegeben worden. Erweiterungslose Routen beheben dies; tatsächliches Laden der Bilddateien wird jetzt ausdrücklich im Browser geprüft. Keine Hosting-/MySQL-/Restore-Abnahme, keine Felddaten und keine Aussage über beliebige hochgeladene Bilder oder Effekte auf Kundenwebsites.
|
||||
|
||||
## Ergänzung: responsive Editorgestaltung, 12.09.2026
|
||||
|
||||
- **34 PHP-Tests / 120 Assertions** unter PHP 8.2.12 und 8.4.22 erfolgreich. Zusätzlich zu den Sicherheits-/Revisionsprüfungen: v1/v2 lesen und speichern, originale Veröffentlichung erhalten, v1 wiederherstellen, validierte Gestaltungsklassen ohne Inline-CSS/JavaScript sowie Zurückweisung falscher Geräte, ungeeigneter Blockeigenschaften, unbekannter Tokens und zukünftiger Versionen.
|
||||
- **9 JavaScript-Modelltests** erfolgreich: ergänzt um idempotente, inhaltserhaltende Migration; Gerätevererbung/Reset/Undo; atomare Vorlagen mit neuen IDs und genau einer H1; Abgleich des generierten CSS mit dem zentralen Tokenmanifest.
|
||||
- Erweiterter Playwright-Ablauf auf eigener Datenbank erfolgreich: einklappbare Struktur/Werkzeugkasten, Suche und Auswahl per Tastatur, Schriftgröße/Ausrichtung/Abstände auf Desktop/Tablet/Mobil, echte Iframebreiten, Vererbung und Zurücksetzen samt Undo, Zweispaltenvorlage mit mobilem Umbruch. Danach Speichern, Neuladen und Veröffentlichen; berechnete öffentliche Styles auf 1600/768/390 px gegen die Vorschauwerte geprüft. Bestehende Fehler-/Konflikt-/Drag-and-drop-Prüfungen bleiben Bestandteil des Ablaufs.
|
||||
- Keine axe-Verstöße in Login, Seitenliste, Desktop-/Mobil-Editor und gestalteter öffentlicher Mobilseite. Screenshotkontrolle von Desktop-Editor, Mobil-Editor und veröffentlichter Mobilseite erfolgreich; kein horizontaler Überlauf. Die unten beschriebene Einschränkung der scriptgesperrten Frameprüfung gilt weiterhin. Kompaktbericht: `docs/quality/editor-design-browser.json`.
|
||||
- Alle drei bestehenden öffentlichen v1-Beispielseiten erneut bei 1440/390 px geprüft; sechs erfolgreiche Accessibility-Prüfungen plus Tastatur- und Navigation ohne JavaScript.
|
||||
- **Lighthouse 13.4.1 auf der isolierten, veröffentlichten v2-Seite**, einschließlich Design-CSS und eingefügter responsiver Abschnittsvorlage: drei mobile und drei echte Desktopläufe, alle fünf Kategoriescores in jedem Lauf **100**. LCP-Median mobil **901 ms**, Desktop **240 ms**, CLS **0**, TBT **0 ms**. Produktionsmodus, PHP 8.2.12, SQLite und lokaler PHP-Server; Chromium/Profilparameter im Bericht `docs/quality/editor-design-lighthouse.json`, Rohdaten unter `reports/lighthouse-editor`. Der Test läuft reproduzierbar mit `npm run test:editor -- --audit` und ist in CI vorgesehen; externe CI weiterhin nicht ausgeführt.
|
||||
- PHP-Format-, Twig-/YAML-/Containerprüfungen, JavaScript-Syntaxprüfung, Diff-Prüfung und Produktionscacheaufbau erfolgreich. Die zusätzlichen Designressourcen werden nur für v2-Dokumente geladen. Auf dem PHP-Hosting ist kein Node-Prozess nötig.
|
||||
|
||||
Weiterhin kleine lokale Testinhalte: keine Pilotkundenabnahme, keine Felddaten/INP-Aussage, keine umfassende Screenreaderprüfung und kein Nachweis für beliebige Gestaltungsentscheidungen. PHP-Webhosting und MySQL/MariaDB bleiben ungeprüft. Der echte Seitenbestand und der bereits geöffnete Browserentwurf wurden nicht für Tests geändert.
|
||||
|
||||
Die folgenden Abschnitte dokumentieren die früheren Entwicklungsstände und deren damalige Messungen.
|
||||
|
||||
## Ergänzung: erster visueller Editor, 12.09.2026
|
||||
|
||||
Die folgenden Ergebnisse betreffen den neuen Editor; die ursprüngliche Phase-0-Messung bleibt darunter als Ausgangsstand erhalten.
|
||||
|
||||
- **27 PHP-Tests, 105 Assertions**, erfolgreich unter PHP 8.2.12 und 8.4.22. Ergänzt: geschützte Admin-/API-Routen, Login-CSRF und falsches Passwort, CSRF für alle Schreib-/Vorschauaktionen, Editor ohne Veröffentlichungsrecht, HTTP-422/409-Behandlung, konkrete Revisionsprüfung, privater Entwurf und anschließende Veröffentlichung, Logout-CSRF, Passwort-Rehash und Sessioninvalidierung bei Rollenänderung.
|
||||
- **5 JavaScript-Modelltests** für Undo/Redo samt Speicherpunkt, Zusammenfassung von Texteingaben, unveränderte History-Snapshots, neue IDs beim Duplizieren, Zyklenschutz beim Verschieben und identischen JSON-Roundtrip.
|
||||
- **End-to-End-Editorprüfung** mit Playwright: echte Formularanmeldung, Klickauswahl im Iframe, Eigenschaftenänderung und Live-Vorschau, Undo/Redo, Einfügen/Duplizieren/Verschieben einschließlich Drag-and-drop/Löschen, Speichern und identisches Neuladen, Entwurfsprivatheit, separate Veröffentlichung, Escape/Fokusrückkehr im Dialog, abgefangener Netzwerkabbruch mit erneutem Speichern, 409-Konflikt ohne Verlust lokaler Änderungen, JSON-Download und bestätigtes Laden des Serverstands. Eigene Testdatenbank und Zufallszugänge unter `var/browser-tests`; echte Seiten und Benutzer bleiben durch diese Tests unverändert.
|
||||
- axe-core: keine gefundenen Verstöße in Login, Seitenübersicht, Desktop- und Mobil-Editor sowie separat in der bearbeiteten öffentlichen Ausgabe. Die scriptgesperrte Vorschau kann den axe-Frameworker nicht ausführen. Der Frameinhalt wird deshalb in der Editor-axe-Prüfung ausgeschlossen und seine identische öffentliche Ausgabe separat geprüft; die Frameauswahl und Bearbeitung sind weiterhin funktional im realen Sandbox-Iframe getestet. Diese Einschränkung ist keine vollständige Barrierefreiheitsabnahme.
|
||||
- Visuell geprüft: Editor-Desktop bei 1600 × 1100 und Mobil bei 390 × 844, Screenshots unter `reports/editor`. Scrollbereich ist per Tastatur fokussierbar. Keine horizontalen Überläufe in der Mobilprüfung.
|
||||
- Öffentliche Browser-Regression: alle drei unveränderten Beispielseiten bei 1440 und 390 px erfolgreich, kein Editor-JavaScript und kein zusätzliches Session-Cookie auf der öffentlichen Route.
|
||||
- Erneute **Lighthouse-13.4.1-Messung** mit drei echten Mobil-/Desktop-Läufen im Produktionsmodus: jeweils 100 in allen fünf Kategorien. LCP-Mediane jetzt mobil 803 ms, Desktop 252 ms, CLS 0 und TBT 0 ms. Gleiches kleines lokales Testszenario und dieselben Grenzen wie unten; keine reale Kundenabnahme oder Felddaten. Metadaten: `docs/quality/editor-public-lighthouse.json`.
|
||||
- Composer Audit ohne bekannte Advisories; Composer-Validierung, PHP-Formatierung, Twig-/YAML-/Containerprüfung, JavaScript-Syntaxprüfung erfolgreich. CI wurde um Modell- und Editorprüfungen ergänzt, aber nicht extern ausgeführt. MySQL/MariaDB/Hosting bleiben ungetestet.
|
||||
|
||||
Der lokale Benutzer `umut` wurde getrennt von den Tests auf ausdrücklichen Nutzerwunsch angelegt und im In-App-Browser angemeldet. Keine Zugangsdaten in Quellen oder Dokumentation abgelegt.
|
||||
|
||||
---
|
||||
|
||||
Datum: 12.09.2026. Ziel: `http://127.0.0.1:8080/`. Diese Messung betrifft ausschließlich die lokale Kant-CMS-Demoseite, keine bestehende Kundenwebsite und nicht `kant-it.de`.
|
||||
|
||||
## Tatsächlich ausgeführte Prüfungen
|
||||
|
||||
- PHPUnit 11.5.56: 19 Tests, 35 Assertions erfolgreich unter PHP 8.2.12 und PHP 8.4.22. Dokument-Roundtrip, Entwurfsprivatheit, abgewiesene veraltete Schreibzugriffe, Transaktionsrollback, fremde Revisionen, Wiederherstellung, XSS-Maskierung, ungültige URLs/Designwerte/Block-IDs, Canonical, 404 und verweigerte HTTP-Schreibmethoden.
|
||||
- Composer-Validierung, PHP-Formatprüfung, Twig-/YAML-/Containerprüfung und produktiver Cacheaufbau erfolgreich. Composer Audit und npm install meldeten keine bekannten Paketlücken zum Prüfzeitpunkt.
|
||||
- Frische Kopie der für Git vorgesehenen Quellen unter `var/fresh-check`: `composer install --no-dev`, Setup, erste Migration, Seeding zweimal, Produktionscache und Symfony-Request erfolgreich. Gespeicherter Inhalt erscheint mit HTTP 200; zweites Seeding verändert vorhandene Seiten nicht.
|
||||
- Playwright 1.63.0 / Chromium 153.0.8010.12 und axe-core 4.13.0: `/`, `/grundlagen`, `/projektstand`, jeweils mit 1440 und 390 px Breite; keine axe-Verstöße in den ausgewählten WCAG-2-A/AA-, WCAG-2.1-AA- und Best-Practice-Regeln. Je Kombination 29 bestandene axe-Prüfungen. Kein horizontaler Überlauf oder JavaScript-Seitenfehler.
|
||||
- Automatisierte Tastaturprüfung des Sprunglinks und Navigation, zusätzlich Navigation mit deaktiviertem JavaScript erfolgreich. Desktop- und Mobil-Screenshots der Startseite visuell durchgesehen.
|
||||
|
||||
## Lighthouse
|
||||
|
||||
Lighthouse 13.4.1, Chromium Headless 153.0.8010.12 unter Windows; PHP 8.4.22 mit `APP_ENV=prod`, `APP_DEBUG=0`, vorgewärmtem Symfony-Cache, SQLite, lokalem PHP-Entwicklungsserver. Vollständige gespeicherte HTML-Inhalte, keine externen Dienste, keine Editor-Ressourcen. Netzwerk-/CPU-Drosselung simuliert. Drei Läufe je Profil, Median:
|
||||
|
||||
| Profil | Leistung | Barrierefreiheit | Best Practices | SEO | Agentisches Browsing | LCP | CLS | TBT |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
||||
| Mobil | 100 | 100 | 100 | 100 | 100 | 797 ms | 0 | 0 ms |
|
||||
| Desktop | 100 | 100 | 100 | 100 | 100 | 261 ms | 0 | 0 ms |
|
||||
|
||||
Alle sechs endgültigen Läufe hatten diese Kategoriescores. Mobil: 412 × 823 px, DPR 1,75, RTT 150 ms, 1.638,4 Kbit/s Durchsatz, CPU-Faktor 4. Desktop: 1350 × 940 px, DPR 1, RTT 40 ms, 10.240 Kbit/s Durchsatz, CPU-Faktor 1. Detailparameter und Umgebungsmetadaten stehen in `docs/quality/lighthouse-summary.json`. Das Skript prüft die tatsächliche `formFactor`-Einstellung und lehnt indexierungsgesperrte Antworten vor dem Audit ab.
|
||||
|
||||
Agentisches Browsing: Die anwendbaren Prüfungen `agent-accessibility-tree` und `cumulative-layout-shift` bestanden. `webmcp-form-coverage`, `webmcp-registered-tools`, `webmcp-schema-validity` und `llms-txt` waren **nicht anwendbar**, nicht als implementierte Funktionen bestanden. Es gibt noch keine Formulare, WebMCP-Tools oder llms.txt.
|
||||
|
||||
## Grenzen und noch ausstehende Abnahme
|
||||
|
||||
- Die kleine Demoseite hat bewusst keine echten Kundenbilder, Blogbeiträge oder Formulare. Deshalb ist sie nur eine technische Regressionsbasis und erfüllt noch nicht die im Plan geforderte repräsentative Referenzsuite. Die Werte nicht als Leistungsnachweis für Kundenwebsites verwenden.
|
||||
- INP und die Core-Web-Vitals-Feldwerte am 75. Perzentil sind unbekannt. Der gemessene TBT ist kein INP. Es gibt keine realen Nutzungsdaten.
|
||||
- Manuelle Screenreader-Prüfung, vollständige manuelle Tastatur-/Kontrast-/Zoomprüfung, Dialoge, Formulare und responsive Editorabläufe fehlen. Visuelle Screenshotkontrolle und automatisierte axe-Prüfungen ersetzen sie nicht.
|
||||
- MySQL-/MariaDB-Betrieb, Apache-Rewrites, tatsächliches PHP-Webhosting, HTTPS-Konfiguration, Restore und externe CI-Ausführung wurden nicht getestet. Ein MySQL-Smokejob ist vorbereitet.
|
||||
- GEO, Auffindbarkeit und Zitierung in KI-Antworten wurden nicht geprüft. Keine Ranking- oder Zitiergarantie.
|
||||
- Die rohe Auditserie und Browser-Screenshots liegen lokal in `reports/` und sind nicht für Git vorgesehen. Die kompakte Zusammenfassung und dieser Bericht werden mit den Quellen abgelegt.
|
||||
|
||||
## Im Verlauf behoben
|
||||
|
||||
Mobiler Textüberlauf bei langen deutschen Wörtern; fehlende Übernahme realer Prozessvariablen bei PHP-Konfiguration ohne `E` in `variables_order` (dadurch blieb Debug/noindex aktiv); anfänglich falsch übergebener Desktop-Preset an die Lighthouse-Programmierschnittstelle; unter Windows gesperrte temporäre Testdatenbank sowie Cleanup des anfänglichen Chrome-Launchers. Die endgültigen oben dokumentierten Prüfungen liefen nach diesen Korrekturen erfolgreich.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Anforderungen und Analyse des Entwicklungsplans
|
||||
|
||||
Stand: 12.09.2026.
|
||||
|
||||
Die beiden Dokumente sind unveränderte Planungsvorlagen aus Downloads. Aussagen wie „kein Repository eingerichtet“ oder „dieser Chat hat derzeit keinen Zugriff“ beschreiben ihren ursprünglichen Entstehungskontext. Der aktuelle Implementierungsstand wird in STATUS gepflegt. Aus dem mehrphasigen Plan folgt keine Behauptung, das vollständige CMS sei mit dem initialen Auftrag fertigzustellen oder fertiggestellt.
|
||||
|
||||
## Bestätigt
|
||||
|
||||
- Eigenständiges CMS für Kundenwebsites; ein visuell bedienbarer Editor als Kernziel.
|
||||
- Explizite aktuelle Nutzerantwort: herkömmliches PHP-Webhosting.
|
||||
- Öffentliche HTML-Ausgabe ohne Editorpaket; versionierte Blöcke, getrennte Entwürfe/Publikationen.
|
||||
- Leistung, Barrierefreiheit, Best Practices, SEO und agentisches Browsing ab dem ersten Prototyp überprüfen.
|
||||
- Noch keine externe Veröffentlichung beauftragt.
|
||||
|
||||
## Noch offen, aber kein Hindernis für das lokale Grundgerüst
|
||||
|
||||
- Pilotwebsite: `kant-it.de` wurde im Plan als Messbeispiel erwähnt, ist noch nicht als Pilot ausgewählt.
|
||||
- Hostinganbieter/-tarif, PHP-Version, Datenbankversion, Dokumentenstamm und CLI-/Deploymentzugriff.
|
||||
- Tatsächliche Flatsome-Referenz und häufig genutzte Workflows: keine Screenshots/Demo übergeben, keine Referenzanalyse behauptet.
|
||||
- Produktname, echte Kundeninhalte, Menüs, Seitentypen, Formulare und Sprachumfang.
|
||||
|
||||
## Geplanter erster Editorablauf
|
||||
|
||||
1. Eine vorhandene Seite auswählen und den gespeicherten Entwurf laden.
|
||||
2. Sektion, Zeile oder Spalte über die Elementbibliothek anlegen.
|
||||
3. Überschrift, Text, Bild und Link einfügen; Auswahl in Baum und Vorschau synchron halten.
|
||||
4. Eigenschaften im Panel ändern; mobile Vorschau und Vererbungsmodell sichtbar machen.
|
||||
5. Elemente verschieben, duplizieren und löschen; zusätzlich tastaturbedienbare Schaltflächen bereitstellen.
|
||||
6. Änderung rückgängig machen/wiederholen; gespeicherten Stand von lokalem Undo-Verlauf unterscheiden.
|
||||
7. Speichern mit sichtbarem Zustand; Konflikt beim veralteten Versionsstand anzeigen.
|
||||
8. Veröffentlichung gesondert auslösen; dieselben Blöcke auf der öffentlichen Route prüfen.
|
||||
|
||||
Das ist ein Arbeitsentwurf aus dem Plan, keine nachgewiesene Flatsome-Funktionsgleichheit. Vor Freischalten von Editor-Schreibwegen sind Symfony Security, CSRF und serverseitige Berechtigungen nötig, auch wenn der große CMS-Ausbau im Plan erst später folgt.
|
||||
|
||||
## Priorisierung
|
||||
|
||||
Der initiale Abschnitt schließt die ausführbare technische Grundlage von Phase 0 ab. Die Anforderungsabnahme dieser Phase bleibt wegen Pilot-/Hostingdetails und Referenz offen. Der Editor bietet kontrollierte Layout-/Typografiewerte, responsive Vererbung, Abschnittsvorlagen, Werkzeuge für lange Blockbäume sowie Bildmediathek, Galerien und Effekte. Seitenerstellung und vollständiger Referenzabgleich fehlen noch. Plugins, umfassendes SEO und WordPress-Migration sind keine bereits implementierten Funktionen.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Projektstatus
|
||||
|
||||
Stand: 12.09.2026. Arbeitstitel Kant CMS. **Editor mit Gestaltung, responsiven Werten, Abschnittsvorlagen, Medienverwaltung, Galerien und Effekten. Die vollständige Phase-1-Abnahme bleibt wegen fehlender Seitenerstellung und Referenzabgleich offen.**
|
||||
|
||||
## Erledigt
|
||||
|
||||
- `AGENTS.md` und `ENTWICKLUNGSPLAN.md` unverändert aus Downloads im Projektstamm abgelegt; SHA-256 jeweils mit dem Original identisch.
|
||||
- Leeres lokales Git-Projekt auf `main` initialisiert; Quellen und Lockfiles für den ersten Commit vorgemerkt. Noch kein Commit und kein Remote/Push.
|
||||
- Nutzerentscheidung „herkömmliches PHP-Webhosting“ übernommen. Symfony 7.4 / Twig / Doctrine gewählt; kein Python-/Django-Anwendungscode.
|
||||
- Start-/Build-/Prüfkommandos und Hostingvoraussetzungen in README, begründete Architektur und Datenmodell in ARCHITECTURE, Plananalyse/offene Anforderungen in REQUIREMENTS.
|
||||
- Erstes Datenbankschema, versionierte Blockdokumente, unveränderliche Revisionen über den Repository-Vertrag, getrennte Entwürfe/Veröffentlichungen und optimistische Schreibkonflikterkennung.
|
||||
- Drei gespeicherte öffentliche HTML-Demoseiten, lokale CSS-Ausgabe ohne JavaScript, Metadaten/Canonical, 404, Sprunglink und sichtbarer Fokus. `/home` leitet auf `/` um.
|
||||
- Idempotentes Demo-Seeding und lokaler CLI-Import validierter Entwürfe. Keine ungeschützte HTTP-Schreibschnittstelle.
|
||||
- Symfony-Security-Anmeldung, CSRF, Login-Throttling, geschützte Sessions und Rollen Editor/Publisher/Admin. Neue Migration ergänzt ausschließlich die Benutzertabelle. Passwort-Rehash hält Sessionbenutzer und Datenbank synchron; Rollenänderungen invalidieren bestehende Sitzungen.
|
||||
- Seitenübersicht und visueller Editor: Elementbibliothek, Strukturbaum, gemeinsame serverseitige Live-Vorschau, Eigenschaften, Drag-and-drop und Schaltflächen zum Verschieben/Verschachteln, Duplizieren/Löschen, lokales Undo/Redo.
|
||||
- Inhalt-/Designbereiche mit typabhängigen Abständen, Ausrichtung, Schriftgröße/-stärke, Zeilenhöhe, Spaltenaufteilung/-abstand und Ecken. Gerätewerte Desktop → Tablet → Mobil samt Vererbung, Einzel-/Gerätereset und Undo. Echte Vorschau-Layoutbreiten 1240/768/390 px mit visueller Skalierung.
|
||||
- Drei bearbeitbare Abschnittsvorlagen (Intro, zwei Leistungen, Kontaktaufruf), einklappbarer Werkzeugkasten, Struktursuche mit Vorfahren, einklappbare Teilbäume, Pfadnavigation und dauerhaft erreichbare Blockaktionen.
|
||||
- Dokumentformat v2, erhaltender idempotenter v1-Konverter, gemeinsame Tokenliste für Validator/Editor/CSS und dokumentierter Migrations-/Rückweg. Bestehende v1-Seiten werden beim Öffnen nicht geändert; keine neue DB-Migration erforderlich.
|
||||
- Dokumentformat v3 für Galerie, Bildbeschriftungen/-varianten und Effekte, mit erhaltendem Upgrade ohne Downgrade und Undo. v1/v2 bleiben unterstützt. Schatten, Hover-Anheben/Bildzoom und Einblenden beim Laden ohne öffentliches JavaScript; Bewegungsreduktion wird berücksichtigt.
|
||||
- Medienverwaltung im Editor und unter `/admin/media`: JPEG/PNG/WebP-Upload, echte Bildvalidierung, Größen-/Pixel-/Speichergrenzen, WebP-Varianten bis 480/960/1600 px, Suche, Titel/Alt-Text, Archivieren/Wiederherstellen und Schreibkonflikterkennung. Bildauswahl für einzelne Bilder und Galerien, kontextbezogene Alt-Texte/dekorative Verwendung und Beschriftungen.
|
||||
- Neue Medientabelle durch Migration `20260912000300` lokal angewendet. Vorher konsistentes SQLite-Backup unter `var/backups/before-media-20260912-051258.db`. Bestehende Seiten/Benutzer nicht geändert. Lokal läuft PHP 8.4 mit 8M Upload-, 10M POST- und 256M Speicherlimit; originale Uploads werden nicht gespeichert.
|
||||
- Speichern/Laden von Entwürfen, separates Veröffentlichen mit Bestätigung, sichtbare Speicher-/Fehler-/Konfliktzustände, JSON-Sicherung und bewusster Server-Neuladedialog. Keine Tests schreiben in den echten Seitenbestand.
|
||||
- Auf ausdrücklichen Nutzerwunsch lokalen Administrator `umut` mit zufälligem Passwort angelegt und im In-App-Browser erfolgreich angemeldet. Das Passwort steht in keiner Projektdatei; nur der Hash in der lokalen Datenbank. Keine Browser-Passwortspeicherung ausgelöst.
|
||||
- Lokale PHP-/Browser-/Lighthouse-Prüfungen und minimale GitHub-Actions-Konfiguration einschließlich vorbereitetem MySQL-Smokejob.
|
||||
|
||||
## Geprüft
|
||||
|
||||
- 41 PHP-Tests / 155 Assertions unter PHP 8.2.12 und 8.4.22 erfolgreich; zusätzlich 10 JavaScript-Modelltests. Abgedeckt sind Migration/Erhaltung, Versionen, ungültige Geräte-/Typ-/Design-/Effektwerte, Vererbung/Reset/Undo, Vorlage-/Galerie-IDs, Uploadvalidierung und Neuencodierung, Metadatenkonflikte, Archivierung sowie sichere Bildquellen.
|
||||
- Composer-/Format-/Twig-/YAML-/Containerprüfungen, Migration, wiederholtes Seeding und Produktionsbuild erfolgreich.
|
||||
- Frische Quellkopie ohne bestehende DB/Secrets/Dev-Abhängigkeiten erfolgreich eingerichtet; gespeicherte Seite als HTTP 200 gerendert.
|
||||
- Browserprüfung aller drei öffentlichen Seiten mobil und Desktop; keine axe-Verstöße, keine Überläufe, funktionierende Sprunglink-/Navigationsabläufe auch ohne JavaScript.
|
||||
- Editor-End-to-End in isolierter Installation: Anmeldung, Auswahl im Iframe, Texteingabe, Undo/Redo, Einfügen/Duplizieren/Verschieben/Drag-and-drop/Löschen, identisches Neuladen, private Entwürfe, Veröffentlichung, Dialog-Fokus/Escape, simulierter Netzwerkfehler mit Wiederholung, 409-Konflikt mit JSON-Export und Server-Neuladen. Einschränkungen der axe-Frameprüfung sind in QUALITY dokumentiert.
|
||||
- Ausbau im Browser geprüft: Struktursuche und Auswahl per Tastatur, Einklappen, Abstände, Schriftwerte und Vererbung in echten Gerätebreiten, Rücksetzen/Undo, responsive Zweispaltenvorlage und identische Styles nach Speichern/Publizieren auf allen drei Geräten.
|
||||
- Editoroberfläche, Login und Seitenübersicht ohne axe-Verstöße; identisch gerenderter bearbeiteter öffentlicher Inhalt separat geprüft. Desktop- und Mobil-Screenshots visuell durchgesehen.
|
||||
- Lighthouse-Startseite: jeweils drei echte mobile und Desktop-Läufe, Median in allen fünf Kategorien 100. Nur lokaler Prototyp; keine Kundenwebsite-Abnahme. Umfang und Grenzen siehe QUALITY.
|
||||
- Gestaltete v2-Testseite mit Design-CSS und responsiver Abschnittsvorlage: zusätzliche sechs Lighthouse-Läufe, alle fünf Kategorien jeweils 100; LCP-Median mobil 901 ms/Desktop 240 ms, CLS/TBT 0. Echte Seitenbestände und geöffnete Browserentwürfe unangetastet. Bericht: `docs/quality/editor-design-lighthouse.json`.
|
||||
- v3-Galerieseite mit echten optimierten Testbildern und Effekten: sechs Lighthouse-Läufe, alle fünf Kategorien jeweils 100; LCP-Median mobil 937 ms/Desktop 279 ms, CLS/TBT 0. Upload, Metadaten, Mehrfachauswahl per Tastatur, Bildbeschriftung, Sortier-Undo, Archivieren/Wiederherstellen, Bewegungsreduktion und öffentliche Bilder im isolierten Browserablauf bestanden. Keine axe-Verstöße in Desktop-/Mobil-Mediathek; Screenshots geprüft. Berichte: `docs/quality/editor-media-browser.json` und `editor-media-lighthouse.json`.
|
||||
- Keine bekannten Dependency-Advisories im ausgeführten Composer-Audit/npm-Installationsaudit.
|
||||
|
||||
## Bekannte Einschränkungen
|
||||
|
||||
- Gestaltung über geprüfte Tokens, keine beliebigen Pixelwerte, eigenen Schriften oder freien Farben. Noch keine Inline-Textbearbeitung, Formulare, dynamischen Menüs, Plugin-/Themeverwaltung oder WordPress-Import. Abschnittsvorlagen sind lokale Blockrezepte, keine globale Templateverwaltung.
|
||||
- Mediathek derzeit für statische Bilder: keine Videos/PDFs/SVGs, Lightbox/Slideshow, freie Bildzuschnitte, Ordner, Paginierung oder physische Löschung. Bild-URLs sind öffentlich; Archivieren schützt keine vertraulichen Dateien. Originale werden durch optimierte Varianten ersetzt. Einblendungen starten beim Laden, nicht beim Scrollen.
|
||||
- Sektionen bieten die vorhandenen Farb-/Breitentokens geräteübergreifend. Neue Seiten, Benutzerverwaltung und Passwortänderung sind noch nicht als Browseroberfläche verfügbar. Bestehende Seiten können bearbeitet und veröffentlicht werden.
|
||||
- SQLite tatsächlich getestet. MySQL-/MariaDB-Kompatibilität und CI erst vorbereitet, nicht nachgewiesen; Anbieter-/Tarifdetails und Livebetrieb offen.
|
||||
- Plugin-Fallback im Renderer noch nicht durch den strikten Lesevalidator erreichbar; unbekannte Blocktypen werden derzeit abgewiesen, nicht gelöscht. Ausbau in Phase 4.
|
||||
- Kein Inhaltscache, nur Symfony-Programmcache. Seiten senden `no-store`; Veröffentlichung ist dadurch ohne Cacheinvalidierungsverzögerung sichtbar.
|
||||
- Noch keine repräsentativen Kundeninhalte/Bilder/Blog-/Formularseite, keine Felddaten und keine vollständige manuelle Barrierefreiheitsprüfung.
|
||||
- Die vor der Hostingantwort erzeugte `.venv` bleibt ungenutzt und von Git ausgeschlossen. Die automatische Freigabeprüfung blockierte ihren Löschversuch mit „blocked by policy“; keine Umgehung versucht. Auch `var/fresh-check`, DB, Secrets und Berichte sind lokal ignoriert.
|
||||
|
||||
## Nächster konkreter Schritt
|
||||
|
||||
Neue Seiten über den Browser anlegen und mit einer Startvorlage aufbauen; danach Mediennutzung und Zuschnitte weiter ausbauen. Die wichtigsten Editorabläufe anhand einer konkreten UX-Builder-Referenz abgleichen. Für die Anmeldung eine reguläre Passwortänderungsmöglichkeit ergänzen, ohne Geheimnisse in Projektdateien zu speichern.
|
||||
|
||||
Parallel Pilotwebsite, reale UX-Builder-Referenz und Hostingausstattung konkretisieren. Noch keine Pilotwebsite ausgewählt; `kant-it.de` ist allein durch seine Erwähnung im Plan nicht beauftragt. Keine externe Veröffentlichung erfolgt.
|
||||
|
||||
## Lokale Vorschau
|
||||
|
||||
Öffentlich: `http://127.0.0.1:8080/`. Verwaltung: `http://127.0.0.1:8080/admin`. PHP 8.4.22 im Symfony-Produktionsmodus; der Browser wurde als `umut` angemeldet. Der Prozess ist sitzungsabhängig; zum erneuten Start README verwenden.
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"checks": [
|
||||
{
|
||||
"name": "login",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "page list",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "preview selection, property edit, undo and redo",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "network failure retains edits and allows retry",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "edited public renderer accessibility",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "add, duplicate, move, delete, undo, exact reload, separate publication, dialog focus",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "conflict retains local edits, JSON export, explicit server reload",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "desktop editor",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "mobile editor",
|
||||
"violations": 0
|
||||
}
|
||||
],
|
||||
"publicDataUntouched": true
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"checks": [
|
||||
{
|
||||
"name": "login",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "page list",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "preview selection, property edit, undo and redo",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "keyboard tree search and collapse, responsive inheritance/reset/undo, true viewport widths, spacing and responsive section preset",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "network failure retains edits and allows retry",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "edited public renderer accessibility",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "add, duplicate, move, delete, undo, exact reload, separate publication, dialog focus",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "conflict retains local edits, JSON export, explicit server reload",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "desktop editor",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "mobile editor",
|
||||
"violations": 0
|
||||
}
|
||||
],
|
||||
"publicDataUntouched": true
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
[
|
||||
{
|
||||
"profile": "mobile",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "mobile",
|
||||
"throttling": {
|
||||
"rttMs": 150,
|
||||
"throughputKbps": 1638.4,
|
||||
"requestLatencyMs": 562.5,
|
||||
"downloadThroughputKbps": 1474.5600000000002,
|
||||
"uploadThroughputKbps": 675,
|
||||
"cpuSlowdownMultiplier": 4
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": true,
|
||||
"width": 412,
|
||||
"height": 823,
|
||||
"deviceScaleFactor": 1.75,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Mobile Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5250,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
},
|
||||
{
|
||||
"profile": "desktop",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "desktop",
|
||||
"throttling": {
|
||||
"rttMs": 40,
|
||||
"throughputKbps": 10240,
|
||||
"requestLatencyMs": 0,
|
||||
"downloadThroughputKbps": 0,
|
||||
"uploadThroughputKbps": 0,
|
||||
"cpuSlowdownMultiplier": 1
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": false,
|
||||
"width": 1350,
|
||||
"height": 940,
|
||||
"deviceScaleFactor": 1,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5297,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"checks": [
|
||||
{
|
||||
"name": "login",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "page list",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "preview selection, property edit, undo and redo",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "keyboard tree search and collapse, responsive inheritance/reset/undo, true viewport widths, spacing and responsive section preset",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "media picker",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "image upload, alt metadata, multi-select gallery, caption, sorting undo, archive/restore, responsive variants and reduced-motion effects",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "network failure retains edits and allows retry",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "edited public renderer accessibility",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "add, duplicate, move, delete, undo, exact reload, separate publication, dialog focus",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "conflict retains local edits, JSON export, explicit server reload",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "desktop editor",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "mobile editor",
|
||||
"violations": 0
|
||||
},
|
||||
{
|
||||
"name": "mobile media library",
|
||||
"violations": 0
|
||||
}
|
||||
],
|
||||
"publicDataUntouched": true
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
[
|
||||
{
|
||||
"profile": "mobile",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "mobile",
|
||||
"throttling": {
|
||||
"rttMs": 150,
|
||||
"throughputKbps": 1638.4,
|
||||
"requestLatencyMs": 562.5,
|
||||
"downloadThroughputKbps": 1474.5600000000002,
|
||||
"uploadThroughputKbps": 675,
|
||||
"cpuSlowdownMultiplier": 4
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": true,
|
||||
"width": 412,
|
||||
"height": 823,
|
||||
"deviceScaleFactor": 1.75,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Mobile Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5314,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
},
|
||||
{
|
||||
"profile": "desktop",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "desktop",
|
||||
"throttling": {
|
||||
"rttMs": 40,
|
||||
"throughputKbps": 10240,
|
||||
"requestLatencyMs": 0,
|
||||
"downloadThroughputKbps": 0,
|
||||
"uploadThroughputKbps": 0,
|
||||
"cpuSlowdownMultiplier": 1
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": false,
|
||||
"width": 1350,
|
||||
"height": 940,
|
||||
"deviceScaleFactor": 1,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5319,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,144 @@
|
||||
[
|
||||
{
|
||||
"profile": "mobile",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "mobile",
|
||||
"throttling": {
|
||||
"rttMs": 150,
|
||||
"throughputKbps": 1638.4,
|
||||
"requestLatencyMs": 562.5,
|
||||
"downloadThroughputKbps": 1474.5600000000002,
|
||||
"uploadThroughputKbps": 675,
|
||||
"cpuSlowdownMultiplier": 4
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": true,
|
||||
"width": 412,
|
||||
"height": 823,
|
||||
"deviceScaleFactor": 1.75,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Mobile Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5286,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
},
|
||||
{
|
||||
"profile": "desktop",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "desktop",
|
||||
"throttling": {
|
||||
"rttMs": 40,
|
||||
"throughputKbps": 10240,
|
||||
"requestLatencyMs": 0,
|
||||
"downloadThroughputKbps": 0,
|
||||
"uploadThroughputKbps": 0,
|
||||
"cpuSlowdownMultiplier": 1
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": false,
|
||||
"width": 1350,
|
||||
"height": 940,
|
||||
"deviceScaleFactor": 1,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5331,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,144 @@
|
||||
[
|
||||
{
|
||||
"profile": "mobile",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "mobile",
|
||||
"throttling": {
|
||||
"rttMs": 150,
|
||||
"throughputKbps": 1638.4,
|
||||
"requestLatencyMs": 562.5,
|
||||
"downloadThroughputKbps": 1474.5600000000002,
|
||||
"uploadThroughputKbps": 675,
|
||||
"cpuSlowdownMultiplier": 4
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": true,
|
||||
"width": 412,
|
||||
"height": 823,
|
||||
"deviceScaleFactor": 1.75,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Mobile Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5274,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
},
|
||||
{
|
||||
"profile": "desktop",
|
||||
"scores": {
|
||||
"performance": 1,
|
||||
"accessibility": 1,
|
||||
"best-practices": 1,
|
||||
"seo": 1,
|
||||
"agentic-browsing": 1
|
||||
},
|
||||
"lighthouseVersion": "13.4.1",
|
||||
"settings": {
|
||||
"output": "json",
|
||||
"maxWaitForFcp": 30000,
|
||||
"maxWaitForLoad": 45000,
|
||||
"pauseAfterFcpMs": 1000,
|
||||
"pauseAfterLoadMs": 1000,
|
||||
"networkQuietThresholdMs": 1000,
|
||||
"cpuQuietThresholdMs": 1000,
|
||||
"formFactor": "desktop",
|
||||
"throttling": {
|
||||
"rttMs": 40,
|
||||
"throughputKbps": 10240,
|
||||
"requestLatencyMs": 0,
|
||||
"downloadThroughputKbps": 0,
|
||||
"uploadThroughputKbps": 0,
|
||||
"cpuSlowdownMultiplier": 1
|
||||
},
|
||||
"throttlingMethod": "simulate",
|
||||
"screenEmulation": {
|
||||
"mobile": false,
|
||||
"width": 1350,
|
||||
"height": 940,
|
||||
"deviceScaleFactor": 1,
|
||||
"disabled": false
|
||||
},
|
||||
"emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
|
||||
"auditMode": false,
|
||||
"gatherMode": false,
|
||||
"clearStorageTypes": [
|
||||
"file_systems",
|
||||
"shader_cache",
|
||||
"service_workers",
|
||||
"cache_storage"
|
||||
],
|
||||
"disableStorageReset": false,
|
||||
"debugNavigation": false,
|
||||
"channel": "node",
|
||||
"usePassiveGathering": false,
|
||||
"disableFullPageScreenshot": false,
|
||||
"skipAboutBlank": false,
|
||||
"blankPage": "about:blank",
|
||||
"ignoreStatusCode": false,
|
||||
"locale": "en-US",
|
||||
"blockedUrlPatterns": null,
|
||||
"additionalTraceCategories": null,
|
||||
"extraHeaders": null,
|
||||
"precomputedLanternData": null,
|
||||
"onlyAudits": null,
|
||||
"onlyCategories": null,
|
||||
"skipAudits": null
|
||||
},
|
||||
"environment": {
|
||||
"networkUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36",
|
||||
"hostUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/153.0.8010.12 Safari/537.36",
|
||||
"benchmarkIndex": 5264,
|
||||
"credits": {
|
||||
"axe-core": "4.13.0"
|
||||
}
|
||||
},
|
||||
"note": "Local prototype only. No customer-site acceptance or field-data claim."
|
||||
}
|
||||
]
|
||||
Reference in new issue
Block a user