Weinverwaltung
Internes Verwaltungstool für das Familienweingut Honsig
Die EU-Vorgaben zur Lebensmittelkennzeichnung verlangen seit Ende 2023 auch von Winzern detaillierte Nährwert- und Inhaltsstoffangaben pro Wein. Auf Etiketten ist dafür kaum Platz, also kommt ein QR-Code auf die Flasche, der auf ein digitales Produktdatenblatt verlinkt. Das Weingut Honsig brauchte eine schlanke Möglichkeit, diese Datenblätter zentral zu pflegen, QR-Codes auf Knopfdruck zu erzeugen und sie zur Etikettenproduktion bereitzustellen.
Das Problem
Vor dem Tool gab es eine Excel-Tabelle und einen Online-QR-Generator. Beides funktionierte – getrennt. Beim Etikettendruck wurden Codes regelmäßig neu generiert, weil niemand mehr wusste, welche Datei zu welchem Jahrgang gehörte. Außerdem änderten sich Inhaltsstoffangaben zwischen Jahrgängen, und ein QR-Code, der auf eine veraltete Seite verweist, ist schlimmer als gar keiner.
Rahmenbedingungen
Ein Nutzer (der Winzer), unregelmäßige Nutzung, kein Internet im Keller. Hosting im eigenen Webspace, kein Budget für Lizenzen, eine Familie, die kein DevOps machen will. Wartung musste so klein wie möglich werden. Das Tool darf auch zwei Jahre lang ungewartet im Hintergrund laufen, ohne dass etwas kaputtgeht.
Architektur
Das Frontend ist eine Svelte-Single-Page-App, gebaut mit Vite, gestylt mit Tailwind und DaisyUI. Backend und Datenbank macht PocketBase – ein einzelnes Go-Binary mit eingebauter SQLite-DB, Auth, File-Storage und REST-API. Die App spricht direkt mit PocketBase, kein eigener API-Layer dazwischen.
Pro Wein gibt es einen Datensatz mit Stammdaten (Sorte, Jahrgang, Alkohol) und einer Detailseite mit den verpflichtenden Angaben. Beim Speichern erzeugt das Tool den QR-Code zur stabilen Detail-URL und stellt ihn als PNG zum Download bereit. Eine Suche über alle Datenblätter beschleunigt das Wiederverwenden vorhandener Einträge bei der Etikettenproduktion – im Alltag wichtiger als das initiale Anlegen.
Entscheidungen – und was verworfen wurde
Backend: NestJS/MySQL → PocketBase. Für einen Single-User-Workflow ein eigenes Backend zu bauen, wäre Overhead. PocketBase ersetzt App-Server, Auth und Datenbank durch eine Binary, die in Sekunden hochläuft. Das bedeutet weniger Aufmerksamkeit für Plumbing, mehr Aufmerksamkeit für die UI – und beim Hosting fallen Auth-Migrationen und Datenbank-Upgrades weg.
Framework: SvelteKit → Svelte + Vite. SvelteKit kann SSR und Routing, aber das Tool ist ein internes Werkzeug hinter Login. Niemand muss es indexieren, es gibt nur einen sinnvollen Einstiegspunkt. SvelteKit hätte mehr Konzepte (Server-Routen, Load-Functions, Adapter) ins Spiel gebracht, ohne einen davon zu nutzen. Plain Svelte + Vite hält die Codebasis kürzer und das Build-Output kleiner.
Styling: Custom CSS → Tailwind + DaisyUI. Ich wollte initial keine Klassen-Soup, habe es trotzdem mit Tailwind versucht – und nicht zurückgewechselt. DaisyUI gibt sinnvolle Defaults für Formulare und Buttons, ohne die Tailwind-Klassen zu verstecken. Bei einem internen Tool ohne eigenes Branding zählt „sieht ok aus, sofort“ mehr als „bricht visuell aus dem Markenstil aus“.
QR-Generierung: Server → Client. Ein älterer Entwurf erzeugte QR-Codes serverseitig in PocketBase. Verworfen, weil clientseitig (mit qrcode-Lib im Browser) einfacher ist: der QR-Code ist eine Funktion der URL, die der Browser ohnehin kennt. Kein Roundtrip nötig, kein Server-State.
Was im Betrieb zählt
Wichtig war nicht „schnell“, sondern „zuverlässig“. Das Tool läuft seit 2024 ohne Eingriff. PocketBase-Updates sind ein binary-Austausch im Hintergrund. Backups sind ein File-Copy der SQLite-Datei. Wenn der Webspace ausfällt, fehlt nichts Eiliges – das Etikett wird halt am nächsten Tag gedruckt.
Was ich anders machen würde
Jahrgangs-Snapshots. Aktuell wird ein Datenblatt überschrieben, wenn sich Inhaltsstoffangaben ändern. Theoretisch könnten Etiketten alter Jahrgänge dadurch auf eine Seite zeigen, die für einen neueren Jahrgang gilt. In der Praxis nicht passiert, aber als Datenmodell-Schwäche dokumentiert: ein Datenblatt pro Jahrgang als Snapshot statt ein gleitendes Dokument wäre die richtige Lösung.
Bulk-Import für die Stammdaten. Die initiale Befüllung war händisch (~40 Weine). Ein CSV-Import hätte die Einarbeitungszeit von zwei Abenden auf zwei Stunden gedrückt. Bei einem so engen Anwendungsfall wäre das vermutlich nie wieder relevant – außer wenn ein zweites Weingut anfragt. Nicht-Aufgaben rechtzeitig zu erkennen ist auch ein Skill.
Pre-Print-Preview. Das Tool zeigt das Datenblatt im Browser, nicht aber wie es auf einem 30-mm-Etikett aussieht. Eine schlichte Druck-Vorschau (CSS-Print-Stylesheet) wäre billig und würde den letzten Schritt vor dem Druck schließen.