A medical diagnosis guessing game where players identify radiological conditions from X-ray images. Built with Next.js and Supabase.
RadWordle is an educational game that challenges medical professionals and students to identify diagnoses from radiological images. Each day features a new puzzle with progressive hints to help narrow down the answer.
- Framework: Next.js 16 (App Router)
- Database: Supabase
- Styling: Tailwind CSS
- Language: TypeScript
- Node.js 18+: Download and install from nodejs.org
- pnpm (recommended): Install globally with
npm install -g pnpm- Alternatively, you can use npm (comes with Node.js)
To verify your installations:
node --version # Should show v18 or higher
pnpm --version # If using pnpm- Clone the repository:
git clone <repository-url>
cd radwordle- Install dependencies:
pnpm install
# or
npm install- Set up environment variables:
Create a .env.local file in the root directory. Contact the repository owner (Tanmay) for the required credentials:
NEXT_PUBLIC_SUPABASE_URL=<ask-owner>
NEXT_PUBLIC_SUPABASE_ANON_KEY=<ask-owner>
NEXT_PUBLIC_GAME_EPOCH=2025-01-01- Run the development server:
pnpm dev
# or
npm run dev- Open http://localhost:3000 (or the port shown in terminal) to see the application.
radwordle/
├── app/ # Next.js app directory
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home/test page
│ └── globals.css # Global styles
├── lib/ # Utility functions and configs
│ ├── supabase.ts # Supabase client and database functions
│ ├── gameLogic.ts # Game logic utilities
│ ├── localStorage.ts # Local storage helpers
│ └── constants.ts # App constants
├── components/ # React components
└── types/ # TypeScript type definitions
The application uses three main tables in Supabase:
id: UUID (Primary Key)name: Text - Diagnosis namecategory: Text - Medical categoryaliases: Text[] - Alternative names
id: UUID (Primary Key)puzzle_number: Integer - Sequential puzzle numberimage_url: Text - URL to X-ray imageanswer: Text - Correct diagnosisdifficulty: Text - easy, medium, hardis_active: Boolean - Whether puzzle is active
id: UUID (Primary Key)puzzle_id: UUID (Foreign Key to puzzles)hint_order: Integer - Order of hint revealcontent_type: Text - text or imagehint_text: Text - Hint content (nullable)image_url: Text - Hint image URL (nullable)image_caption: Text - Image caption (nullable)
- Daily Puzzles: The game cycles through puzzles based on days since the game epoch (January 1, 2025)
- Max Guesses: Players get 6 attempts per puzzle
- Progressive Hints: Hints are revealed in order to help players
- lib/supabase.ts - Database queries and type definitions
- lib/gameLogic.ts - Core game mechanics
- app/page.tsx - Main test page showing database connection
The homepage serves as a test page that displays:
- Connection status
- Database statistics
- Today's puzzle details
- All hints for the current puzzle
- Available conditions
If you see the green "Supabase Connected" message, everything is working correctly.
pnpm test # Run all 154 tests
pnpm test:watch # Run in watch mode (re-runs on file changes)
pnpm test:coverage # Run with coverage reportE2E tests run against the real app in a Chromium browser. The dev server starts automatically.
pnpm e2e # Run all 55 E2E tests (headless)
pnpm e2e:headed # Run with browser visible (watch tests execute)
pnpm e2e:ui # Open Playwright's interactive test picker UIRun a single test by name:
pnpm e2e --headed --grep "should complete first-time user journey"Run a specific test file:
pnpm e2e e2e/tests/mobile-responsive.spec.tsFun tests to watch in headed mode:
| Command | What it does |
|---|---|
--grep "should complete first-time user journey" |
Accepts cookies, makes a wrong guess, then wins |
--grep "should show game over after 5 incorrect" |
Makes 5 wrong guesses with hints revealing each time |
--grep "should complete a full game on mobile" |
Plays a full game on a 390x844 iPhone viewport |
--grep "should simulate multi-day play" |
Wins today's game, then plays an archive game |
--grep "should show WON badge" |
Wins an archive game, goes back to verify WON badge |
E2E test coverage (10 spec files):
- First-time user journey (cookie consent, win flow, persistence, stats)
- Losing game flow (5 wrong guesses, hints, game over)
- Archive mode (browsing, separate stats, WON badge)
- Autocomplete & validation (dropdown, keyboard nav, error messages)
- Toast notifications (correct/incorrect/partial feedback)
- Mobile responsiveness (iPhone 12 viewport)
- Stats recovery (localStorage cleared, cookie/IndexedDB backup)
- Network failure handling (Supabase down, graceful degradation)
- Multi-day progression (per-day state, streaks, guess distribution)
- Guess time tracking (timing in localStorage)
pnpm build
pnpm startContact the repository owner for contribution guidelines and access to environment variables.
Private repository - All rights reserved.
- some stats are still wrong
- feedback form
- currently able to submit free text answers, make them from bank only for simplicity