HopRank is a real-time collaborative beer rating platform that brings together beer enthusiasts to rank and review beers in organized tasting sessions. Think of it as a digital beer competition platform with integrated Untappd support.
HopRank allows groups of people to create structured beer tasting sessions where participants collaboratively rate beers across multiple criteria. The platform automatically calculates rankings, creates leaderboards, and can even integrate with Untappd for seamless check-ins.
πΊ Collaborative Beer Sessions
- Create or join beer tasting sessions with friends
- Real-time synchronization across all participants
- Structured voting with customizable rating criteria
π Smart Ranking System
- Multi-criteria scoring with weighted averages
- Automatic leaderboard generation with podium visualization
- Detailed breakdown of ratings by criteria
π Untappd Integration
- OAuth authentication with Untappd
- Automatic beer search and data fetching
- Direct check-in to Untappd with your ratings
- Venue detection and integration
β‘ Real-time Experience
- WebSocket-powered live updates
- Session progress tracking
- Live voting status for all participants
π± Mobile-First Design
- Responsive design built with Mantine UI
- Touch-friendly rating sliders
- Mobile app integration (Untappd deep links)
- Create a new tasting session with a unique join code
- Define rating criteria (e.g., Appearance, Aroma, Taste, etc.)
- Search Untappd's database to find beers
- Add beers to the session queue
- Beers are automatically shuffled for random ordering
- The session progresses through each beer one by one
- All participants rate the current beer on each criterion
- Ratings are submitted simultaneously for fairness
- Integration with Untappd for automatic check-ins
- Real-time calculation of weighted averages
- Podium-style visualization of top 3 beers
- Detailed results table with all ratings
- Individual criteria breakdowns
- Created: Session setup, adding beers
- Active: Currently rating beers
- Finished: All beers rated, final results available
Install dependencies:
pnpm installCreate a .env file with the required environment variables. Below is a consolidated list grouped by purpose.
| Variable | Purpose |
|---|---|
APP_URL |
Base URL of the app (used to build OAuth callback URLs) |
SESSION_SECRET |
Secret for signing session cookies |
UNTAPPD_CLIENT_ID |
Untappd OAuth client ID |
UNTAPPD_CLIENT_SECRET |
Untappd OAuth client secret |
| DATABASE_PATH | Path to the SQLite database file (e.g. ./data/database.db) |
| VITE_ALGOLIA_APP_ID | Algolia application ID for beer search |
| VITE_ALGOLIA_API_K | Algolia search-only API key |
| VITE_WS_URL | WebSocket endpoint used by the client (e.g. ws://localhost:5173) |
| Variable | Purpose |
|---|---|
DATABASE_FILE_NAME |
Name of the database file (default: data.db) |
SMTP_FROM |
From address for outbound emails |
SMTP_HOST |
SMTP server host for email login links |
SMTP_PORT |
SMTP server port |
SMTP_USER |
SMTP auth username |
SMTP_PASS |
SMTP auth password |
TOTP_SECRET |
Base secret for generating TOTP (2FA) codes |
MAX_SESSION_AGE_HOURS |
Auto-close sessions older than this (default: 24) |
MAX_SESSION_IDLE_TIME_HOURS |
Timeout for "idle" session (default: 6) |
VITE_UMAMI_SRC_URL |
Umami analytics script URL (production only) |
VITE_UMAMI_WEBSITE_ID |
Umami website/site ID |
VITE_LATEST_COMMIT_HASH |
Injected at build time for UI display of current commit |
VITE_LATEST_COMMIT_MESSAGE |
Injected commit message for display |
# Base App
APP_URL=http://localhost:5173
SESSION_SECRET=dev_super_secret
# Database
DATABASE_PATH=./data/database.db
# Untappd OAuth
UNTAPPD_CLIENT_ID=your_untappd_client_id
UNTAPPD_CLIENT_SECRET=your_untappd_client_secret
# Algolia (Beer Search)
VITE_ALGOLIA_APP_ID=your_algolia_app_id
VITE_ALGOLIA_API_K=your_algolia_api_key
# WebSockets
VITE_WS_URL=ws://localhost:5173
# Optional Email (disable if not set)
SMTP_FROM=HopRank <no-reply@localhost>
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_USER=
SMTP_PASS=
# Optional 2FA
TOTP_SECRET=replace_me_for_prod
# Optional Analytics / Build Metadata
VITE_UMAMI_SRC_URL=
VITE_UMAMI_WEBSITE_ID=
VITE_LATEST_COMMIT_HASH=
VITE_LATEST_COMMIT_MESSAGE=
# Housekeeping
MAX_SESSION_AGE_HOURS=12Generate and run database migrations:
pnpm generate # Generate migration files
pnpm migrate # Apply migrationsStart the development server:
pnpm devYour application will be available at http://localhost:5173.
pnpm studio # Open Drizzle Studio for database management
pnpm typecheck # Run TypeScript type checking
pnpm lint # Run Biome linterapp/
βββ auth/ # Authentication strategies and user management
βββ components/ # React components
β βββ modals/ # Modal dialogs
β βββ auth/ # Authentication-related components
β βββ ... # Core app components
βββ database/ # Database schema, config, and utilities
β βββ utils/ # Database helper functions
βββ routes/ # React Router routes
β βββ api/ # API endpoints
β βββ auth/ # Authentication routes
β βββ sessions/ # Session-related routes
βββ types/ # TypeScript type definitions
βββ utils/ # Utility functions
βββ hooks/ # Custom React hooks
drizzle/ β# Database migration files
public/ # Favicons, robots.txt, etc.
- Sessions: Main tasting sessions with join codes
- SessionUsers: Participants in each session
- SessionBeers: Beers added to sessions with ordering
- SessionState: Current state and progress tracking
- Criteria: Configurable rating categories
- Ratings: Individual user ratings for each beer/criterion
- Weighted Scoring: Automatic calculation with criterion weights
- OAuth Flow: Secure authentication with Untappd
- Beer Search: Real-time search using Algolia
- Check-ins: Automatic posting to Untappd with ratings
- Venue Detection: GPS-based venue selection
Build and run with Docker:
docker build -t hoprank .
docker run -p 3000:3000 hoprankThe application supports the following production environment variables:
VITE_WS_URL=wss://your-domain.com
VITE_ALGOLIA_APP_ID=production_algolia_app_id
VITE_ALGOLIA_API_K=production_algolia_api_key
VITE_UMAMI_SRC_URL=analytics_url
VITE_UMAMI_WEBSITE_ID=analytics_id