2026-04-01 00:21:25 -07:00
2026-03-30 02:30:13 +00:00
2026-04-26 16:44:47 -07:00
2026-04-26 04:27:54 +00:00
2026-03-30 02:30:13 +00:00
2026-04-01 06:14:25 +00:00
2026-04-01 00:13:15 -07:00
2026-03-30 02:30:13 +00:00
2026-04-26 04:27:54 +00:00
2026-03-30 02:30:13 +00:00
2026-04-01 06:14:25 +00:00
2026-03-30 02:30:13 +00:00

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
  • Home Page: Public-facing landing page showing top players, recent tournaments, and club information

Tech Stack

  • Framework: Next.js 14+ (App Router)
  • Language: TypeScript
  • Database: Prisma ORM with SQLite (default) or PostgreSQL
  • Styling: Tailwind CSS
  • Authentication: Better Auth
  • Form Handling: React Hook Form + Zod validation
  • CSV Parsing: PapaParse
  • Unit Testing: Vitest
  • Acceptance Testing: Playwright
  • CI/CD: Gitea Actions with SQLite for CI tests

Project Structure

euchre_camp/
├── .gitea/workflows/     # CI/CD workflows (Gitea Actions)
├── docs/                 # Documentation
│   ├── deployment/       # Deployment guides
│   └── planning/         # Planning documents
├── prisma/               # Prisma schema and migrations
├── public/               # Static assets
├── scripts/              # Utility scripts
│   └── python/           # Python scripts (legacy)
├── src/                  # Source code
│   ├── app/              # Next.js app directory
│   │   ├── api/          # API routes
│   │   ├── auth/         # Authentication pages
│   │   ├── admin/        # Admin pages
│   │   ├── players/      # Player pages
│   │   ├── rankings/     # Rankings page
│   │   └── components/   # Shared components
│   ├── lib/              # Utilities and configuration
│   │   ├── auth.ts       # Better Auth configuration
│   │   ├── prisma.ts     # Prisma client (SQLite/PostgreSQL)
│   │   ├── permissions.ts # Authorization functions
│   │   └── elo-utils.ts  # Elo calculation utilities
│   └── __tests__/        # Vitest and Playwright tests
└── ...                   # Configuration files in root

See docs/FILE_ORGANIZATION.md for detailed file organization.

Features Implemented

Epic 1: Authentication & User Management

  • User registration with email confirmation
  • Login with credentials
  • Password reset flow
  • Session management with Better Auth
  • Role-based access control (player, tournament_admin, club_admin)

Epic 2: Player Profile & Analytics

  • Player profile page with statistics
  • Partnership performance table
  • Win rate and Elo display
  • Direct player stats (gamesPlayed, wins, losses)

Epic 3: Rankings & Public Data

  • Player rankings page
  • Sortable rankings table
  • Public player profiles
  • Home page with top 10 players, recent tournament, club president

Epic 4: Tournament Management

  • Create tournaments
  • Manage participants
  • Create teams
  • View tournament details

Epic 5: Match Recording & CSV Import

  • Record match results via API
  • CSV upload for batch processing
  • Automatic Elo calculation
  • Partnership tracking

Getting Started

Prerequisites

  • Node.js 20+
  • npm or yarn
  • SQLite3 (default) or PostgreSQL (optional)

For SQLite (default):

  • No additional setup required

For PostgreSQL:

  • PostgreSQL 12+ installed and running
  • Create a database for EuchreCamp

Installation

  1. Clone the repository

    git clone <repository-url>
    cd euchre_camp
    
  2. Install dependencies

    npm install
    
  3. Set up environment variables

    cp .env.example .env
    # Edit .env to configure your database
    
  4. Set up the database

    For SQLite (default):

    npx prisma migrate deploy
    npx prisma generate
    

    For PostgreSQL:

    # Set up PostgreSQL database
    npm run db:setup-postgres
    
    # Or manually:
    npx prisma migrate deploy
    npx prisma generate
    
  5. Start the development server

    npm run dev
    

Environment Variables

Create a .env file:

# Database Configuration
DATABASE_PROVIDER=sqlite  # or "postgresql"
DATABASE_URL="file:./dev.db"

# Better Auth
BETTER_AUTH_SECRET="your-secret-key-here"
BETTER_AUTH_URL="http://localhost:3000"

Using PostgreSQL:

DATABASE_PROVIDER=postgresql
DATABASE_URL="postgresql://username:password@localhost:5432/euchre_camp"
DATABASE_SHADOW_URL="postgresql://username:password@localhost:5432/euchre_camp_shadow"

Development Database

For development and testing, use a separate development database to avoid conflicts with production data.

Setup Development Database:

# Create and setup the development database
npm run db:setup-dev

# Reset the development database (drops and recreates)
npm run db:reset-dev

# Clean development database (drop and recreate with migrations)
npm run db:setup-dev:clean

Environment Configuration:

The development database uses .env.development which is automatically configured for:

  • Database: euchre_camp_dev
  • NODE_ENV: development

Testing with Development Database:

# Run unit tests (uses test database automatically)
npm run test

# Run acceptance tests (uses development database)
npm run test:acceptance

Test Data Cleanup:

All tests automatically clean up their created records:

  • Global setup/teardown handles Playwright tests
  • Test utilities provide cleanupTestRecords() for manual cleanup
  • Tests use beforeEach and afterEach hooks for automatic cleanup

