Running a yacht club involves more than just boats and sails. Behind the scenes, there are beverages to track, inventory to manage, bills to settle, and community events to organize. The Wiesbadener Yacht Club (WYC) needed a modern system to replace manual beverage tracking, paper-based accounting, and chaotic volunteer coordination for their annual Schiersteiner Hafenfest. The result is a full-stack TypeScript application that handles everything from kiosk operations to volunteer shift management — built with React 18, Express.js, and PostgreSQL.

The Problem

Yacht clubs and similar community organizations face a unique set of operational challenges that off-the-shelf software does not address:

  • Beverage Tracking: Members consume beverages at the club throughout the season. Tracking who drank what, when, and how much they owe is done on paper lists that get lost, smudged, or disputed.
  • Inventory Management: Knowing when to reorder, what is in stock, and reconciling purchases with consumption requires manual counting and spreadsheet gymnastics.
  • Billing Complexity: Members need periodic invoices. Accounting staff need transaction histories. The treasurer needs revenue reports. None of this is automated.
  • Event Volunteer Coordination: The Schiersteiner Hafenfest is a major annual event where the club runs a beer stand. Coordinating dozens of volunteers across multiple shifts over four days is a logistical nightmare with group chats and shared documents.

When your volunteer coordination happens over WhatsApp and your beverage tracking lives on a paper list pinned to the bar, something is going to fall through the cracks.

The Solution

WYC Wiesbaden is a purpose-built management system with two major modules: a Beverage Management System for year-round club operations and a Hafenfest Helper Registration system for annual event volunteer coordination. The application is fully responsive, works on mobile devices (critical for kiosk use at the bar), and supports role-based access control with six distinct user roles.

Key Features

Beverage Management

  • Kiosk Mode — Simplified interface for quickly recording beverage consumption at the bar
  • Member Accounts — Track individual consumption with running balances
  • Inventory Tracking — Monitor stock levels and flag low-inventory items
  • Billing and Invoicing — Generate member invoices with detailed consumption breakdowns
  • Product Management — Configure beverages, pricing, and categories
  • Paper List Processing — OCR service to digitize handwritten consumption lists

Hafenfest Helper Registration

A comprehensive volunteer management system for the club’s beer stand at the Schiersteiner Hafenfest 2025 (July 11-14):

  • Public Registration (/hafenfest) — Mobile-optimized signup where volunteers select their preferred shifts
  • Admin Dashboard (/hafenfest/admin) — Full management interface with manual add, remove, move, and delete capabilities
  • Public Shift View (/hafenfest-view) — Transparent overview showing current sign-ups per shift (no admin functions)
  • Personal Links (/hafenfest/{uniqueLink}) — Each volunteer gets a short memorable URL (e.g., maxmuster123) for easy updates
  • WhatsApp Lists — Generate formatted WhatsApp messages per shift for quick communication
  • CSV Export — Export all registrations for offline planning

Shift Structure

Day 14:00-17:00 17:00-20:00 20:00-24:00
Friday 11.07 3 helpers needed 4 helpers needed 5 helpers needed
Saturday 12.07 3 helpers needed 4 helpers needed 5 helpers needed
Sunday 13.07 3 helpers needed 3 helpers needed 4 helpers needed
Monday 14.07 2 helpers needed 3 helpers needed 5 helpers needed

Role-Based Access Control

Six user roles provide granular access control:

  • Admin — Full system access including user management and all settings
  • Accounting — Financial operations, billing, and transaction history
  • Member — Standard user access to personal consumption and balance
  • Inventory — Product management and stock operations
  • Paper — Paper list processing and digitization
  • Kiosk — Simplified interface for bar operations only

Technology Stack

Layer Technology Purpose
Frontend React 18, TypeScript, Vite, TailwindCSS, Shadcn/UI Responsive web application
Routing Wouter Lightweight client-side routing
State React Query + React Context Server state and auth state management
Forms React Hook Form + Zod Type-safe form handling and validation
Backend Express.js, TypeScript RESTful API server
Database PostgreSQL (Neon) Cloud-hosted relational database
ORM Drizzle ORM + Zod Type-safe queries and schema validation
Auth Custom OTP + Express Sessions Phone-based authentication
Build Vite (frontend) + esbuild (backend) Fast builds for both layers

Architecture

The application follows a clean full-stack TypeScript architecture with shared types between frontend and backend.

The Frontend (/client) is a React 18 SPA built with Vite and TailwindCSS. Components use Shadcn/UI primitives for a consistent design system. Routing is handled by Wouter (a lightweight alternative to React Router). Server state is managed through React Query, which handles caching, refetching, and optimistic updates. Authentication state flows through React Context providers.

The Backend (/server) is an Express.js API with middleware for authentication and role-based access control. Business logic is organized into services: OTP service for phone-based login, OCR service for paper list digitization, and a scraper service. The API follows RESTful conventions with all endpoints under /api/*.

The Shared Layer (/shared) contains TypeScript types and the Drizzle ORM schema definition (schema.ts), ensuring type safety from database to frontend. Zod schemas validate data at API boundaries.

Authentication uses a phone + OTP flow: users receive a one-time password via SMS, which is verified against the database. Sessions are stored in PostgreSQL for persistence across server restarts.

/client (React 18 + Vite + TailwindCSS)
    |-- /src/components   (Shadcn/UI primitives)
    |-- /src/context       (Auth + Query providers)
    |-- /src/pages         (Wouter routes)
    |-- /src/lib           (API client)
          |
     REST API (/api/*)
          |
/server (Express.js + TypeScript)
    |-- /middleware        (Auth + RBAC)
    |-- /services          (OTP, OCR, Scraper)
          |
/shared (Drizzle schema + Zod + Types)
          |
     PostgreSQL (Neon)

The Hafenfest module uses a lightweight JSON storage approach (/data/hafenfest-registrations.json) for volunteer data, with unique links generated using a pattern of cleaned name plus three random digits (e.g., maxmuster123). Registration IDs are persisted in the browser’s local storage so returning users can easily update their preferences.

API Design

The REST API is divided into public and admin endpoints for the Hafenfest module:

Public Endpoints

  • GET /api/hafenfest/public/data — Available time slots and current sign-ups
  • POST /api/hafenfest/public/register — Register as a volunteer
  • PUT /api/hafenfest/public/registration/:id — Update existing registration
  • GET /api/hafenfest/public/link/:uniqueLink — Retrieve registration via personal link

Admin Endpoints (requires admin role)

  • GET /api/hafenfest/admin/registrations — All registrations with full details
  • POST /api/hafenfest/admin/add-helper — Manually assign volunteer to shift
  • DELETE /api/hafenfest/admin/remove-helper — Remove volunteer from shift
  • PUT /api/hafenfest/admin/move-helper — Transfer between shifts
  • DELETE /api/hafenfest/admin/registration/:id — Delete entire registration

Looking Ahead

WYC Wiesbaden demonstrates how a targeted full-stack application can solve real operational problems for community organizations. Rather than forcing a yacht club into generic business software, this system speaks the language of its users — shifts, beverages, members, and kiosks. The combination of modern frontend tooling (React 18, TailwindCSS, Shadcn/UI) with a pragmatic backend (Express.js, Drizzle ORM, PostgreSQL) delivers a maintainable, type-safe application that serves both day-to-day club operations and major annual events.