Weinverwaltung
Internal management tool for the Honsig family winery
Since late 2023, EU food-labelling rules require winemakers to publish detailed nutrient and ingredient information per wine. There’s no room for that on a label, so a QR code on the bottle points to a digital product data sheet. The Honsig family winery needed a lean way to maintain those sheets centrally, generate QR codes on demand, and hand them off for label printing.
The problem
Before the tool there was an Excel sheet and an online QR generator. Both worked — separately. At label-printing time codes were regenerated routinely because nobody could match the file to the right vintage. Also: ingredient information changes between vintages, and a QR code pointing at an outdated page is worse than no code at all.
Constraints
One user (the winemaker), irregular usage, no internet in the cellar. Hosting on their own web space, no licensing budget, a family that doesn’t want to do DevOps. Maintenance needed to be as small as possible. The tool should be able to run untouched for two years without breaking.
Architecture
The frontend is a Svelte single-page app built with Vite, styled with Tailwind and DaisyUI. Backend and database are handled by PocketBase — a single Go binary with built-in SQLite, auth, file storage, and REST API. The app talks directly to PocketBase; there’s no custom API layer in between.
Each wine is one record with master data (variety, vintage, alcohol) and a detail view with the required information. On save the tool generates a QR code pointing to the stable detail URL and offers it as a PNG download. A search across all data sheets accelerates re-using existing entries at label-printing time — more important in daily use than initial entry.
Decisions — and what I rejected
Backend: NestJS/MySQL → PocketBase. Building a custom backend for a single-user workflow is overhead. PocketBase replaces app server, auth, and database with a binary that boots in seconds. Less attention to plumbing, more attention to UI — and hosting drops auth migrations and database upgrades.
Framework: SvelteKit → Svelte + Vite. SvelteKit can do SSR and routing, but this is an internal tool behind a login. Nobody indexes it, there’s only one sensible entry point. SvelteKit would have introduced more concepts (server routes, load functions, adapters) without using any of them. Plain Svelte + Vite keeps the codebase shorter and the build smaller.
Styling: custom CSS → Tailwind + DaisyUI. I initially wanted to avoid class soup, tried Tailwind anyway — and didn’t switch back. DaisyUI gives sensible defaults for forms and buttons without hiding Tailwind classes. For an internal tool with no brand identity, “looks fine immediately” matters more than “stays inside a design system.”
QR generation: server → client. An earlier draft generated QR codes server-side in PocketBase. Rejected because client-side (with a qrcode library in the browser) is simpler: the QR code is a function of a URL the browser already has. No round trip, no server state.
What matters in operation
The goal wasn’t “fast” but “reliable.” The tool has been running untouched since 2024. PocketBase updates are a background binary swap. Backups are a file copy of the SQLite file. If hosting goes down, nothing urgent is missing — the label gets printed the next day.
What I would do differently
Vintage snapshots. Today a data sheet is overwritten when ingredient information changes. In theory labels from an older vintage could point to a page that now shows a newer vintage. Hasn’t happened in practice, but it’s a documented data-model weakness: one snapshot per vintage rather than one rolling document would be the right shape.
Bulk import for master data. The initial fill (~40 wines) was manual. A CSV import would have compressed setup from two evenings to two hours. For such a narrow use case it’ll probably never matter again — unless a second winery asks. Recognising non-tasks is a skill too.
Pre-print preview. The tool renders the data sheet in the browser but not what it looks like on a 30 mm label. A simple print preview (CSS print stylesheet) would be cheap and would close the last step before the press.