2026-04-15 18:34:15 +02:00
|
|
|
# Handoff — Nächste Session
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
2026-04-16 15:17:57 +02:00
|
|
|
## Zustand (Details in `STATUS.md`)
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
**Die Nostr-Publish-Pipeline ist live.** Alle 18 Posts sind publiziert als
|
|
|
|
|
`kind:30023`-Events auf 5 Relays, 91 Bilder auf 2 Blossom-Servern. Die
|
|
|
|
|
SvelteKit-SPA unter `svelte.joerg-lohrer.de` rendert alles ordentlich.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
**Das inhaltliche Kernziel des Gesamtprojekts ist damit erreicht.**
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Der Rest sind Feinschliff- und Cutover-Aufgaben.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
## Was als Nächstes ansteht
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:44:00 +02:00
|
|
|
### Option 1 — CI-Push-Auto-Trigger verifizieren (optional)
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:44:00 +02:00
|
|
|
**Status:** Workflow-Manual-Trigger ist grün (Run #1 am 18.04.2026).
|
|
|
|
|
Automatischer Auto-Trigger bei Content-Push noch nicht ausprobiert —
|
|
|
|
|
kann jederzeit beiläufig mitgenommen werden:
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:44:00 +02:00
|
|
|
1. Minimaler Edit in einem Post (z. B. Typo) → commit → push `main`
|
|
|
|
|
2. Forgejo synct automatisch zu GitHub → Workflow triggert → 1 Post als
|
|
|
|
|
`update` publiziert
|
|
|
|
|
3. Log-Artefakt in GitHub Actions prüfen
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:44:00 +02:00
|
|
|
Kein Ziel mehr, nur Bestätigung. Pipeline ist funktional vollständig.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
### Option 2 — Cutover auf `joerg-lohrer.de`
|
2026-04-16 15:17:57 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
**Voraussetzung:** Option 1 optional, aber nicht blockierend. Die Pipeline
|
|
|
|
|
läuft ja schon, ob manuell oder via CI ist für den Cutover egal.
|
2026-04-16 15:17:57 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
**Schritte:**
|
|
|
|
|
1. In All-Inkl KAS die Domain `joerg-lohrer.de` auf den SvelteKit-Webroot
|
|
|
|
|
umhängen (aktuell: `svelte.joerg-lohrer.de` → `/www/htdocs/v109928/joerglohrer28/`
|
|
|
|
|
oder welcher Ordner auch immer).
|
|
|
|
|
2. SvelteKit-SPA deployen, sofern sie nicht schon dort liegt.
|
|
|
|
|
3. Live-Check: `curl -sI https://joerg-lohrer.de/` → sollte die neue SPA
|
|
|
|
|
liefern, nicht mehr Hugo.
|
2026-04-16 15:17:57 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Hugo-Altbestand bleibt als Archiv im `hugo-archive`-Branch.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 14:30:37 +02:00
|
|
|
### Option 3 — Startseite + Menü-Navigation + Impressum in der SPA
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 14:30:37 +02:00
|
|
|
**Unabhängig von Cutover**, aber Voraussetzung für diesen: ohne Design wäre
|
|
|
|
|
die Hauptdomain eine rohe Post-Liste.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 14:30:37 +02:00
|
|
|
- **Startseite** bekommt ein eigenes Design (nicht nur Post-Liste dump)
|
|
|
|
|
- **Menü-Navigation** in `app/src/routes/+layout.svelte` (Home, Archiv,
|
|
|
|
|
Impressum, Mastodon-Link)
|
|
|
|
|
- **Impressum** als Static-Page (SvelteKit-Route `/impressum/`), **nicht**
|
|
|
|
|
als Nostr-Event — soll nicht als Blog-Beitrag in Listen erscheinen.
|
|
|
|
|
Text ist bereits im `content/`-Ordner (Repo-Quelle); die einzige
|
|
|
|
|
rechtlich relevante HTML-Datei, die auf dem Server liegt.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 14:30:37 +02:00
|
|
|
### Option 4 — SPA respektiert `kind:5`-Deletion-Events
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 14:30:37 +02:00
|
|
|
**Status:** aktuell filtert die SPA nicht nach NIP-09. Wenn ein Event per
|
|
|
|
|
`kind:5`-Referenz gelöscht wurde (z. B. `7f5d08b8…` deletet `89609df5…`
|
|
|
|
|
für `d=1744905463975` am 18.04.), zeigen Relays es meist nicht mehr aus —
|
|
|
|
|
aber die SPA würde es trotzdem rendern, falls ein Relay es doch liefert.
|
|
|
|
|
|
|
|
|
|
**Zu tun:** im `kind:30023`-Loader (`app/src/lib/nostr/...`) einen
|
|
|
|
|
Cross-Check auf `kind:5`-Events einbauen. Events, deren Addressable-Pointer
|
|
|
|
|
(`30023:pubkey:d-tag`) in einem `kind:5` referenziert ist, werden
|
|
|
|
|
gefiltert. Defensive Maßnahme für zukünftige Duplikate / Soft-Deletes.
|
|
|
|
|
|
|
|
|
|
### Option 5 — Repo/Nostr-Konflikt-Management
|
|
|
|
|
|
|
|
|
|
**Warum:** aktuell ist die Pipeline eine einseitige Straße — Repo → Nostr.
|
|
|
|
|
Wenn du via Client (Habla, Yakihonne, Amber) auf Nostr editierst,
|
|
|
|
|
überschreibt der nächste Pipeline-Lauf deine Client-Edits mit dem (alten)
|
|
|
|
|
Repo-State. Das ist ein echter Datenverlust-Risikofaktor.
|
|
|
|
|
|
|
|
|
|
**Zu tun:**
|
|
|
|
|
- **Defensiv (`created_at`-Check):** Pipeline liest vor Publish das
|
|
|
|
|
aktuelle Event vom Relay und vergleicht `created_at`. Wenn das
|
|
|
|
|
Remote-Event neuer ist: Abbruch mit Warnung.
|
|
|
|
|
- **Reverse-Sync (`pull-from-nostr`-Subcommand):** liest Events, vergleicht
|
|
|
|
|
mit Repo, zeigt Diffs. Manuelle Konfliktauflösung.
|
|
|
|
|
|
|
|
|
|
Keine Eile, solange du nicht parallel editierst. Erst relevant, wenn du
|
|
|
|
|
dich an Habla & Co. gewöhnst.
|
|
|
|
|
|
|
|
|
|
### Option 6 — NIP-09-Delete als Pipeline-Subcommand
|
|
|
|
|
|
|
|
|
|
**Status:** heute einmalig per `nak event -k 5 …` mit neu erzeugter Bunker-
|
|
|
|
|
URL erledigt (Duplikat `1744905463975`). Das war ein Workaround um das
|
|
|
|
|
„already connected"-Problem unserer Pipeline-Signer-Wiederverwendung.
|
|
|
|
|
|
|
|
|
|
**Zu tun:** in `publish/src/subcommands/` einen `delete`-Subcommand bauen,
|
|
|
|
|
der NIP-09 sauber erledigt und unsere stabile Signer-Identität nutzt.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
deno task publish-delete --slug <slug>
|
|
|
|
|
# oder
|
|
|
|
|
deno task publish-delete --event-id <hex>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Jetzt nicht dringend — nur bauen, wenn der Fall öfter eintritt.
|
|
|
|
|
|
|
|
|
|
### Option 7 — Pipeline weg von GitHub (self-hosted CI)
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
**Wann:** Wenn der Optiplex-Server steht und ein zentraler Ort für Dienste
|
|
|
|
|
existiert.
|
2026-04-16 15:17:57 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
**Varianten:**
|
|
|
|
|
- **Cron / systemd-Timer** auf dem Optiplex, der alle X Minuten `git pull &&
|
|
|
|
|
deno task publish` macht. Einfach, minimaler Setup.
|
|
|
|
|
- **Woodpecker-CI** als Docker-Container neben Forgejo. Volle Push-getriggerte
|
|
|
|
|
Pipeline ohne GitHub.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Der Pipeline-Code selbst (`publish/src/**`) ist CI-agnostisch — nur die
|
|
|
|
|
Trigger-Konfiguration ändert sich.
|
2026-04-15 18:34:15 +02:00
|
|
|
|
|
|
|
|
## 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)
|
2026-04-18 07:27:48 +02:00
|
|
|
3. Für CI-Themen: `docs/github-ci-setup.md`
|
|
|
|
|
4. Für Pipeline-Fragen: `docs/superpowers/specs/2026-04-15-publish-pipeline-design.md`
|
2026-04-15 18:34:15 +02:00
|
|
|
|
|
|
|
|
## Dev-Kommandos
|
|
|
|
|
|
|
|
|
|
```sh
|
2026-04-18 07:27:48 +02:00
|
|
|
# SPA-Tests
|
2026-04-15 18:34:15 +02:00
|
|
|
cd app && npm run test:unit
|
|
|
|
|
cd app && npm run test:e2e
|
|
|
|
|
cd app && npm run check
|
|
|
|
|
cd app && npm run dev
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
# SPA-Build + Deploy
|
2026-04-15 18:34:15 +02:00
|
|
|
cd app && npm run build && cd .. && ./scripts/deploy-svelte.sh
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
# Publish-Pipeline
|
|
|
|
|
cd publish && deno task check # pre-flight
|
|
|
|
|
cd publish && deno task publish --dry-run # diff-modus simulation
|
|
|
|
|
cd publish && deno task publish # diff-modus echt
|
|
|
|
|
cd publish && deno task publish --force-all # alle posts
|
|
|
|
|
cd publish && deno task publish --post <slug> # einen post
|
|
|
|
|
cd publish && deno task test # 59 tests
|
2026-04-15 18:34:15 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Bekannte Stolperfallen
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
- **Amber-Bunker:** bei neuer Bunker-URL müssen die zwei Permissions
|
|
|
|
|
(`get_public_key`, `sign_event`) in Amber auf „Allow + Always" gesetzt
|
|
|
|
|
werden, bevor Publish-Requests verarbeitet werden. Siehe
|
|
|
|
|
`docs/github-ci-setup.md` für Details.
|
|
|
|
|
- **`CLIENT_SECRET_HEX`** in `.env.local` identisch mit GitHub-Secret —
|
|
|
|
|
sorgt dafür, dass sich beide Umgebungen bei Amber mit derselben App
|
|
|
|
|
anmelden. Rotieren nur bei bewusstem Neu-Pairing in Amber.
|
|
|
|
|
- **`relay.damus.io`** bestätigt Events manchmal nicht mit `OK`. Bekanntes
|
|
|
|
|
Damus-Verhalten, wird toleriert (MIN_RELAY_ACKS=2, andere 4 Relays sind
|
|
|
|
|
zuverlässig).
|
|
|
|
|
- **Svelte 5 Runes:** `$props()`-Werte via `$derived()` in lokale Variablen.
|
|
|
|
|
- **Hugo-quotierte Dates:** `date: "2023-02-26"` ist ein YAML-String, nicht
|
|
|
|
|
ein Date-Objekt. `validatePost` coerced das automatisch; in neuen Posts
|
|
|
|
|
am besten ohne Quotes schreiben.
|
2026-04-16 15:17:57 +02:00
|
|
|
|
|
|
|
|
## Offene UNKNOWN-Einträge zur späteren Recherche
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Im VR-Post (`content/posts/2021-08-15-virtual-reality/index.md`) sind
|
|
|
|
|
4 Bilder als `license: UNKNOWN / authors: UNKNOWN` markiert:
|
2026-04-16 15:17:57 +02:00
|
|
|
- `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)
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Pipeline loggt Warnungen, publisht aber trotzdem. Recherche-Notizen in
|
|
|
|
|
`docs/redaktion-bild-metadaten.md`.
|
|
|
|
|
|
|
|
|
|
## Session-Kontext
|
|
|
|
|
|
|
|
|
|
Hilfreich beim Wiedereinstieg mit Claude:
|
|
|
|
|
- Branch-Check: `git log --oneline -10 spa main`
|
|
|
|
|
- Live-Check SPA: `curl -sI https://svelte.joerg-lohrer.de/`
|
|
|
|
|
- Event-Count: `nak req -k 30023 -a 4fa5d1c413e2b45e10d40bf3562ab701a5331206e359c90baae0e99bfd6c6e41 wss://relay.primal.net 2>/dev/null | jq -s 'length'` → 18
|
|
|
|
|
- Pipeline-Tests: `cd publish && deno task test` → 59 grün
|
2026-04-16 15:17:57 +02:00
|
|
|
|
|
|
|
|
## Community-Wiki-Entwürfe
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Liegen im Repo, noch nicht extern veröffentlicht:
|
2026-04-16 15:17:57 +02:00
|
|
|
- `docs/wiki-entwurf-nostr-bild-metadaten.md` — DE
|
|
|
|
|
- `docs/wiki-draft-nostr-image-metadata.md` — EN
|
|
|
|
|
|
2026-04-18 07:27:48 +02:00
|
|
|
Können als NIP-Proposal oder auf nostrbook.dev eingebracht werden, jetzt wo
|
|
|
|
|
die Konvention in der Praxis validiert ist.
|