- Install Bun via mise - Update package.json scripts to use Bun - Migrate unit tests from Vitest to Bun test runner - Migrate component tests from Vitest to Bun test runner - Configure Bun with DOM environment for React Testing Library - Keep Playwright for E2E tests (as planned) - 93/100 tests passing (7 flaky tests when running all together, pass individually)
EuchreCamp
A comprehensive tournament management and partnership analytics system for the card game Euchre.
Overview
EuchreCamp is a full-stack web application built with Next.js 14+ and TypeScript that provides:
- Tournament Management: Create and manage round-robin, single elimination, double elimination, and Swiss-style tournaments
- Partnership Analytics: Track partnership performance, win rates, and Elo changes between players
- Player Profiles: Display individual player statistics and partnership breakdowns
- Admin Dashboard: Centralized management interface for tournaments, players, and matches
- Authentication & Authorization: Role-based access control with player, tournament_admin, and club_admin roles
Quick Start
Prerequisites
- Node.js 20+ (managed by mise or nvm)
- SQLite3
Installation
- Clone the repository:
git clone <repository-url>
cd euchre_camp
- Install dependencies:
npm install
- Set up the database:
npx prisma migrate deploy
npx prisma generate
- Start the development server:
npm run dev
Accessing the Application
- Main Page: http://localhost:3000
- Admin Dashboard: http://localhost:3000/admin
- Rankings: http://localhost:3000/rankings
- Login: http://localhost:3000/auth/login
- Registration: http://localhost:3000/auth/register
Development
Project Structure
euchre_camp/
├── src/
│ ├── app/ # Next.js App Router pages and routes
│ │ ├── auth/ # Authentication pages (login, register)
│ │ ├── admin/ # Admin dashboard and management
│ │ ├── players/ # Player profiles and schedules
│ │ ├── rankings/ # Player rankings page
│ │ └── api/ # API routes
│ ├── components/ # React components
│ ├── lib/ # Utilities and configurations
│ │ ├── auth.ts # Better Auth configuration
│ │ ├── prisma.ts # Prisma client
│ │ └── auth-client.ts
│ └── __tests__/ # Vitest and Playwright tests
├── prisma/
│ └── schema.prisma # Database schema
├── public/ # Static assets
└── package.json # Dependencies and scripts
Running the Application
Development mode (with auto-reload):
npm run dev
Production mode:
npm run build
npm start
Database Management
Run migrations:
npx prisma migrate deploy
Generate Prisma client:
npx prisma generate
Reset database:
npx prisma migrate reset
Open Prisma Studio:
npx prisma studio
Testing
Run unit tests:
npm run test
Run unit tests in watch mode:
npm run test:run
Run acceptance tests:
npm run test:acceptance
Run acceptance tests in headed mode:
npm run test:acceptance:headed
Test with Playwright MCP (browser automation):
- Start the development server:
npm run dev - Use opencode with Playwright MCP tools to:
- Navigate to pages
- Take screenshots
- Test responsive layouts
- Verify mobile UI elements
Assets
CSS is handled by Tailwind CSS with automatic compilation during development.
Features
Tournament Management
Creating a Tournament
- Navigate to Admin Dashboard (
/admin) - Click "Create Tournament"
- Enter tournament details:
- Name
- Format (round-robin, single elimination, double elimination, Swiss)
- Number of teams/players
- Register participants
- Generate schedule
- Record match results
Tournament Formats
- Round-Robin: Each team plays every other team once
- Single Elimination: Lose once and you're out
- Double Elimination: Must lose twice to be eliminated
- Swiss: Pairings based on win-loss records
Partnership Analytics
Tracking Partnerships
The system automatically tracks:
- Games played together
- Win/loss records
- Elo changes per partnership
- Partnership win rates
Viewing Partnership Data
- Visit any player's profile page (
/players/:id/profile) - Scroll to "Partnership Performance" section
- View statistics for each partner
Player Profiles
Each player profile displays:
- Current Elo rating
- Total games played
- Win rate
- Partnership statistics
- Recent games timeline
Admin Dashboard
The admin dashboard provides:
- Quick statistics (total players, active tournaments, recent matches)
- Quick action buttons for common tasks
- Recent matches table
- Links to all admin sections
Authentication & Authorization
User Roles
| Role | Permissions |
|---|---|
| Player | Edit own profile, record own matches within 5 minutes |
| Tournament Admin | Create/manage tournaments, edit matches in their tournaments (no time limit) |
| Club Admin | Full access to edit/delete any record, manage all players and tournaments |
Login/Logout
Login:
- Navigate to
/login - Enter email and password
- Click "Login"
Logout:
- Click "Logout" in navigation bar
Admin User Creation
To create an admin user, use the provided script:
node scripts/create-admin.js <email> <password>
Example:
node scripts/create-admin.js admin@example.com mypassword
This will:
- Create a player profile
- Create a user account with
club_adminrole - Mark the account as confirmed
Using Better Auth CLI:
npx better-auth cli
API Reference
Routes
Public Routes
GET /- Redirects to rankingsGET /rankings- Player rankingsGET /players/:id- Player profileGET /players/:id/profile- Player profile with partnershipsGET /players/:id/schedule- Player tournament schedule
Authentication Routes
GET /login- Login formPOST /auth/login- Process loginGET /logout- Logout and clear session
Admin Routes (Require Authentication)
GET /admin- Admin dashboardGET /admin/players- List all playersGET /admin/players/new- Add new player formPOST /admin/players- Create new playerGET /admin/players/:id/edit- Edit player formPATCH /admin/players/:id- Update playerDELETE /admin/players/:id- Delete playerGET /admin/matches- List all matchesGET /admin/matches/new- Record match formPOST /admin/matches- Create matchGET /admin/matches/:id/edit- Edit match formPATCH /admin/matches/:id- Update matchGET /admin/matches/upload- CSV upload formPOST /admin/matches/process_upload- Process CSV uploadGET /admin/tournaments- List all tournamentsGET /admin/tournaments/new- Create tournament formPOST /admin/tournaments- Create tournamentGET /admin/tournaments/:id- Tournament detailsGET /admin/tournaments/:id/edit- Edit tournament formPATCH /admin/tournaments/:id- Update tournamentDELETE /admin/tournaments/:id- Delete tournamentPOST /admin/tournaments/:id/participants- Add participantDELETE /admin/tournaments/:id/participants/:player_id- Remove participantPOST /admin/tournaments/:id/teams- Create teamGET /admin/tournaments/:id/teams/:team_id/edit- Edit team formPATCH /admin/tournaments/:id/teams/:team_id- Update teamDELETE /admin/tournaments/:id/teams/:team_id- Delete teamPOST /admin/tournaments/:id/schedule- Generate scheduleGET /admin/tournaments/:id/rounds/:round_id- View round matchupsGET /admin/tournaments/:id/results- Tournament resultsPOST /admin/tournaments/:id/results- Save resultsPOST /admin/tournaments/:id/complete- Complete tournament
Database Schema
Tables
- players: Player information and ratings
- users: Authentication and authorization
- events: Tournaments and events
- event_participants: Player participation in tournaments
- teams: Teams in tournaments
- tournament_rounds: Tournament rounds
- bracket_matchups: Matchups per round
- matches: Individual match results
- elo_snapshots: Elo rating history
- partnership_games: Partnership occurrence tracking
- partnership_stats: Aggregated partnership statistics
Common Tasks
Adding a New Player
- Navigate to Admin Dashboard
- Click "Add Player"
- Enter name and initial rating (default 1000)
- Click "Create Player"
Recording a Match
- Navigate to Admin Dashboard
- Click "Record Match Result"
- Select players for Team 1 and Team 2
- Enter scores
- Click "Create Match"
Creating a Tournament
- Navigate to Admin Dashboard
- Click "Create Tournament"
- Enter tournament details
- Register participants
- Generate schedule
- Start recording results
Editing a Match
Within 5 minutes (any user):
- Navigate to
/admin/matches - Click "Edit" next to the match
- Update scores
- Click "Update Match"
Anytime (tournament admin or club admin):
- Same process as above, no time restriction
Troubleshooting
Common Issues
Server won't start:
- Check if port 3000 is already in use:
lsof -i :3000 - Kill existing process:
kill -9 <PID> - Try a different port:
bundle exec puma -p 3001
CSS not loading:
- Recompile assets:
./node_modules/.bin/esbuild app/assets/css/app.css --bundle --outfile=public/assets/app-GVDAEYEC.css - Clear browser cache
Database errors:
- Run migrations:
bundle exec rake db:migrate - Reset database:
bundle exec rake db:reset
Authorization errors:
- Ensure you're logged in
- Check user role in database
Debugging
Check server logs:
tail -f /tmp/puma.log
Check database:
sqlite3 db/euchre_camp.db
sqlite> .tables
sqlite> SELECT * FROM users;
Development Workflow
Making Changes
- Create a feature branch:
git checkout -b feature/your-feature - Make changes to code
- Run tests:
npm run test(unit tests) ornpm run test:acceptance(acceptance tests) - Commit with conventional commit message
- Push to remote:
git push origin feature/your-feature - Create pull request
Commit Message Format
<type>: <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changesrefactor: Code refactoringtest: Test changeschore: Build/dependency changes
Code Style
- Follow existing code patterns in the project
- Use Prisma ORM for database access
- Keep business logic in lib/ directory
- Use React Server Components where appropriate
- Write unit tests (Vitest) and acceptance tests (Playwright) for new features
Deployment
Production Environment
- Set production environment variables:
export NODE_ENV=production
export DATABASE_URL=file:./dev.db
export BETTER_AUTH_SECRET=<secure-random-string>
export BETTER_AUTH_URL=http://localhost:3000
- Build the application:
npm run build
- Run migrations:
npx prisma migrate deploy
- Start server:
npm start
Using a Process Manager
Using systemd:
[Unit]
Description=EuchreCamp
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/euchre_camp
Environment=NODE_ENV=production
ExecStart=/usr/local/bin/npm start
Restart=always
[Install]
WantedBy=multi-user.target
Using PM2 (Node.js):
pm2 start npm --name "euchre-camp" -- start
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests to ensure they pass
- Submit a pull request
License
MIT License - see LICENSE file for details
Credits
Built with:
- Next.js 14+ (App Router)
- TypeScript
- Tailwind CSS
- Prisma ORM
- Better Auth
- Vitest
- Playwright