Usage

Creating a Tournament

  1. Navigate to /admin/tournaments
  2. Click "Create Tournament"
  3. Fill in tournament details

Uploading Match Results via CSV

  1. Navigate to /admin/matches/upload
  2. Select a tournament
  3. Upload CSV file with Euchre format

Viewing Player Profiles

Navigate to /players/[id]/profile to see statistics, partnerships, and recent games.

Home Page

Visit / to see:

  • Top 10 players by Elo rating
  • Most recent tournament with full match list
  • Club president information

API Endpoints

Tournaments

  • GET /api/tournaments - List all tournaments
  • POST /api/tournaments - Create new tournament

Matches

  • GET /api/matches - List matches
  • POST /api/matches/upload - Upload CSV with match results

Authentication

  • POST /api/auth/sign-up/email - Register new account
  • POST /api/auth/sign-in/email - Login with email/password
  • POST /api/auth/sign-out - Logout

Users

  • GET /api/users/[id]/role - Get user role

Development

The project includes a justfile with common development tasks:

# Show all available tasks
just help

# Development mode
just dev

# Run all tests (unit + acceptance with SQLite)
just test

# Run PR validation (what runs on pull requests)
just pr-validate

# Run CI pipeline locally
just ci

# Switch database provider
just db-switch-sqlite
just db-switch-postgres

# Docker shortcuts
just docker-up
just docker-down
just docker-logs

Using npm scripts directly

# Development mode
npm run dev

# Production build
npm run build
npm start

# Run unit tests
npm run test

# Run acceptance tests
npm run test:acceptance

# Run acceptance tests with SQLite (CI-style)
DATABASE_PROVIDER=sqlite DATABASE_URL=file:./prisma/ci.db npm run test:acceptance

Database Commands

# Switch between SQLite and PostgreSQL
npm run db:switch sqlite
npm run db:switch postgresql

# Set up PostgreSQL database
npm run db:setup-postgres

# Seed database with sample data
npm run db:seed

Admin User Creation

To create an admin user, use the provided scripts:

Option 1: Using Better Auth API (Recommended)

node scripts/create-admin-via-api.js

This creates the admin user david@dhg.lol with password adminadmin using Better Auth's internal API.

Option 2: Direct Database Creation

node scripts/create-admin-better-auth.js

This creates the admin user david@dhg.lol with password admin directly in the database.

List All Users:

node scripts/list-users.js

Update Admin Password:

node scripts/update-admin-password.js

This updates the admin password to adminadmin.

Note: All scripts currently create the user david@dhg.lol. If you need to create a different admin user, you can modify the email in the script or use Better Auth's CLI.

User Stories

User stories are organized into epics in docs/USER_STORIES.md:

  1. Authentication & User Management
  2. Player Profile & Analytics
  3. Rankings & Public Data
  4. Tournament Management
  5. Match Recording & CSV Import
  6. Club Administration
  7. Mobile Responsiveness
  8. Data Management & Export

CI/CD Pipeline

The application uses Gitea Actions for continuous integration and deployment:

Workflow Architecture

  1. PR Workflow (.gitea/workflows/pr.yml): Runs on pull requests

    • Unit tests (fast feedback)
    • Acceptance tests with SQLite database
    • Semantic version bump analysis
  2. Test Workflow (.gitea/workflows/test.yml): Runs on all branch pushes

    • Unit tests for quick feedback
    • Skips auto-generated version bumps
  3. Release Workflow (.gitea/workflows/release.yml): Runs on main branch pushes

    • Version bumping and tagging
    • Docker image building and testing
    • Registry push and deployment

CI Runner Image

Note: The CI runner image approach has been deprecated for Gitea Actions workflows.

The original attempt to use a pre-built CI runner image with pre-installed dependencies encountered fundamental issues with how Gitea Actions handles workspace mounting. When Gitea Actions runs a container job, it mounts the workspace at a specific path (e.g., /workspace/david/euchre_camp), which hides the container's /app directory where dependencies were installed.

Current Approach:

  • Workflows use standard node:20-alpine or mcr.microsoft.com/playwright containers
  • Dependencies are installed via npm ci in each workflow run
  • This is the recommended approach for Gitea Actions

Why the CI image approach doesn't work:

  1. Dockerfile.ci installs dependencies in /app
  2. Gitea Actions mounts workspace at /workspace/david/euchre_camp
  3. Workspace mount hides the /app directory
  4. Symlinks from /app/node_modules don't work because /app is hidden

Database Strategy for CI

  • CI Tests: SQLite database (fast, no server required)
  • Production: PostgreSQL (production-like environment)
  • Configuration: DATABASE_PROVIDER environment variable

Running CI Locally

# Run unit tests (same as CI)
npm run test:run

# Run acceptance tests with SQLite
DATABASE_PROVIDER=sqlite DATABASE_URL=file:./prisma/ci.db npm run test:acceptance

Docker Deployment

This application can be run using Docker and Docker Compose. See DOCKER.md for detailed instructions.

Quick Start:

# Start all services (PostgreSQL + Next.js app)
docker-compose up -d

# Access the application
# http://localhost:3000

Development Mode:

# Start with hot reload
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d

License

MIT License

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%