The Daily Peaky Blinders Companion -- a daily quote, a daily challenge, and an empire to build.
Shelby Empire is a fan companion app for Peaky Blinders. Every day you get a fresh quote with a mindset lesson, play a trivia challenge, track your streak, grow your empire from The Streets to The Crown, and compete on leaderboards. Think Wordle meets Peaky Blinders.
- Daily Quote -- a new quote each morning with character attribution, episode context, and a "Shelby Lesson" mindset takeaway
- Daily Challenge -- "Who Said It?" (guess who said the quote) and "Blinder or Bluff?" (true/false about the real Peaky Blinders)
- Shareable Results -- Wordle-style colored grids you can copy or share to X/Twitter
- Streak System -- daily activity tracking with streak preservation at midnight UTC
- Empire Progression -- 8 levels from The Streets to The Crown based on your streak
- Badge System -- 10 achievement badges for milestones (first game, perfect score, streak goals)
- Quote Vault -- full-text search across 30+ quotes, filterable by character, season, mood, and tags
- Leaderboard -- current streak, longest streak, and total active days rankings
- OG Images -- dynamic Open Graph images for social media link previews
- Docker-ready -- full local Supabase stack in Docker, zero external dependencies
docker compose up --buildOpen http://localhost:3000. Sign up, play the daily challenge, build your empire.
This starts the full stack:
| Service | URL | Description |
|---|---|---|
| App | http://localhost:3000 | Next.js application |
| Supabase API | http://localhost:8000 | Kong gateway (auth + REST) |
| Supabase Auth | http://localhost:9999 | GoTrue authentication |
| PostgREST | http://localhost:3001 | Direct database API |
| PostgreSQL | localhost:5432 | Database (schema + seed pre-loaded) |
Requires Node.js 20+ and pnpm 8+.
# Clone the repository
git clone https://github.com/JamilAfouri99/shelby-empire.git && cd shelby-empire
# Install dependencies
pnpm install
# Create environment file
cp .env.local.example .env.local
# Fill in your Supabase credentials (see SETUP.md for details)
# Start the dev server
pnpm devFor the full setup guide including Supabase project creation, database migration, and seeding, see SETUP.md.
- Landing page -- visit
http://localhost:3000to see the marketing page - Sign up -- create an account with email, password, and username
- Daily content -- view today's quote and mindset lesson at
/today - Play the game -- complete the daily challenge (Who Said It? or Blinder or Bluff?)
- Track progress -- check your streak and empire level at
/empire - Browse quotes -- search and filter the full vault at
/vault - Compete -- see where you rank on the leaderboard at
/leaderboard - Share results -- copy your Wordle-style result grid or share to X/Twitter
Next.js 15, React 19, TypeScript, Tailwind CSS v4, Supabase (PostgreSQL + Auth + RLS), Upstash Redis, Docker
- Server Components by default --
"use client"only when state/effects are needed - Server Actions for mutations -- no API routes for data changes
- Strategy pattern for game types -- each game type implements
GameStrategy - Result<T, E> type for error handling -- no throwing in business logic
- Zod validation on every server action input
- Row Level Security on all database tables
src/
├── app/ # Next.js App Router (pages, layouts, API routes)
│ ├── (marketing)/ # Landing page
│ ├── (auth)/ # Login, signup
│ ├── (app)/ # Today, vault, empire, leaderboard, profile
│ └── api/og/ # OG image generation
├── actions/ # Server Actions (auth, game, streak, vault, leaderboard)
├── components/ # React components organized by feature
├── hooks/ # Client-side hooks (countdown, game, share, streak)
├── lib/ # Utilities, constants, validators, Supabase/Redis clients
└── types/ # TypeScript type definitions
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Yes | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Yes | Supabase anonymous API key |
SUPABASE_SERVICE_ROLE_KEY |
Yes | Supabase service role key |
UPSTASH_REDIS_REST_URL |
No | Upstash Redis URL (leaderboard falls back to Supabase) |
UPSTASH_REDIS_REST_TOKEN |
No | Upstash Redis token |
NEXT_PUBLIC_SITE_URL |
No | Site URL (defaults to http://localhost:3000) |
Add quotes and daily content via SQL. See SETUP.md for examples.
Game data formats:
Who Said It?:
{"quote": "...", "correct_answer": "Tommy Shelby", "options": ["Tommy Shelby", "Arthur Shelby", ...]}Blinder or Bluff?:
{"statement": "...", "correct_answer": true, "explanation": "..."}- Add the type to
GameTypeKeyinsrc/types/database.ts - Create a strategy class implementing
GameStrategyinsrc/lib/utils/game.ts - Register in
createGameStrategy()factory - Create a UI component in
src/components/daily-game/ - Add the component to
GameContainer - Add the label to
GAME_TYPE_LABELSinsrc/lib/constants/game-config.ts
See CONTRIBUTING.md.
See SECURITY.md for our security policy and how to report vulnerabilities.