From 67d9222c9796e363f531e5958db9da7579080b3b Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Sun, 26 Jul 2026 00:33:57 +0200 Subject: [PATCH] docs: Export, Import und Sicherung dokumentieren README bekommt einen eigenen Abschnitt mit den vier Wegen, den drei Importstrategien und beiden Sicherungsarten - samt der Empfehlung, eine Sicherung einmal in eine Wegwerf-Datenbank zurueckzuspielen. FEATURES beschreibt dasselbe ausfuehrlicher. In der ROADMAP wandert Export und Import zu den erledigten Punkten, mit den getroffenen Entscheidungen: keine Tokens, keine Snapshots, Voll-Sicherung nur fuer Administratoren. Die folgenden Punkte ruecken auf. Co-Authored-By: Claude Opus 5 (1M context) --- FEATURES.md | 36 +++++++++++++++++++++++++++++++ README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ROADMAP.md | 33 ++++++++--------------------- 3 files changed, 106 insertions(+), 24 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index 008625e..e9dafbb 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -215,6 +215,42 @@ Dateneinsicht. Ein Administrator sieht dadurch weiterhin keine fremden Projekte. --- +## 4a. Export, Import und Sicherung + +### Projekte mitnehmen + +- **JSON-Export** einzeln oder für alle Projekte: Stammdaten, Notizen, Tags, + Repo-Verknüpfung. **Ohne Access Tokens** — die Verbindung wird nur beschrieben, das + Token muss beim Import neu hinterlegt werden. Auch ohne Snapshots (reproduzierbar) und + ohne Datenbank-IDs (gelten nur in der Quellinstanz). +- **Markdown-Export** eines Projekts: Beschreibung, Kennzahlen, Notizen und der letzte + bekannte Git-Stand als lesbare Datei. +- **Import mit Vorschau.** Die Datei wird streng geprüft, bevor irgendetwas passiert. + Abgeglichen wird über den Slug; bei Treffern stehen drei Strategien bereit: + + | Strategie | Wirkung | + | --- | --- | + | Überspringen | Vorhandene bleiben unverändert | + | Zusätzlich anlegen | Kopie mit freiem Slug (`nebula` → `nebula-2`) | + | Ersetzen | Stammdaten überschreiben, Notizen austauschen | + + Die Vorschau zeigt je Projekt, was geschähe, und weist auf fehlende Git-Verbindungen + hin. Erst ein zweiter Klick schreibt. + +### Sicherung + +- **JSON-Sicherung** im Adminbereich: Einstellungen, Konten, Verbindungen, Projekte und + Notizen in einer Datei. Passwörter als scrypt-Hash, Git-Tokens als Chiffrat — ohne + dasselbe `APP_SECRET` wertlos. Sitzungen und Passkeys bleiben draußen: erstere sind + kurzlebig, letztere hängen an Gerät und rpID. +- **Datenbank-Sicherung** über `scripts/backup.*`: `pg_dump` im Container, mit + `--clean --if-exists`, also für sich allein einspielbar. Gegenstück ist + `scripts/restore.*`, das vor dem Überschreiben nachfragt und sich über einen Parameter + auf eine Wegwerf-Datenbank umlenken lässt — damit sich eine Sicherung prüfen lässt, + ohne die echte anzufassen. + +--- + ## 5. Oberfläche - **Dark Glassmorphism**: milchige Glasflächen, driftende Nebel im Hintergrund, feines diff --git a/README.md b/README.md index 2007bf2..be0233e 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,63 @@ Wer lieber von außen taktet, lässt den Automatismus aus und ruft --- +## Export, Import und Sicherung + +### Projekte mitnehmen + +| Weg | Wo | Inhalt | +| --- | --- | --- | +| **Alle Projekte als JSON** | Dashboard → Datenbank-Symbol | Stammdaten, Notizen, Repo-Verknüpfung | +| **Ein Projekt als JSON** | Projektseite → Download-Symbol | dasselbe, für ein Projekt | +| **Ein Projekt als Markdown** | Projektseite → Download-Symbol | lesbar, inklusive letztem Git-Stand | +| **Import** | Dashboard → Datenbank-Symbol | JSON einlesen, mit Vorschau | + +**Access Tokens sind nie enthalten.** Die Git-Verbindung wird nur beschrieben (Name, +System, Basis-URL); nach dem Import muss das Token neu hinterlegt werden. Verweist eine +importierte Datei auf eine hier unbekannte Verbindung, wird das Projekt ohne Verknüpfung +angelegt und in der Vorschau angezeigt. + +Beim Import wird über den Slug abgeglichen. Für Treffer gibt es drei Strategien: + +- **Überspringen** — Vorhandene bleiben unverändert +- **Zusätzlich anlegen** — Kopie mit freiem Slug (`nebula` → `nebula-2`) +- **Ersetzen** — Stammdaten überschreiben, Notizen austauschen + +Vor dem Schreiben zeigt eine Vorschau, was passieren würde. Erst dann wird geschrieben. + +### Sicherung + +Zwei Wege, mit unterschiedlichem Zweck: + +**JSON-Sicherung** (Admin-Einstellungen → Sicherung) enthält Einstellungen, Konten, +Verbindungen, Projekte und Notizen. Gut zum Umziehen. Passwörter liegen als scrypt-Hash +vor, Git-Tokens als Chiffrat — ohne dasselbe `APP_SECRET` sind sie wertlos. Trotzdem +vertraulich behandeln. + +**Datenbank-Sicherung** über `pg_dump` — das, was man zum Wiederherstellen einer kaputten +Instanz braucht: + +```powershell +.\scripts\backup.ps1 # → .\backups\nebula-.sql +.\scripts\restore.ps1 -File .\backups\nebula-....sql +``` + +```bash +./scripts/backup.sh # → ./backups/nebula-.sql +./scripts/restore.sh backups/nebula-....sql +``` + +Die Skripte lesen Benutzer und Datenbankname aus der `.env` und führen `pg_dump` im +Container aus — auf dem Rechner selbst muss nichts installiert sein. + +> Eine Sicherung ist erst dann eine Sicherung, wenn du sie einmal zurückgespielt hast. +> Das geht ohne Risiko in eine Wegwerf-Datenbank: +> +> ```powershell +> docker exec nebula-db psql -U nebula -d postgres -c "CREATE DATABASE nebula_test" +> .\scripts\restore.ps1 -File .\backups\nebula-....sql -Database nebula_test -Force +> ``` + ## Projektstruktur ``` @@ -271,6 +328,10 @@ ausschließlich Daten des angemeldeten Kontos. | `GET` `POST` | `/api/admin/users` | Konten auflisten / anlegen (Admin) | | `PATCH` `DELETE` | `/api/admin/users/:id` | Konto ändern / löschen (Admin) | | `GET` `POST` | `/api/projects` | Projekte auflisten / anlegen | +| `GET` | `/api/projects/export` | Alle eigenen Projekte als JSON | +| `GET` | `/api/projects/:id/export` | Ein Projekt (`?format=md` für Markdown) | +| `POST` | `/api/projects/import` | Import, mit `dryRun` für die Vorschau | +| `GET` | `/api/admin/backup` | Vollständige Sicherung als JSON (Admin) | | `GET` `PATCH` `DELETE` | `/api/projects/:id` | Projekt lesen / ändern / löschen | | `POST` | `/api/projects/:id/sync` | Repo-Daten vom Git-System holen | | `GET` `POST` | `/api/projects/:id/notes` | Notizen des Projekts | diff --git a/ROADMAP.md b/ROADMAP.md index 485e7b2..44b596a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -11,28 +11,7 @@ Was bereits steht, listet [FEATURES.md](FEATURES.md). ## 1 · Als Nächstes empfohlen -### 1.1 Export und Import `M` - -Dein Vorschlag, in vier Stufen — jede für sich nutzbar: - -| Stufe | Inhalt | -| --- | --- | -| **Projekt-Export** | Ein Projekt oder alle als JSON: Stammdaten, Notizen, Repo-Verknüpfung. Ein Klick auf der Projektseite, einer im Dashboard für alles. | -| **Projekt-Import** | JSON hochladen, Vorschau, dann übernehmen. Konfliktstrategie wählbar: überspringen · umbenennen · überschreiben. | -| **Markdown-Export** | Ein Projekt als lesbares `.md` — Beschreibung, Notizen, aktueller Git-Stand. Gut zum Archivieren oder für ein README. | -| **Voll-Backup** | `pg_dump` aus dem Container heraus, per Knopf im Adminbereich als Datei. Plus dokumentierter Rückweg. | - -**Offene Fragen, die wir klären sollten:** -- **Git-Tokens mitexportieren?** Mein Vorschlag: **nein**. Die Verbindung wird - mitexportiert (Name, System, Basis-URL), das Token muss beim Import neu - hinterlegt werden. Ein Export-JSON landet sonst schnell irgendwo, wo es - nicht hingehört. -- **Reichweite:** Export der eigenen Daten für jeden — Voll-Backup nur für - Administratoren? -- **Snapshots mitnehmen?** Ich würde sie weglassen: sie sind reproduzierbar - und blähen die Datei auf. Ein Sync nach dem Import holt sie zurück. - -### 1.2 Markdown in Beschreibung und Notizen `S` +### 1.1 Markdown in Beschreibung und Notizen `S` Heute wird alles als reiner Text dargestellt. Mit Markdown werden aus `- [ ] Aufgabe` echte Checklisten, Codeblöcke bekommen Hervorhebung, Links @@ -41,13 +20,13 @@ werden klickbar. Zu beachten: HTML muss beim Rendern entfernt werden, sonst reißt es ein XSS-Loch. Mit `react-markdown` plus `rehype-sanitize` ist das sauber lösbar. -### 1.3 Volltextsuche über Notizen `S` +### 1.2 Volltextsuche über Notizen `S` Die Suche im Board deckt Namen, Kurzbeschreibung und Tags ab — Notizen nicht. Postgres kann das nativ (`tsvector` mit deutscher Konfiguration), also ohne zusätzlichen Dienst. -### 1.4 Kanban-Board mit Drag & Drop `M` +### 1.3 Kanban-Board mit Drag & Drop `M` Die gruppierte Ansicht gibt es schon, aber Statuswechsel geht nur über das Menü. Spalten mit Ziehen und Ablegen wären der natürlichere Weg. @@ -176,3 +155,9 @@ Damit klar ist, was **nicht** kommt und warum: | Härtung: CSRF, CSP, SSRF, Ratenbegrenzung, Datentrennung | ✓ | | Docker- und Standalone-Betrieb | ✓ | | Automatischer Abgleich mit Zeitplan | ✓ | +| Export, Import und Sicherung | ✓ | + +Zur Entscheidung beim Export: Git-Tokens gehen **nicht** mit. Die Verbindung wird nur +beschrieben, das Token ist nach dem Import neu zu hinterlegen. Snapshots bleiben +ebenfalls draußen — sie sind reproduzierbar. Der Projekt-Export steht jedem Konto für +seine eigenen Daten offen, die Voll-Sicherung nur Administratoren.