diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 06fadf1..12a4072 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -3,44 +3,58 @@ Du (Claude, nächste Session) oder ich (Jörg, später) kommen hier zurück. Dieses Dokument sagt: was ist der Zustand, was wartet, wo liegen die Fäden. -## Zustand (siehe `STATUS.md` für Details) +## Zustand (Details in `STATUS.md`) Die SvelteKit-SPA unter `svelte.joerg-lohrer.de` ist **fertig und live**. -35 geplante Tasks + einige Erweiterungen abgeschlossen. Branch `spa` hat -alle Commits. Ein Git-Merge nach `main` und Deploy auf die Hauptdomain ist -**noch nicht** erfolgt — das kommt erst nach dem Cutover-Plan. +Alle 18 Posts haben jetzt **strukturierte Bild-Metadaten** im Frontmatter +(Commit `c023b59`, 91 Bilder). Der Publish-Pipeline-**Plan ist geschrieben** +(`docs/superpowers/plans/2026-04-16-publish-pipeline.md`, 24 Tasks in 12 Phasen). + +**Als nächstes:** Pipeline implementieren, beginnend mit Task 1. ## Was als Nächstes ansteht -Drei Optionen, ordered by natürlichkeit der Fortsetzung: +### Option 1 — Publish-Pipeline implementieren ⬅ empfohlen -### Option 1 — Publish-Pipeline bauen +**Warum:** Spec + Plan fertig, Content vorbereitet, alle Design-Entscheidungen +getroffen. Kann direkt losgehen. -**Warum:** aktuell muss Jörg jeden neuen Post manuell mit `nak event` signieren -und publishen (siehe `preview/spa-mini/README.md`, Referenzbefehl in den -Brainstorm-Notizen). Eine Publish-Pipeline automatisiert: +**Nächster konkreter Schritt:** -1. Markdown-Post in `content/posts/` bearbeiten / neu anlegen -2. Git-Commit + push auf `main` -3. GitHub Action signiert Event via NIP-46 (Amber-Bunker), pushed zu allen - Relays aus `kind:10002`, lädt Bilder zu Blossom, lädt Altbild-Assets - ggf. zu All-Inkl via SSH/rsync. - -**Was existiert:** Spec vollständig unter -`docs/superpowers/specs/2026-04-15-publish-pipeline-design.md`. Plan -**noch nicht geschrieben.** - -**Nächster Konkreter Schritt:** ``` -superpowers:writing-plans +cd /Users/joerglohrer/repositories/joerglohrerde ``` -mit dem Publish-Spec als Input. -**Vorarbeiten:** -- SSH-Zugang zu All-Inkl klären (Premium-Tarif angefragt, Status prüfen) -- Deno ≥ 2.x installiert? -- GitHub Actions-Repo-Secrets vorbereiten (`BUNKER_URL`, `ALLINKL_DEPLOY_ROOT`, - `SSH_DEPLOY_KEY`, `AUTHOR_PUBKEY_HEX`) +Dann den Plan öffnen: +``` +docs/superpowers/plans/2026-04-16-publish-pipeline.md +``` + +Und Task 1 (Deno-Projekt-Grundgerüst) starten. Der Plan nutzt TDD; +jeder Task hat Test-First, Implementation, Commit. + +**Ausführungsweisen:** +- **Subagent-Driven** (im Plan empfohlen): pro Task frischer Subagent, + Review zwischen Tasks. Skill: `superpowers:subagent-driven-development`. +- **Inline**: alles in einer Session. Skill: `superpowers:executing-plans`. + +**Besonderheiten beim Plan:** +- Pipeline ist **Blaupause** für andere Nostr-Repos — keine + Projekt-Konstanten im Code, alles via Env. +- **Env-File:** nutzt `../.env.local` (Repo-Root), wo `BUNKER_URL`, + `AUTHOR_PUBKEY_HEX`, `BOOTSTRAP_RELAY` bereits stehen. +- **Blossom-only**: keine rsync/SSH-Altlasten mehr; alle Bilder (auch + die der 17 Altposts) werden zu Blossom hochgeladen. +- **Staging:** `staging.joerg-lohrer.de` zeigt auf `/www/htdocs/v109928/joerglohrer26/`. + Wird erst beim Cutover relevant — Pipeline selbst braucht es nicht. + +**Vorarbeiten (bereits erledigt):** +- ✅ SSH-Zugang All-Inkl (Premium): `ssh-v109928@v109928.kasserver.com` + mit Deploy-Key `~/.ssh/id_ed25519_joerglohrerde_deploy` (auch im KAS + eingetragen). Wird jetzt allerdings nicht mehr für die Pipeline + gebraucht — Blossom-only. +- ✅ `.env.local` enthält alle Pipeline-Keys. +- ✅ Content-Migration (18 Posts × Bild-Metadaten) abgeschlossen. ### Option 2 — Menü-Navigation + Impressum auf der SPA @@ -51,28 +65,29 @@ mit dem Publish-Spec als Input. - `/impressum/`-Route anlegen mit rechtlichem Text - ggf. Archives-Route als eigene Liste mit Gruppierung nach Jahr -**Aufwand:** ~30-60 min je nach Layout-Wunsch. Kein Spec-Update nötig, -ist in SPA-Spec §2 bereits als Ziel erwähnt. +**Aufwand:** ~30-60 min. ### Option 3 — Cutover auf Hauptdomain -**Warum:** `joerg-lohrer.de` liefert aktuell noch Hugo aus. Sobald genug -Altposts als Events publiziert sind und die Publish-Pipeline läuft, kann die -SvelteKit-SPA auf die Hauptdomain umziehen. Das ist aber **kein Task jetzt** -— muss auf Publish-Pipeline warten, sonst brechen Backlinks zu Posts, die -noch nicht als Events existieren. +**Voraussetzung:** Option 1 abgeschlossen und alle 18 Posts als Events +publiziert, Bilder auf Blossom. -**Reihenfolge:** Option 1 → Publish-Pipeline + einmaliger Massen-Import der -übrigen 17 Altposts → dann Option 3. +**Dann:** KAS → Domain `joerg-lohrer.de` auf den SvelteKit-Webroot +umhängen (derselbe wie `svelte.joerg-lohrer.de` oder `joerglohrer26/`, +je nach Entscheidung). + +Reihenfolge: **Option 1 → Option 3**, Option 2 kann parallel laufen. ## Schnell-Orientierung für die nächste Claude-Session Lies in dieser Reihenfolge: 1. `docs/STATUS.md` (5 min) 2. `docs/HANDOFF.md` (= dieses Dokument) -3. Die relevante Spec, je nachdem was drankommt: +3. Für die Pipeline: `docs/superpowers/plans/2026-04-16-publish-pipeline.md` +4. Bei Design-Fragen: - Publish-Pipeline: `docs/superpowers/specs/2026-04-15-publish-pipeline-design.md` - - SPA-Anpassungen: `docs/superpowers/specs/2026-04-15-nostr-page-design.md` + - Bild-Metadaten: `docs/superpowers/specs/2026-04-16-image-metadata-convention.md` + - SPA: `docs/superpowers/specs/2026-04-15-nostr-page-design.md` Nutze den Skill unter `.claude/skills/joerglohrerde-workflow.md` für wiederkehrende Kommandos. @@ -80,50 +95,41 @@ wiederkehrende Kommandos. ## Dev-Kommandos ```sh -# Unit-Tests (Vitest) +# Unit-Tests SPA (Vitest) cd app && npm run test:unit -# E2E-Tests (Playwright) +# E2E-Tests SPA (Playwright) cd app && npm run test:e2e -# Type-Check +# Type-Check SPA cd app && npm run check -# Dev-Server (Port 5173) +# SPA-Dev-Server (Port 5173) cd app && npm run dev -# Production-Build + Deploy +# SPA-Production-Build + Deploy cd app && npm run build && cd .. && ./scripts/deploy-svelte.sh ``` -## Manuelles Publishen (bis Publish-Pipeline fertig ist) - -Einen Post aus `content/posts//index.md` als kind:30023-Event -publizieren: - +Publish-Pipeline-Kommandos (sobald implementiert): ```sh -# Body ohne Frontmatter extrahieren -awk 'BEGIN{in_fm=0; past_fm=0} NR==1 && /^---$/ {in_fm=1; next} in_fm && /^---$/ {in_fm=0; past_fm=1; next} past_fm {print}' content/posts//index.md > /tmp/body.md - -# Bunker-URL aus .env.local -BUNKER_URL=$(grep -E '^BUNKER_URL=' .env.local | sed 's/^BUNKER_URL=//') - -# Event bauen, signieren, zu Relays pushen -# (Tags: d, title, summary, image, published_at, t×n) -# Siehe "dezentrale-oep-oer"-Beispiel in der Brainstorm-Historie +cd publish && deno task check # Pre-Flight +cd publish && deno task publish --dry-run # Simulation +cd publish && deno task publish --post # einen Post +cd publish && deno task publish --force-all # alle Posts +cd publish && deno task test # Tests ``` -Für Bilder: Upload zu Blossom mit `nak blossom upload`: -```sh -nak blossom upload --server https://blossom.edufeed.org --sec "$BUNKER_URL" -``` +## Manuelles Publishen (Übergang, bis Pipeline fertig) + +Siehe frühere Version dieses Dokuments. Bis die Pipeline läuft, gehen +neue Posts manuell über `nak event` raus. ## Bekannte Stolperfallen - **Amber-Bunker:** bei neuer Bunker-URL müssen globale Permissions in Amber zurückgesetzt werden, sonst hängt `nak` auf den Signatur-Request. -- **All-Inkl FTPS:** bricht mit TLS 1.3 die Data-Connection ab. Script - nutzt `--tls-max 1.2`. Bei SSH-Umstellung: rsync fixen, TLS-Flag raus. + Auto-Approve für `kind:30023` und `kind:24242` (Blossom-Auth) setzen. - **Svelte 5 Runes:** `$props()`-Werte müssen via `$derived()` in lokale Variablen, sonst `state_referenced_locally`-Warning. - **applesauce-relay API:** ist RxJS-basiert. `pool.request(relays, filter)` @@ -131,10 +137,36 @@ nak blossom upload --server https://blossom.edufeed.org --sec "$BUNKER_URL" /dev/null | jq -c '{d: (.tags[] | select(.[0]=="d") | .[1]), title: (.tags[] | select(.[0]=="title") | .[1])}'` +- Publish-Status: `nak req -k 30023 -a 4fa5d1c413e2b45e10d40bf3562ab701a5331206e359c90baae0e99bfd6c6e41 wss://relay.damus.io 2>/dev/null | jq -s 'length'` + (aktuell ~10, nach Pipeline-Lauf `--force-all`: 18) + +## Offene UNKNOWN-Einträge zur späteren Recherche + +Im VR-Post (`content/posts/2021-08-15-virtual-reality/index.md`) +sind 4 Bilder als `license: UNKNOWN / authors: UNKNOWN` markiert: +- `01-immersion-wikipedia.jpg` (Wikipedia-Screenshot) +- `02-mittelalterliche-kirche.jpg` (Sketchfab — Lizenz ist CC BY-NC, Fotograf fehlt) +- `03-avatare-erstellen.jpg` (Ready Player Me) +- `05-pupillendistanz.jpg` (EyeMeasure iOS App) + +Pipeline loggt beim Publishen eine Warnung pro UNKNOWN, publisht aber +trotzdem (Phase-1-Default: `STRICT_MODE=false`). Die Recherche-Todo-Liste +steht in `docs/redaktion-bild-metadaten.md`. + +## Community-Wiki-Entwürfe + +Noch nicht extern veröffentlicht, liegen im Repo bereit: +- `docs/wiki-entwurf-nostr-bild-metadaten.md` — DE +- `docs/wiki-draft-nostr-image-metadata.md` — EN + +Können in die Nostr-Community eingebracht werden (z. B. als NIP-Proposal +oder auf nostrbook.dev), sobald die Pipeline sie in der Praxis validiert. diff --git a/docs/STATUS.md b/docs/STATUS.md index fcf349b..8780df8 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -1,6 +1,6 @@ # Projekt-Status: joerg-lohrer.de → Nostr-basierte SPA -**Stand:** 2026-04-15 +**Stand:** 2026-04-16 ## Kurzfassung @@ -9,13 +9,14 @@ Site-Generator zu einer dezentralen Nostr-basierten SPA überführt. Posts existieren als signierte Events (NIP-23, `kind:30023`) auf Public-Relays und werden zur Laufzeit im Browser gerendert. -## Drei parallele Webseiten +## Vier parallele Webseiten | URL | Status | Rolle | |---|---|---| -| `https://joerg-lohrer.de/` | live, unverändert | **Hugo-Altbestand** (wird noch nicht ersetzt) | -| `https://spa.joerg-lohrer.de/` | live | **Vanilla-HTML-Mini-Spike** (Proof of Concept, ~250 Zeilen HTML+JS) | +| `https://joerg-lohrer.de/` | live, unverändert | **Hugo-Altbestand** (bleibt bis Cutover) | +| `https://spa.joerg-lohrer.de/` | live | **Vanilla-HTML-Mini-Spike** (Proof of Concept) | | `https://svelte.joerg-lohrer.de/` | live | **SvelteKit-SPA** (35-Task-Plan komplett) | +| `https://staging.joerg-lohrer.de/` | live, leer | **Staging** (Webroot `joerglohrer26/` für Pipeline-Entwicklung; FTP-Creds in `.env.local`) | Die SvelteKit-SPA unter `svelte.joerg-lohrer.de` ist die Ziel-Implementierung. `spa.joerg-lohrer.de` bleibt als schlanke Referenz erhalten. Hugo läuft weiter, @@ -25,81 +26,104 @@ bis die Publish-Pipeline steht und der Cutover auf die Hauptdomain erfolgt. - **Autoren-Pubkey:** `npub1f7jar3qnu269uyx5p0e4v24hqxjnxysxudvujza2ur5ehltvdeqsly2fx9` (hex: `4fa5d1c413e2b45e10d40bf3562ab701a5331206e359c90baae0e99bfd6c6e41`) -- **Publizierte Events:** ~10 Langform-Posts (`kind:30023`), darunter - `dezentrale-oep-oer`, `offenheit-das-wesentliche`, `gleichnis-vom-saemann`, - `bibelfussball`, `dampfnudeln` u. a. +- **Publizierte Events:** ~10 Langform-Posts (`kind:30023`). Die restlichen + 8 Posts warten auf die Publish-Pipeline (Events werden beim ersten + `deno task publish --force-all`-Lauf erzeugt). - **Relay-Liste** (`kind:10002`): `relay.damus.io`, `nos.lol`, `relay.primal.net`, `relay.tchncs.de`, `relay.edufeed.org` - **Blossom-Server** (`kind:10063`): `blossom.edufeed.org`, `blossom.primal.net` -Bilder des ersten „experimentell publizierten" Posts (`dezentrale-oep-oer`) -liegen auf Blossom. Weitere 17 Altposts haben ihre Bilder noch unter dem -ursprünglichen Hugo-Permalink auf All-Inkl. +Bisher nur die Bilder des `dezentrale-oep-oer`-Posts auf Blossom. **Designentscheidung +2026-04-16:** Alle Bilder (inkl. der 17 Altpost-Bilder) kommen via Publish-Pipeline +auf Blossom — kein rsync-Legacy-Pfad mehr, kein `image_source: legacy`-Flag. +Einheitlicher Render-Pfad in der SPA. ## Repo-Struktur ``` joerglohrerde/ -├── content/posts/ # Markdown-Quelle (18 Posts, wird vom Publish-Skript gelesen) +├── content/posts/ # 18 Markdown-Posts, alle mit structured images: im Frontmatter ├── app/ # SvelteKit-SPA (Ziel-Implementation) ├── preview/spa-mini/ # Vanilla-HTML-Mini-Spike (Referenz) +├── publish/ # NOCH NICHT ANGELEGT — Publish-Pipeline (Task 1 aus Plan) ├── scripts/ │ └── deploy-svelte.sh # FTPS-Deploy nach svelte.joerg-lohrer.de ├── docs/ │ ├── STATUS.md # Dieses Dokument │ ├── HANDOFF.md # Wie man hier weitermacht +│ ├── redaktion-bild-metadaten.md # Checkliste, Bild-Durchgang (abgearbeitet) +│ ├── wiki-entwurf-nostr-bild-metadaten.md # Wiki-Konvention deutsch +│ ├── wiki-draft-nostr-image-metadata.md # Wiki-Konvention englisch │ └── superpowers/ -│ ├── specs/ # SPA-Spec + Publish-Pipeline-Spec -│ └── plans/ # SPA-Implementation-Plan (35 Tasks, abgeschlossen) +│ ├── specs/ # SPA + Publish-Pipeline + Bild-Metadaten-Konvention +│ └── plans/ +│ ├── 2026-04-15-spa-sveltekit.md # erledigt +│ └── 2026-04-16-publish-pipeline.md # ⬅ als nächstes ├── .claude/ │ ├── skills/ # Repo-spezifischer Claude-Skill -│ └── settings.local.json # Claude-Session-State (nicht committen? aktuell schon) -└── .env.local # Gitignored: FTP-Creds + Bunker-URL +│ └── settings.local.json # Claude-Session-State (gitignored) +└── .env.local # Gitignored: FTP-Creds, Bunker-URL, Publish-Pipeline-Keys ``` ## Branch-Layout (Git) -- **`main`** — kanonischer Zweig. Enthält Content, Specs, Pläne, Deploy-Scripts, - `.claude/`-Skill. Schlanker als früher (kein Hugo-Artefakt mehr). -- **`spa`** — aktueller Arbeits-Branch. SvelteKit-SPA in `app/` komplett - implementiert und live. **Aktuell vor `main` mit allen `spa:`-Commits.** -- **`hugo-archive`** — Orphan-Branch mit dem letzten funktionierenden - Hugo-Zustand, eingefroren. Rollback über `git checkout hugo-archive && hugo build`. +- **`main`** — kanonischer Zweig. +- **`spa`** — aktueller Arbeits-Branch, vor `main`. SvelteKit-SPA live, + Content-Migration (Bild-Metadaten) abgeschlossen, Publish-Pipeline geplant. +- **`hugo-archive`** — Orphan-Branch mit Hugo-Zustand, eingefroren. ## Setup-Zustand Einmalig manuell erledigt: - ✅ Amber-Bunker-URL in `.env.local` als `BUNKER_URL` -- ✅ SPA-FTP-Creds (`spa.joerg-lohrer.de`) in `.env.local` als `SPA_FTP_*` -- ✅ SvelteKit-FTP-Creds (`svelte.joerg-lohrer.de`) in `.env.local` als `SVELTE_FTP_*` -- ✅ `kind:10002`-Event publiziert -- ✅ `kind:10063`-Event publiziert -- ✅ Subdomains mit TLS + HSTS (`max-age=300`) +- ✅ FTP-Creds für alle Subdomains (SPA, SVELTE, STAGING) in `.env.local` +- ✅ `AUTHOR_PUBKEY_HEX` und `BOOTSTRAP_RELAY=wss://relay.primal.net` in `.env.local` +- ✅ `kind:10002`-Event publiziert (Relay-Liste) +- ✅ `kind:10063`-Event publiziert (Blossom-Server) +- ✅ Subdomains mit TLS + HSTS +- ✅ Staging-Subdomain `staging.joerg-lohrer.de` → Webroot `joerglohrer26/` Alles in `.env.local` — gitignored, nicht committet. -## Offene Punkte / Nicht-in-Scope +## Offene Punkte -- **Publish-Pipeline** (Spec vorhanden unter `docs/superpowers/specs/2026-04-15-publish-pipeline-design.md`, Plan noch nicht geschrieben) +- **Publish-Pipeline** — Spec + Plan vollständig, **Implementierung steht an** + (Task 1 aus `docs/superpowers/plans/2026-04-16-publish-pipeline.md`). - **Menü-Navigation** in der SPA (Home / Archiv / Impressum / Kontakt) - **Impressum-Seite** (braucht rechtlichen Text) -- **Meta-Stubs für Social-Previews und SEO** (wird Teil der Publish-Pipeline) -- **SSH-Zugang zu All-Inkl** (laut Notiz von Jörg: Premium-Tarif im Kommen → rsync statt FTPS möglich) -- **Cutover auf `joerg-lohrer.de`** (Hauptdomain bekommt dann die SvelteKit-SPA) +- **Cutover auf `joerg-lohrer.de`** (nach Pipeline-Live: Hauptdomain + bekommt die SvelteKit-SPA) + +## Erledigt seit 2026-04-15 + +- ✅ Content-Migration: alle 18 Posts haben strukturierte `images:`-Liste + im Frontmatter (91 Bilder, mit Alt-Text, Lizenz, Autor:innen, ggf. Caption + und Modifications). Commit `c023b59`. +- ✅ Erlebnispädagogik-Post: tote Amazon-Hotlinks entfernt, Literatur- + Liste aufgeräumt. +- ✅ Design-Entscheidung „Blossom-only" dokumentiert in Spec + `docs/superpowers/specs/2026-04-15-publish-pipeline-design.md`. +- ✅ Publish-Pipeline-Plan (24 Tasks, Blaupausen-tauglich) geschrieben: + `docs/superpowers/plans/2026-04-16-publish-pipeline.md`. +- ✅ Bild-Metadaten-Konvention (Phase 1) in Spec: + `docs/superpowers/specs/2026-04-16-image-metadata-convention.md`. +- ✅ Community-Wiki-Entwürfe (DE + EN) für Nostr-Bildattribution: + `docs/wiki-entwurf-nostr-bild-metadaten.md` + `-draft-nostr-image-metadata.md`. +- ✅ 5 `UNKNOWN`-Einträge im VR-Post zur Recherche markiert (bleiben erstmal so). ## Live-Verifikation -Jederzeit: ```sh curl -sI https://svelte.joerg-lohrer.de/ | head -3 -curl -sI https://spa.joerg-lohrer.de/ | head -3 +curl -sI https://staging.joerg-lohrer.de/ | head -3 ``` ## Kontakt zur Implementierung Alle Design-Entscheidungen in: - `docs/superpowers/specs/2026-04-15-nostr-page-design.md` (SPA) -- `docs/superpowers/specs/2026-04-15-publish-pipeline-design.md` (Publish) -- `docs/superpowers/plans/2026-04-15-spa-sveltekit.md` (35-Task-Plan, abgeschlossen) +- `docs/superpowers/specs/2026-04-15-publish-pipeline-design.md` (Publish, Blossom-only) +- `docs/superpowers/specs/2026-04-16-image-metadata-convention.md` (Bild-Metadaten-YAML) +- `docs/superpowers/plans/2026-04-16-publish-pipeline.md` (24 Tasks, als nächstes) -Für die nächste Session: `docs/HANDOFF.md` lesen. +Für die nächste Session: **`docs/HANDOFF.md`** lesen.