Move site content between installations as a package

System now exports a content package and imports one, by upload or from
var/pakete. Pages with their revisions, areas, menus, media, forms,
redirects, terms, translations, design and settings are replaced;
submissions, statistics, tasks, plugin state and service keys stay, and
accounts only come along when that is chosen explicitly. A backup comes
first, the site is in maintenance meanwhile, and every file and document
in the package is checked before anything is written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5.5 committed 2026-10-12 16:31:06 +02:00
1 parent a57b829a15
commit 32e42f973b
13 files changed
+973 -2

No files matched your search

+14
View File
@@ -2,6 +2,20 @@
Stand: 12.10.2026. Arbeitstitel KantSites; Produktname offen.
## ADR 118 – Inhaltspakete: Export und Import ohne die Konten (12.10.2026)
Anlass: Umut: „Können wir sowas wie einen Importer einbauen, weil sich nach jeder Anpassung sonst das Passwort ändert? Wo man auswählen muss, ob Passwort/Benutzer überschrieben werden sollen. Gerne auch als Plugin.“ Bisher wurde eine lokal gebaute Website als ganze SQLite-Datei hochgeladen – samt Konten (neues Passwort nach jedem Neuaufbau) und ohne das, was nur live entstanden war (Anfragen, Statistik).
**Entscheidung: im Kern, nicht als Plugin.** Plugins führen bewusst keinen eigenen Servercode aus (ADR zum Pluginsystem; serverseitiger Code nur mit Isolation). Ein Import schreibt Datenbank und Medienordner – das gehört in den Kern, unter System, nur für Administratoren.
**Paket.** Zip mit `paket.json` (Art, Format 1, Fassung, Website, Konten ja/nein, Zahlen, SHA-256 von `inhalt.json`), `inhalt.json` (Zeilen je Tabelle) und `medien/` (Bildvarianten, PDFs, erzeugte Seitensymbole). JSON statt SQLite-Datei: Ein Paket geht von SQLite nach MySQL und zurück, und jede Zeile wird vor dem Schreiben geprüft. Inhalt: `page`, `revision`, `partial`, `menu`, `media`, `document`, `form`, `redirect`, `term`, `page_term`, `page_translation` und die Website (Name, Sprache, Gestaltung, Einstellungen). **Nicht** darin: Anfragen, Statistik, Aufgaben, Plugin-Stand, Migrationsliste und die Zugangsdaten zu Diensten (`turnstile`, `turnstileSiteKey`, `turnstileSecret`). Konten nur mit „Konten mitnehmen“ beim Export.
**Import (`App\Ops\SitePackage::import`).** Prüfen vor Schreiben: nur bekannte Einträge im Zip (keine Pfade nach oben, keine anderen Dateitypen, Größengrenzen gegen Zip-Bomben), Prüfsumme von `inhalt.json`, nur bekannte Tabellen und Spaltennamen, jedes Seiten- und Bereichsdokument durch `DocumentValidator`, Paket nicht aus einer neueren Fassung. Dann Sicherung (`vor Import`), Wartungszustand, Inhalte in einer Transaktion ersetzen (nur Spalten, die es hier gibt – ein älteres Paket passt so in ein neueres Schema), Website-Einstellungen übernehmen außer den Dienst-Zugangsdaten, Anfragen über die Formularadresse dem neuen Formular zuordnen, Medienordner ersetzen. **Konten nur mit eigenem Häkchen** („Konten und Passwörter aus dem Paket übernehmen“); ohne bleiben Benutzer und Passwörter der Website. Ein Häkchen bei einem Paket ohne Konten bricht ab, ohne etwas zu ändern.
**Oberfläche.** System → „Inhalte übertragen“: Export als Download (Datei wird nach dem Senden gelöscht), Import per Upload oder aus `var/pakete/` (für Pakete über der Upload-Grenze des Hostings, die angezeigt wird), Bestätigungshäkchen, Ergebnisseite mit den Schritten und einem Hinweis, falls Schriften der neuen Gestaltung auf dem Server fehlen. Konsole: `cms:paket:export [--mit-benutzern] [--ziel=…]`, `cms:paket:import <datei> [--mit-benutzern] [--ja]`.
**Folgen.** Das Zurückspielen einer Sicherung bleibt Konsolensache; der Import ist der Weg für Inhalte aus einer anderen Installation, mit eigener Sicherung davor. Reset-Skripte können ein Paket schreiben (zuerst `reset-huefner.sh` → `var/huefner-paket.zip`). Keine Migration.
## ADR 117 – Menü schließt beim Klick daneben, Netzwerk-Symbole, schlankere Symbole (12.10.2026)
Anlass: Umut: „Bei Mobilmenü, wenn es aufgeklappt ist, schließt es nicht, wenn man irgendwo anders hinklickt.“ Und für Hüfner: Facebook, Instagram und „Angebot anfragen“ als Menü-Buttons statt eigener Knöpfe im Kopf.