2026-03-27 13:45:30 -07:00
2024-09-06 12:59:40 -07:00
2024-09-06 15:40:13 -07:00
2024-09-06 12:59:40 -07:00
2024-09-06 12:59:40 -07:00
2024-09-06 12:59:40 -07:00
2024-09-12 19:06:02 -07:00

EuchreCamp

A comprehensive tournament management and partnership analytics system for the card game Euchre.

Overview

EuchreCamp is a full-stack Ruby web application built with Hanami 2.1 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

  • Ruby 3.3.3 (managed by mise or rbenv)
  • Node.js 22+ (for asset compilation)
  • SQLite3
  • Bundler

Installation

  1. Clone the repository:
git clone <repository-url>
cd euchre_camp
  1. Install dependencies:
bundle install
npm install
  1. Set up the database:
bundle exec rake db:migrate
  1. Compile assets:
./node_modules/.bin/esbuild app/assets/css/app.css --bundle --outfile=public/assets/app-GVDAEYEC.css
  1. Start the server:
bundle exec puma -p 3000 -e development

Accessing the Application

Development

Project Structure

euchre_camp/
├── app/
│   ├── actions/          # Hanami actions (controllers)
│   ├── assets/           # CSS, JavaScript, images
│   ├── repositories/     # ROM repositories for data access
│   ├── services/         # Business logic (Elo calculator, partnership tracker)
│   ├── templates/        # ERB view templates
│   ├── views/            # Hanami view objects
│   └── action.rb         # Base action class with auth helpers
├── config/
│   ├── routes.rb         # Application routes
│   ├── app.rb            # Hanami app configuration
│   └── assets.js         # Asset compilation configuration
├── db/
│   ├── migrate/          # Database migrations
│   └── euchre_camp.db    # SQLite database
├── lib/
│   └── euchre_camp/      # Domain models and entities
├── spec/
│   └── acceptance/       # RSpec acceptance tests
└── public/
    └── assets/           # Compiled assets

Running the Application

Development mode (with auto-reload):

bundle exec puma -p 3000 -e development

Production mode:

bundle exec puma -p 3000 -e production

Database Management

Run migrations:

bundle exec rake db:migrate

Rollback last migration:

bundle exec rake db:migrate[<version>]

Reset database:

bundle exec rake db:reset

Testing

Run all acceptance tests:

bundle exec rspec spec/acceptance/

Run specific test:

bundle exec rspec spec/acceptance/tournament_partnership_spec.rb:280

Run with documentation:

bundle exec rspec spec/acceptance/ --format documentation

Assets

Compile CSS for development:

./node_modules/.bin/esbuild app/assets/css/app.css --bundle --outfile=public/assets/app-GVDAEYEC.css

Watch for changes (requires separate process):

./node_modules/.bin/esbuild app/assets/css/app.css --bundle --outfile=public/assets/app-GVDAEYEC.css --watch

Features

Tournament Management

Creating a Tournament

  1. Navigate to Admin Dashboard (/admin)
  2. Click "Create Tournament"
  3. Enter tournament details:
    • Name
    • Format (round-robin, single elimination, double elimination, Swiss)
    • Number of teams/players
  4. Register participants
  5. Generate schedule
  6. 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

  1. Visit any player's profile page (/players/:id/profile)
  2. Scroll to "Partnership Performance" section
  3. 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:

ruby scripts/create_admin.rb <email> <password>

Example:

ruby scripts/create_admin.rb david@dhg.lol admin

This will:

  1. Create a player profile
  2. Create a user account with club_admin role
  3. Mark the account as confirmed

Manual SQL Alternative:

If you prefer to create users manually via SQL:

  1. Access the database: sqlite3 db/euchre_camp.db
  2. Generate a BCrypt password hash:
    ruby -e "require 'bcrypt'; puts BCrypt::Password.create('your_password')"
    
  3. Insert a user record:
    INSERT INTO players (name, rating) VALUES ('PlayerName', 1000);
    INSERT INTO users (player_id, email, password_digest, role, confirmed, created_at, updated_at)
    VALUES (1, 'user@example.com', '$2b$12$...', 'club_admin', 1, datetime('now'), datetime('now'));
    

API Reference

Routes

Public Routes

  • GET / - Redirects to rankings
  • GET /rankings - Player rankings
  • GET /players/:id - Player profile
  • GET /players/:id/profile - Player profile with partnerships
  • GET /players/:id/schedule - Player tournament schedule

Authentication Routes

  • GET /login - Login form
  • POST /auth/login - Process login
  • GET /logout - Logout and clear session

