Notizen und Links zu Obstsorten — Verzeichnis der Obstsorten, verknüpft mit treedoc- und OSM-Bäumen jeder Sorte.
  • Go 96.5%
  • PLpgSQL 3.3%
  • Shell 0.2%
Find a file
Maximillian Dornseif db9e3c854b feat(web): Meine Bongerts zeigt den eigenen Sortenbestand
Seine Flaechen ankreuzen konnte man schon, aber danach nirgends sehen, was
darauf waechst -- die Auswahl war Mittel ohne Zweck. Die Seite fuehrt jetzt
unter "Meine Sorten" auf, was auf den gewaehlten Bongerts steht, mit der Zahl
der Baeume je Sorte, die baumreichste zuerst.

Gezaehlt wird ueber die View sorten_baeume, also ueber ALLE Namen einer Sorte:
ein Baum, der in treedoc "Boskop" heisst, zaehlt beim Schoener aus Boskoop
mit. Gerodete Baeume stehen nicht im Cache und fehlen von selbst -- die Zahl
ist eine Aussage ueber den heutigen Bestand. Nur treedoc-Baeume koennen
auftauchen, die 798 OSM-Baeume tragen keinen Bongert.

Darueber steht, wie viel vom Bestand ueberhaupt einen Namen traegt: heute bei
vier Flaechen 236 Sorten auf 336 von 399 Baeumen, 63 ohne bestimmte Sorte.
Diese Luecke ist auf einer Werkstattseite die eigentliche Auskunft -- sie sagt,
wo noch Arbeit liegt.

Die Spalte "Flaechen" erscheint nur bei mehreren eigenen Bongerts; sonst
stuende dort in jeder Zeile eine 1. Die Erklaerung der Auswahl ist zu den
Kaestchen gewandert, weil der Bestand jetzt darueber steht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 06:33:00 +02:00
.claude/skills feat(schnitt): der Vault-Import fällt, obstdoc trägt sich selbst 2026-08-15 10:04:55 +02:00
cmd feat(web): Meine Bongerts zeigt den eigenen Sortenbestand 2026-09-21 06:33:00 +02:00
docs feat(sync): der Anzeige-Server hält Bäume und Archiv selbst aktuell 2026-08-10 08:59:33 +02:00
internal feat(web): Meine Bongerts zeigt den eigenen Sortenbestand 2026-09-21 06:33:00 +02:00
schema feat(obstdoc): Bestand-Feld entfernt; generierte Beschreibung geschärft 2026-07-25 13:17:44 +02:00
scripts Initial commit: obstdoc — Obstsorten-Verzeichnis 2026-07-20 11:10:23 +02:00
web feat(web): Meine Bongerts zeigt den eigenen Sortenbestand 2026-09-21 06:33:00 +02:00
.gitignore feat(cli): obstdoc-sorte-anlegen 2026-09-09 08:35:38 +02:00
CHANGELOG.md feat(web): Meine Bongerts zeigt den eigenen Sortenbestand 2026-09-21 06:33:00 +02:00
CLAUDE.md feat(wiki): nach einem Tag fragen, und die Liste sagt, wonach sie filtert 2026-08-24 11:52:05 +02:00
config.yaml.example feat(sicherung): ein deterministisches Tar am Tag, und der Vault ist aus der Tabelle 2026-08-15 10:22:22 +02:00
go.mod fix(archiv): Sortenseiten mit Merkmalen rendern wieder 2026-09-03 23:25:18 +02:00
go.sum fix(archiv): Sortenseiten mit Merkmalen rendern wieder 2026-09-03 23:25:18 +02:00
merkmale-kalibrierung.md feat(merkmale): Vokabular der Sorten-Stichpunkte und Kalibrierung 2026-08-08 10:53:33 +02:00
README.md feat(schnitt): der Vault-Import fällt, obstdoc trägt sich selbst 2026-08-15 10:04:55 +02:00
treedoc-birnen-anweisung.md docs(treedoc-anweisung): Prüfstand 08.08. — 50 Knoten waren schon versorgt 2026-08-08 09:13:34 +02:00
verworfene-pdf-quellen.txt docs(treedoc-anweisung): Prüfstand 08.08. — 50 Knoten waren schon versorgt 2026-08-08 09:13:34 +02:00

obstdoc

Ein Verzeichnis der Obstsorten — Apfel, Birne, Quitte, Speierling und die anderen Fruchtarten. Während treedoc den einzelnen Baum dokumentiert, dokumentiert obstdoc die Sorte und zeigt zu jeder Sorte die dokumentierten (treedoc) und die in OpenStreetMap kartierten Bäume dieser Sorte.

Das Go-Modul heißt forge.23.nu/md/obstdoc. Es ist wie treework aufgebaut: eigener Postgres-Store, Bäume read-only über die öffentliche treedoc-HTTP-API, optionales OSM-OAuth nur für Identität.

Datenfluss

  Bearbeiten im Browser                treedoc-API        OSM / Overpass
        │  Formulare je Abschnitt,          │                   │
        │  mit Verlauf und Autor            │  Takt-Sync + Webhook (der Server)
        ▼                                   ▼                   ▼
  ┌──────────────────────────────────────────────────────────────────┐
  │  PostgreSQL  (DB: obstdoc, eigene DB — NICHT das replizierte      │
  │  treestore).  sorten + fruchtarten + sorten_namen + baeume-Cache  │
  │  Der Sorte↔Baum-Link ist die VIEW sorten_baeume (abgeleitet).     │
  └───────────────────────────────┬──────────────────────────────────┘
                                  ▲
                          ┌───────────────┐
                          │   obstdoc     │  Anzeige-Server: liest die Sorten,
                          └───────────────┘  schreibt Baum-Cache und Bearbeitungen
                                  │
                                  ▼  nächtlich, in Vault-Gestalt
                       s3://…/Sicherung/obstdoc/JJJJ-MM-TT/
                       (zurück mit obstdoc-auszug --einspielen)

