No description
  • Go 67.6%
  • TypeScript 23.2%
  • CSS 4.4%
  • HTML 2.9%
  • JavaScript 1.1%
  • Other 0.8%
Find a file
Maximillian Dornseif a718147559 feat(api)!: observed_at ist ein Zeitpunkt; position in /around
Notizen tragen jetzt eine Uhrzeit, nicht nur einen Tag:
tree_notes.observed_at wechselt von DATE auf TIMESTAMPTZ, im
API-Vertrag von `format: date` auf `format: date-time`. Ausgeliefert
wird RFC 3339 in Ortszeit des Bongerts; POST/PATCH nehmen weiterhin ein
blankes YYYY-MM-DD an, wenn nur der Tag bekannt ist. Mitternacht
Ortszeit ist die Konvention für "Uhrzeit unbekannt"
(internal/treestore/observedat.go, cmd/treedoc/ui/src/observedAt.ts),
deshalb kommt keine zweite Spalte dazu.

Damit ist auch die vorbestehende Vertragsverletzung erledigt:
observed_at lieferte RFC-3339-Zeitstempel gegen ein zugesagtes
`format: date`. Die OpenAPI-Middleware hatte das erkannt, aber
Response-Verstöße landen nur als Log-Warnung, nicht als Fehler.

Offline-Notizen aus TreePhoto behalten ihren Erfassungszeitpunkt statt
auf den Tag gekürzt zu werden. Fotos bleiben unverändert — deren
created_at war schon immer ein voller Zeitstempel.

Dazu: `position` (Bongert-Rasterkoordinate) fließt in die Antwort von
/api/tree/v1/around, und TreeDocsAround selektiert die Spalte. Ohne das
passende Scan-Ziel lief die Query in
"expected 13 destination arguments in Scan, not 12" — kein Test deckte
den Pfad ab.

Migration (bereits auf cleo und ruby gefahren):
  ALTER TABLE tree_notes ALTER COLUMN observed_at TYPE TIMESTAMPTZ
    USING (observed_at::timestamp AT TIME ZONE 'Europe/Berlin');

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 10:38:58 +02:00
cmd feat(api)!: observed_at ist ein Zeitpunkt; position in /around 2026-07-28 10:38:58 +02:00
config refactor: Review-Stage-Pipeline entfernt (treephoto-import, cluster, track) 2026-07-26 10:02:28 +02:00
internal feat(api)!: observed_at ist ein Zeitpunkt; position in /around 2026-07-28 10:38:58 +02:00
schema feat(api)!: observed_at ist ein Zeitpunkt; position in /around 2026-07-28 10:38:58 +02:00
scripts fix: release.sh prints jj-aware push instructions 2026-06-15 12:57:20 +02:00
.gitignore security: config.sandbox.yaml aus dem Tracking nehmen (Sandbox-Key + DB-Passwort) 2026-07-26 11:21:08 +02:00
.golangci.yml refactor 2026-05-21 07:43:39 +02:00
CHANGELOG.md feat(api)!: observed_at ist ein Zeitpunkt; position in /around 2026-07-28 10:38:58 +02:00
CLAUDE.md docs: Regeln für neue Tabellen + Datenbank-Rollen 2026-07-26 12:02:31 +02:00
config.sandbox.yaml.example security: config.sandbox.yaml aus dem Tracking nehmen (Sandbox-Key + DB-Passwort) 2026-07-26 11:21:08 +02:00
config.yaml.example chore: Config-Dateien aufgeräumt — tote Schlüssel raus 2026-07-26 11:13:09 +02:00
DEPLOY.md refactor: Review-Stage-Pipeline entfernt (treephoto-import, cluster, track) 2026-07-26 10:02:28 +02:00
go.mod URL in OSM etc 2026-06-18 07:46:32 +02:00
go.sum URL in OSM etc 2026-06-18 07:46:32 +02:00
INSTALL.md refactor: Review-Stage-Pipeline entfernt (treephoto-import, cluster, track) 2026-07-26 10:02:28 +02:00
Makefile fix: Build ohne npm liefert kein still kaputtes treedoc-Binary mehr 2026-07-26 11:31:33 +02:00
README.md refactor: Review-Stage-Pipeline entfernt (treephoto-import, cluster, track) 2026-07-26 10:02:28 +02:00

treedoc / treelink

Werkzeuge zum Erfassen, Verwalten und Publizieren von Fotos und Stammdaten von Obstbäumen. Das Go-Modul heißt forge.23.nu/md/treedoc.

Bäume werden mit treephoto.app (iPhone) fotografiert, in treedoc redaktionell bearbeitet und als statisches Archiv nach S3 ausgespielt. Zusätzliche Quelle ist der L&F-Obsidian-Vault.

Schnellstart

# Systemabhängigkeiten (Debian/Ubuntu)
apt install libimage-exiftool-perl imagemagick

make build          # React-UI + alle cmd/-Binaries nach bin/
./bin/treedoc       # → http://localhost:8767

Konfiguration: config.yaml (Vorlage: config.yaml.example; enthält Secrets und ist gitignored). Die DB-DSN kommt aus db_dsn bzw. TREEDOC_DB_DSN.

make check                                      # fmt, vet, lint, typecheck, tests
make sandbox-seed N=10 && make sandbox-treedoc  # Spielwiese auf :8768

Architektur, Paketstruktur und Datenflüsse: CLAUDE.md. Installation und Betrieb: INSTALL.md, DEPLOY.md. Änderungen: CHANGELOG.md.

Statische Archiv-Seite (store/{id}/index.html)

Pro Baum wird bei jedem Speichern eine statische, dependency-freie HTML-Seite nach S3 geschrieben (Langzeit-Archiv, oEmbed-konform). Die Vorlage ist:

internal/treestore/tree-static.html.tmpl

Das ist eine Go-html/template-Datei und wird per //go:embed fest ins Binary gebacken. Zum Ändern des Aussehens diese Datei bearbeiten und neu bauen (make build bzw. go build ./...). Die Seite muss ohne JavaScript und ohne externe Abhängigkeiten auskommen.

Die zugehörige oEmbed-Antwort (store/{id}/oembed.json) wird in Go erzeugt: Funktion RenderOEmbed in internal/treestore/render.go.

Alternativ lässt sich zur Laufzeit eine andere Vorlage per Flag übergeben (treedoc --template pfad/zur/vorlage.tmpl, ebenso cmd/render --template …); ist der Pfad leer oder unlesbar, greift die eingebettete Vorlage.

Bestehende Seiten neu rendern (z. B. nach einer Template-Änderung):

go run ./cmd/render --base https://treedoc.foxel.org --prefix store   # alle Bäume
go run ./cmd/rerender --base https://treedoc.foxel.org abc123 def456  # nur diese IDs