Admin Routes (Require Authentication)

  • GET /admin - Admin dashboard
  • GET /admin/players - List all players
  • GET /admin/players/new - Add new player form
  • POST /admin/players - Create new player
  • GET /admin/players/:id/edit - Edit player form
  • PATCH /admin/players/:id - Update player
  • DELETE /admin/players/:id - Delete player
  • GET /admin/matches - List all matches
  • GET /admin/matches/new - Record match form
  • POST /admin/matches - Create match
  • GET /admin/matches/:id/edit - Edit match form
  • PATCH /admin/matches/:id - Update match
  • GET /admin/matches/upload - CSV upload form
  • POST /admin/matches/process_upload - Process CSV upload
  • GET /admin/tournaments - List all tournaments
  • GET /admin/tournaments/new - Create tournament form
  • POST /admin/tournaments - Create tournament
  • GET /admin/tournaments/:id - Tournament details
  • GET /admin/tournaments/:id/edit - Edit tournament form
  • PATCH /admin/tournaments/:id - Update tournament
  • DELETE /admin/tournaments/:id - Delete tournament
  • POST /admin/tournaments/:id/participants - Add participant
  • DELETE /admin/tournaments/:id/participants/:player_id - Remove participant
  • POST /admin/tournaments/:id/teams - Create team
  • GET /admin/tournaments/:id/teams/:team_id/edit - Edit team form
  • PATCH /admin/tournaments/:id/teams/:team_id - Update team
  • DELETE /admin/tournaments/:id/teams/:team_id - Delete team
  • POST /admin/tournaments/:id/schedule - Generate schedule
  • GET /admin/tournaments/:id/rounds/:round_id - View round matchups
  • GET /admin/tournaments/:id/results - Tournament results
  • POST /admin/tournaments/:id/results - Save results
  • POST /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

  1. Navigate to Admin Dashboard
  2. Click "Add Player"
  3. Enter name and initial rating (default 1000)
  4. Click "Create Player"

Recording a Match

  1. Navigate to Admin Dashboard
  2. Click "Record Match Result"
  3. Select players for Team 1 and Team 2
  4. Enter scores
  5. Click "Create Match"

Creating a Tournament

  1. Navigate to Admin Dashboard
  2. Click "Create Tournament"
  3. Enter tournament details
  4. Register participants
  5. Generate schedule
  6. Start recording results

Editing a Match

Within 5 minutes (any user):

  1. Navigate to /admin/matches
  2. Click "Edit" next to the match
  3. Update scores
  4. 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

  1. Create a feature branch: git checkout -b feature/your-feature
  2. Make changes to code
  3. Run tests: bundle exec rspec spec/acceptance/
  4. Commit with conventional commit message
  5. Push to remote: git push origin feature/your-feature
  6. Create pull request

Commit Message Format

<type>: <description>

[optional body]

[optional footer]

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes
  • refactor: Code refactoring
  • test: Test changes
  • chore: Build/dependency changes

Code Style

  • Follow existing code patterns in the project
  • Use ROM (Ruby Object Mapper) for database access
  • Keep business logic in services
  • Use dependency injection in actions
  • Write acceptance tests for new features

Deployment

Production Environment

  1. Set production environment variables:
export HANAMI_ENV=production
export DATABASE_URL=sqlite:///path/to/prod.db
export SESSION_SECRET=<secure-random-string>
  1. Compile assets for production:
./node_modules/.bin/esbuild app/assets/css/app.css --bundle --outfile=public/assets/app-GVDAEYEC.css
  1. Run migrations:
bundle exec rake db:migrate
  1. Start server:
bundle exec puma -p 3000 -e production

Using a Process Manager

Using systemd:

[Unit]
Description=EuchreCamp
After=network.target

[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/euchre_camp
Environment=HANAMI_ENV=production
ExecStart=/usr/local/bin/bundle exec puma -C config/puma.rb
Restart=always

[Install]
WantedBy=multi-user.target

Using PM2 (Node.js):

pm2 start bundle exec -- puma -C config/puma.rb

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests to ensure they pass
  5. Submit a pull request

License

MIT License - see LICENSE file for details

Credits

Built with:

  • Hanami 2.1
  • ROM (Ruby Object Mapper)
  • SQLite3
  • RSpec
  • Puma

Additional Resources

S
Description
No description provided
Readme 5.6 MiB
2026-03-31 23:35:21 +00:00
Languages
TypeScript 88.4%
JavaScript 8.2%
Gherkin 1.6%
Just 0.9%
Shell 0.5%
Other 0.3%