stammtisch-hersbruck/frontend
Daniel Michelberger 3ba8ec4c86 feat: Trailstatus in relativer Zeit
Ein Datum muss man erst gegen den heutigen Tag rechnen, um zu wissen, ob
eine Sperrung von gestern stammt oder vom letzten Sommer — der Abstand
sagt es sofort. Das genaue Datum steht daneben im Tooltip und geht
dadurch nicht verloren.

date-fns lag bereits im Projekt, es brauchte keine neue Library.
parseDate nimmt PocketBases "2026-09-12 08:30:00.000Z" mit Leerzeichen
statt T; die meisten Browser schlucken das, garantiert ist es nicht.

formatDate auf der Trail-Seite war eine Kopie von formatDateTime und
kommt jetzt aus $lib/time.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P32KoesVtABd6xWsqMKzhr
2026-09-07 22:09:41 +02:00
..
scripts feat: Typen aus der Schema-Migration erzeugen statt aus einer Instanz 2026-08-06 14:20:15 +02:00
src feat: Trailstatus in relativer Zeit 2026-09-07 22:09:41 +02:00
static chore: Repo-Struktur mit frontend/ und backend/ aufsetzen 2026-08-06 13:16:43 +02:00
.env.example feat: Typen aus der Schema-Migration erzeugen statt aus einer Instanz 2026-08-06 14:20:15 +02:00
.npmrc chore: Repo-Struktur mit frontend/ und backend/ aufsetzen 2026-08-06 13:16:43 +02:00
components.json chore: Repo-Struktur mit frontend/ und backend/ aufsetzen 2026-08-06 13:16:43 +02:00
package-lock.json fix: Deployment-Build durch jsdom-Downgrade auf 29 reparieren 2026-08-14 15:59:31 +02:00
package.json fix: Deployment-Build durch jsdom-Downgrade auf 29 reparieren 2026-08-14 15:59:31 +02:00
README.md fix: Deployment reparieren — adapter-node und Node-Anforderung festschreiben 2026-08-06 14:52:00 +02:00
svelte.config.js fix: Deployment reparieren — adapter-node und Node-Anforderung festschreiben 2026-08-06 14:52:00 +02:00
tsconfig.json chore: Repo-Struktur mit frontend/ und backend/ aufsetzen 2026-08-06 13:16:43 +02:00
vite.config.ts feat: GPX-Parser mit Länge, Höhenmetern und Streckenvereinfachung 2026-08-06 17:19:02 +02:00

stammtisch-hersbruck.de — Frontend

SvelteKit-5-Anwendung (Svelte 5 Runes, Tailwind 4) für Zeitnahme und Verwaltung.

Einrichten

.env aus der Vorlage anlegen und ausfüllen — .env.example beschreibt jede Variable:

cp .env.example .env
npm ci
npm run dev

Die App läuft dann auf http://stammtisch-hersbruck.de.localhost:31337

Befehle

Befehl Zweck
npm run dev Development-Server (Port 31337, strict)
npm run build Produktions-Build
npm run preview Produktions-Build lokal ansehen
npm run check Typprüfung (svelte-check)
npm run check:watch Typprüfung im Watch-Modus
npm run generate-pocketbase-types src/lib/types.d.ts aus dem PocketBase-Schema erzeugen

Welche PocketBase-Instanz?

PUBLIC_PB_URL in .env entscheidet, wohin das Frontend spricht:

Wert Instanz
https://api.stammtisch-hersbruck.de produktiv (Default)
http://127.0.0.1:8090 lokales Backend aus ../backend

Die Variable wird von SvelteKit zur Buildzeit eingesetzt ($env/static/public). Ein Wechsel der Instanz erfordert deshalb einen Neustart des Dev-Servers bzw. einen neuen Build — ein bloßer Neustart des Containers genügt nicht.

Es ist die einzige Variable in .env; ein Token wird nicht mehr gebraucht.

Deployment

Gebaut wird mit adapter-node; der Startbefehl ist node build. adapter-auto funktioniert hier nicht — es erkennt Coolify nicht, meldet „Could not detect a supported production environment" und erzeugt gar kein build/, woraufhin node build sofort scheitert.

Zwei Dinge müssen in der Deployment-Umgebung stimmen:

PUBLIC_PB_URL muss als Environment-Variable gesetzt sein. Sie wird zur Buildzeit eingesetzt; fehlt sie, bricht schon der Build ab:

"PUBLIC_PB_URL" is not exported by "virtual:env/static/public"

Die .env aus dem Arbeitsverzeichnis steht auf dem Build-Server nicht zur Verfügung — sie ist gitignored.

Node ≥ 22.12. Das engines-Feld in package.json schreibt die Anforderung von vite und @sveltejs/vite-plugin-svelte fest. Zusammen mit engine-strict=true aus der .npmrc bricht npm ci bei einer älteren Version ab (EBADENGINE) — was bei Node 22.11 aus einem NIXPACKS_NODE_VERSION=22 bereits passiert ist.

Typen

Das maßgebliche Schema liegt als Migration in ../backend/pb_migrations/. Daraus entstehen auch die TypeScript-Typen:

npm run generate-pocketbase-types

Das Script liest das Collections-Array aus der Migration (scripts/schema-to-json.mjs) und erzeugt daraus src/lib/types.d.ts. Es braucht keine laufende Instanz, keinen Token und keinen Netzwerkzugriff — Schema und Typen kommen aus derselben versionierten Quelle und können deshalb nicht auseinanderlaufen.

Nach jeder Schema-Änderung in ../backend/pb_migrations/ einmal ausführen und die aktualisierte types.d.ts mitcommitten.

Die System-Collections (_superusers, _mfas, …) stehen bewusst nicht in der Migration und fehlen deshalb in den Typen. Die Anwendung verwendet sie nicht.