Den Baum-Cache hält der Anzeige-Server selbst aktuell, damit obstdoc nicht davon abhängt, dass jemand ein Werkzeug startet:

  • Takt — alle sync_intervall (Vorgabe 24 h) ein Voll-Sync aus treedoc und Overpass. Das ist das Sicherheitsnetz: Repo.SaveTree in treedoc protokolliert nicht selbst, und nicht jedes CLI holt das nach — solche Änderungen melden keinen Webhook.
  • ZurufPOST /hooks/treedoc nimmt treedocs Änderungsereignisse an (Signatur, ±5-Minuten-Fenster, Webhook-Id gegen Wiederholungen), antwortet sofort und zieht die Bäume 5 Sekunden nach dem letzten Ereignis neu. Das Ereignis trägt keine Daten in die Datenbank; ein verlorener oder verfälschter POST kostet Aktualität, mehr nicht. Protokoll: ../treedoc/docs/webhooks.md, obstdoc-Seite: docs/treedoc-webhook-integration.md.
  • Archiv — hat sich am Bestand etwas geändert, rendert der Server die Sortenseiten und lädt die geänderten nach S3. Verglichen wird ein Abdruck je Quelle; ohne Änderung läuft kein Durchgang, denn er kostet einen treedoc-Aufruf je Baum. Ohne S3-Zugang in der Konfiguration bleibt das aus.

Der Kernpunkt: Namen sind uneinheitlich (Altbestand ist NFD, treedoc/OSM sind NFC; Bäume tragen Klammer-Synonyme wie „Peter Broich (Kaiser Willhelm)"). Alle Namensauflösung läuft über die SQL-Funktion obst_key() und die Tabelle sorten_namen. Der Sorte↔Baum-Link ist bewusst nicht gespeichert, sondern die View sorten_baeume — eine neue Alias-Zeile verknüpft alle betroffenen Bäume auf einmal, nichts wird stale.

Komponenten

Pfad Zweck
cmd/obstdoc HTTP-Anzeige-Server, inkl. Baum-Sync (hintergrund.go) und Webhook-Empfang (webhook.go)
internal/vault Liest Notizen mit Frontmatter — seit dem Schnitt nur noch für den Rückweg aus dem Auszug
internal/auszug Nächtlicher Vollabzug aller Sorten als Notizen
internal/store Postgres-Store + Schema (schema.sql)
internal/treedoc Read-only-Client der treedoc-API
internal/osm Overpass-Client (OSM-Bäume mit Cultivar-Tag)
internal/sync Baum-Cache aus treedoc + OSM aktualisieren
internal/auth OSM-OAuth (identisch zu treework)

Einrichten & Starten

# 1. Datenbank einmalig anlegen (Superuser):
#    CREATE DATABASE obstdoc; \c obstdoc; CREATE EXTENSION IF NOT EXISTS postgis;

cp config.yaml.example config.yaml   # db_dsn setzen

# 2. Server starten — er füllt den Baum-Cache beim Start und danach im Takt:
go run ./cmd/obstdoc                   # http://localhost:8768

Sorten werden im Browser bearbeitet, abschnittsweise, mit Verlauf. Wer schreiben darf, steht in auth.schreiber; für den eigenen Rechner öffnet OBSTDOC_SCHREIBER="*" alles, und das gehört nirgends sonst hin.

Eine leere Datenbank füllt man aus einem Auszug:

go run ./cmd/obstdoc-auszug --einspielen …/2026-08-15/Obstsorten

Den Baum-Cache baut der Server bei jedem Sync komplett neu auf (ReplaceBaeume).

Webhook-Abonnement anlegen

Einmalig, sonst bleibt es beim Takt-Sync. Die Ziel-Adresse muss in treedocs webhooks.allowed_hosts stehen (gepflegt in my_ansible), sonst antwortet treedoc mit 400 — das ist der SSRF-Schutz, kein Fehler.

TOKEN=$(ssh ruby.vpn.foxel.org 'sudo /opt/treedoc/bin/treedoc-token \
    --config /etc/treedoc/config.yaml --name obstdoc-setup --ttl 1h --quiet')

curl -sS -X POST https://treedoc.schnittsyndikat.de/api/tree/v1/webhooks \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"url":"https://obstdoc.schnittsyndikat.de/hooks/treedoc",
       "description":"obstdoc Baum-Cache","event_types":["tree.*"]}'

Die Antwort enthält secret einmalig — als treedoc_webhook_secret in die config.yaml, nicht ins Repo. Danach prüft POST /api/tree/v1/webhooks/{id}/ping die Zustellung, ohne einen Baum anzufassen.

Konfiguration (Env-Overrides)

Variable Zweck
OBSTDOC_DB_DSN Postgres-DSN der obstdoc-DB
OBSTDOC_SCHREIBER Freigabeliste fürs Bearbeiten (OSM-Kennungen, kommagetrennt)
TREEDOC_BASE_URL treedoc-API-Basis
OBSTDOC_TREEDOC_WEBHOOK_SECRET Signaturschlüssel des Webhook-Abonnements (whsec_…)
OBSTDOC_SYNC_INTERVALL Abstand der Voll-Syncs, z. B. 24h; 0s schaltet ab
OVERPASS_ENDPOINT / OVERPASS_RADIUS_KM OSM-Sync
OBSTDOC_OSM_CLIENT_ID / _SECRET / OBSTDOC_SESSION_SECRET OSM-OAuth