Commit Graph

24 Commits

Author SHA1 Message Date
Jörg Lohrer 4e4a5efa42 docs: plan-korrektur — svelte:head muss top-level stehen
Bei der umsetzung von task 4.2 stellte sich heraus, dass svelte
<svelte:head> nicht in einem {#if}-block stehen darf. Plan-code
korrigiert von

  {#if snapshot}<svelte:head>...</svelte:head>{/if}

zu

  <svelte:head>{#if snapshot}...{/if}</svelte:head>

Semantisch identisch (head-content erscheint nur wenn snapshot da ist),
aber svelte-konform.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 08:42:07 +02:00
Jörg Lohrer 0b287f9ff6 docs: jsonld via svelte-tag statt {@html}
User-feedback: <script type="application/ld+json"> kann svelte direkt
rendern. Kein @html-Notausgang noetig, sauberere variante mit
auto-escape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:56:58 +02:00
Jörg Lohrer 7428930a76 docs: implementation-plan fuer prerender-snapshot
Frischer plan gegen die ueberarbeitete spec (fallback_url raus,
OG-default joerg-profil-2024.webp, prerender+runtime-fallback klar
als adapter-static-default). Sechs etappen, jede einzeln testbar
und rollback-bar:

1. renderMarkdown auf isomorphic-dompurify (node-faehig)
2. Snapshot-modul (deno) mit 9 testbaren cores + cli
3. Snapshot in CI
4. Detail-route auf prerender mit runtime-fallback
5. Runtime-fallback entfernen (snapshot ist quelle)
6. lftp mirror in drei phasen (optional, nicht-blockierend)

Alter plan bleibt im archive als geschichte.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:54:18 +02:00
Jörg Lohrer a278f65edf docs: prerender-snapshot-spec — drei klarstellungen
- fallback_url im cover_image rausgenommen (YAGNI; primary url
  reicht, blossom ist content-addressed). Beim ersten konkreten
  bedarf nachreichen.
- Site-default-OG-bild auf app/static/joerg-profil-2024.webp
  festgelegt (vorhandenes asset, nicht spekulativ).
- prerender + runtime-fallback klarer formuliert: das ist das
  default-verhalten von adapter-static mit fallback, kein
  workaround. ReplyList/ReplyComposer-hydration als
  verifikations-punkt im plan-schritt 4 vermerkt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:46:51 +02:00
Jörg Lohrer 050a38d51a docs: plaene ins archiv verschoben
Alle 6 plaene unter docs/superpowers/plans/archive/. Davon 5 abgearbeitet
(SPA, publish-pipeline, 3x multilingual), 1 eingefroren (prerender-snapshot).
Checkboxen wurden waehrend der umsetzung nicht gepflegt — verbindlicher
stand ist STATUS.md und die jeweilige spec, das archive/README.md macht
die zuordnung sichtbar.

plans/ bleibt mit .gitkeep als verzeichnis bestehen, damit neue plaene
sofort wieder dort landen koennen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:30:31 +02:00
Jörg Lohrer 9017ed1926 docs: spec-header-konvention vereinheitlicht + cleanup-spec
Status-Header aller specs nach neuer konvention:
Entwurf | In Umsetzung | Umgesetzt (live seit YYYY-MM-DD) | Eingefroren | Verworfen.

Die zwei aeltesten specs (SPA, publish-pipeline) standen formal noch
auf "ausstehende User-Freigabe", obwohl seit 2026-04-18 live —
nun korrekt als umgesetzt markiert. Bild-metadaten-spec als
Phase 1 umgesetzt mit Phase-2-vermerk. Multilingual-spec angeglichen.
Prerender-snapshot-spec von "Stand:" auf "Status: Entwurf" mit
hinweis auf eingefrorenen plan im archiv.

Cleanup-spec selbst dokumentiert die konvention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:30:24 +02:00
Jörg Lohrer 11e406e5de docs: prerender-snapshot spec-klarstellungen + implementation-plan
spec:
- deploy upload-reihenfolge: drei-phasen-flow (assets → html → delete)
  mit präziser beschreibung statt flag-kombi-raten
- migrations-schritt 4 + 5 entkoppelt: 4 liefert snapshot primär mit
  runtime-fallback für nostr-first-posts, 5 entfernt fallback erst
  nach stabilem cutover
- exclude-glob im delete-pass für extern verwaltete files

plan (20 tasks, tdd):
- snapshot/ als deno-modul mit config, relays, dedup, plausibility,
  cover, extract, write — voll unit-getestet
- renderMarkdown auf isomorphic-dompurify
- sveltekit-route mit prerender=true, entries, og/twitter/json-ld/
  hreflang im head, snapshot-primary + runtime-fallback
- deploy-script auf lftp drei-phasen
- dokumentation in HANDOFF und CLAUDE.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 17:20:25 +02:00
Jörg Lohrer fd093dff5e docs: markdown-rendering aus snapshot in svelte-build verschoben
Der Snapshot liefert content_markdown, nicht content_html. Rendering
(marked + DOMPurify + highlight.js) passiert im SvelteKit-Prerender-
Schritt über das bereits existierende \$lib/render/markdown.ts —
keine Duplikation in Deno, kein gemeinsames Policy-Modul nötig.

Für Blaupausen-Nutzung ist rohes Markdown portabler: alternative
Renderer (Astro, Eleventy) bringen eigenen Markdown-Prozessor mit.

Konsequenz für Migration: Schritt 1 ist jetzt \"renderMarkdown
Node-kompatibel machen\" (isomorphic-dompurify) statt \"shared/
markdown-policy.ts ergänzen\".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 17:08:10 +02:00
Jörg Lohrer 48d05f8d2d docs: spec-review-eingearbeitet (HTML-render, Felder, Migration)
Nachschärfungen nach Review:
- content_html als primary im Snapshot-JSON (marked + DOMPurify +
  highlight.js, gemeinsame Policy in shared/markdown-policy.ts)
- content_markdown bleibt daneben (Debug + alternative Renderer)
- translations[] um title ergänzt (SPA-Switcher ohne Relay-Fetch)
- published_at vs. created_at semantisch klar getrennt (OG vs. Update)
- cover_image.fallback_url mit dokumentiertem Nutzungsszenario
- Fallback-Politik für fehlende summary/image/published_at
- --allow-shrink-Flag und kind:5-gestützte automatische Override
- Upload-Reihenfolge für Hash-benannte Bundles (Assets → HTML → Delete)
- /tag/<name>/-Verhalten in Nicht-Zielen erwähnt
- Edge-Case „Repo-Post + alle Relay-Events gelöscht" in Fehlertabelle
- Migrations-Weg um shared/markdown-policy.ts als Schritt 1 erweitert
- pro Migrations-Schritt explizite Rollback-Strategie

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 17:05:43 +02:00
Jörg Lohrer 708c86aa29 docs: spec für prerender-snapshot (SEO + social-media-cards)
Design-Dokument für die dreistufige Pipeline
publish → snapshot → build+deploy, die Post-Detailseiten mit echten
OG-Metadaten und prerendered Content versorgt, ohne Runtime-Relay-Fetch
und ohne Node-/Go-Server auf dem Shared-Hosting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 16:56:41 +02:00
Jörg Lohrer d12ed3c40e docs: status/handoff/readme/claude.md auf multilingual-stand
- README: neue plan-referenzen (3x multilingual), repo-struktur auf
  content/posts/<lang>/<slug>/, svelte-i18n + translations im app-tree
- STATUS: event-count 27 (26 de + 1 en), kurzfassung um mehrsprachigkeit,
  multilingual-abschnitt in „erledigt" (pipeline, spa, i18n + bugfixes)
- HANDOFF: option D entfernt (erledigt), neuer abschnitt „wie man eine
  übersetzung anlegt", frontmatter-template um a:-platzhalter,
  deploy-target-stolperfalle verschärft, vr-post-pfad aktualisiert
- Multilingual-spec: status von „noch nicht implementiert" auf „umgesetzt"
  + anmerkung zum post-switcher (📖 DE | EN statt text-hinweis)
- CLAUDE.md neu: knapper einstieg für agent-sessions mit commit-konvention,
  deploy-falle, zsh-globbing, forgejo-mirror-timing
- workflow-skill generalüberholt: post-cutover-stand, multilingual,
  publish-pipeline, activeLocale, 73 pipeline-tests

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 16:31:16 +02:00
Jörg Lohrer 5bab73def7 docs: plan 3/3 für multilinguale SPA (svelte-i18n + listen-filter)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:29:38 +02:00
Jörg Lohrer bf7b52ab9b feat(content): erste englische übersetzung (bible-selfies) + bidirektionaler a-tag
- neue sprach-variante content/posts/en/bible-selfies/ verweist auf dt. original
- dt. bibel-selfies verweist zurück auf bible-selfies
- plan 2/3: npm test → npm run test:unit (existing script name)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:53:59 +02:00
Jörg Lohrer c28a64ed49 docs: plan 2/3 für multilinguale SPA (a-tag-resolving + sprachhinweis)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:32:13 +02:00
Jörg Lohrer 66ff33e34a docs: plan 1/3 für multilinguale posts + spec-korrektur (26 statt 8 posts)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 09:14:43 +02:00
Jörg Lohrer 2b82994314 docs: design für multilinguale posts (content/posts/<lang>, l-/a-tags)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 08:48:29 +02:00
Jörg Lohrer 931ef9f03f docs: publish-pipeline-vorbereitung + bild-metadaten-konvention
- spec publish-pipeline aktualisiert: blossom-only (rsync-legacy-pfad raus)
- plan publish-pipeline (24 tasks in 12 phasen), blaupausen-tauglich:
  alle projekt-konstanten via env (BUNKER_URL, AUTHOR_PUBKEY_HEX,
  BOOTSTRAP_RELAY, CONTENT_ROOT, CLIENT_TAG, MIN_RELAY_ACKS)
- spec bild-metadaten-konvention (phase 1, yaml-basiert)
- wiki-entwurf deutsch + englisch: inline-markdown-konvention zur
  bildattribution mit mapping zu nip-92 imeta-tags. konvention für
  menschen, parser passt sich an; bei ambiguität eskalation zur
  redaktion statt stillem raten
- redaktions-checkliste für bild-durchgang (abgearbeitet, bleibt
  zum abgleich bei späteren migrationen)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 15:14:02 +02:00
Jörg Lohrer 937e356f4c plan: sveltekit-spa implementierung (35 tasks, 6 phasen)
Deckt die vollständige SPA-Spec ab: Setup + adapter-static, Daten-
ebene (Relay-Pool, Loader, Profil, Markdown, Signer), Routing mit
Legacy-URL-Normalisierung, Tag-Filter, Reactions, NIP-07-Kommentare.
TDD für pure Transformationen (URL-Parser, naddr, Markdown), E2E mit
Playwright für Happy-Paths.

Deploy-Ziel: svelte.joerg-lohrer.de. spa.joerg-lohrer.de bleibt als
Vanilla-Mini-Spike-MVP erhalten (Referenz-Verhalten).

Publish-Pipeline hat eigene Spec und bekommt separaten Plan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:57:26 +02:00
Jörg Lohrer 841b183b3c spec(spa): kurze form /<dtag>/ als kanonische url
Revidiert das URL-Schema: die lange Hugo-Form /YYYY/MM/DD/<dtag>.html/
wird als Legacy behandelt, die kurze Form /<dtag>/ als kanonisch.

Gründe: schöner zu teilen, skaliert über die 18 Altposts hinaus,
Datumskomponente fügt keinen Informationswert (Datum steht im Event
als published_at).

Legacy-URLs werden clientseitig via history.replaceState ohne Reload
auf die kurze Form normalisiert — Backlinks bleiben funktional,
Bookmarks konvergieren zur kurzen Form. Keine .htaccess-Redirects.

Im Mini-Spike bereits umgesetzt und live auf spa.joerg-lohrer.de.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:46:33 +02:00
Jörg Lohrer db86b7dd23 spec(spa): daten-transparenz statt stilles dedup
Die produktive SPA soll Events wahrheitsgetreu darstellen und nicht
defensiv korrigieren. Daten-Anomalien (doppelte t-Tags etc.) bleiben
sichtbar, damit der Autor sie wahrnimmt. Bereinigung gehört in
separate Audit-Werkzeuge, nicht in die SPA-Renderlogik.

Der Mini-SPA-Spike dedup'te pragmatisch — explizit als Abweichung
vom Zielverhalten vermerkt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:31:20 +02:00
Jörg Lohrer 4251fee668 spec(spa): erläuterung warum webspace für sveltekit ausreicht
Häufige Sorge ("kann mein einfaches Webspace-Paket SvelteKit hosten?")
explizit beantwortet: SvelteKit mit adapter-static produziert reine
statische Dateien, exakt analog zu Hugos public/. Webspace, FTP und
.htaccess reichen vollständig — keine Node-Runtime, keine Datenbank,
kein vServer nötig.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 13:46:45 +02:00
Jörg Lohrer febb3147fb spec(publish): pipeline für nostr-events via deno + amber + rsync
Publish-Pipeline für den Weg Markdown → signiertes kind:30023 → Relays,
plus Bilder-Upload (Legacy: rsync zu All-Inkl für die 18 Altposts;
Blossom: BUD-01-Upload für neue Posts).

Kernpunkte:
- Deno-Runtime, gemeinsame Library und CLI für lokal + GitHub Action
- NIP-46 Bunker (Amber-Stufe, später Optiplex-Stufe ohne Code-Change)
- Relay- und Blossom-Server-Listen via kind:10002 / kind:10063
  (manuell einmalig publiziert, identisch mit SPA-Nutzung)
- Git-Diff als Change-Detection, --force-all für Migration/Reimport
- State-los im Repo, keine Lock-Files, keine Commits zurück
- Pre-Flight `deno task check` validiert alle Voraussetzungen

Beziehung zur SPA-Spec: gemeinsame Event-Verträge (kind:30023, 10002,
10063) sind in dieser Spec normativ; SPA-Spec verweist darauf.
Publish läuft einmalig für die 18 Altposts (SPA-Migrationsschritt C)
vor dem SPA-Cutover (Schritt D).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:07:33 +02:00
Jörg Lohrer 6a4db658c6 spec(spa): relay-liste aus kind:10002 statt hartcodiert
Die Relay-Liste wird zur Laufzeit aus dem NIP-65-Outbox-Event geholt
(via Bootstrap-Relay), mit hartcodierter Fallback-Liste als Sicherheit.
Damit teilen SPA und Publish-Pipeline eine gemeinsame Quelle der
Wahrheit für Relay-Konfiguration — Änderungen erfordern nur ein neues
Event, keinen Code-Deploy.

Publish-Spec wird das normative Schema für kind:10002 und kind:10063
definieren; SPA-Spec verweist darauf.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:02:20 +02:00
Jörg Lohrer 4918175f8b spec: nostr-page auf basis von events — design
SvelteKit-SPA, die Blog-Posts live aus signierten kind:30023-Events
von Public-Relays rendert. Ablösung der Hugo-Seite auf All-Inkl ohne
eigene Infrastruktur in Phase 1; Stubs, eigener Relay und Blossom als
Evolutionspfad.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 09:25:11 +02:00