d24e810ad1
The CI image approach with pre-installed dependencies doesn't work with Gitea Actions due to workspace mounting issues. 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. Changes: - Reverted pr.yml unit-tests to use node:20-alpine with npm ci - Updated pr.yml acceptance-tests to use mcr.microsoft.com/playwright image with npm ci - Updated test.yml to use node:20-alpine with npm ci - Removed ci-image-builder.yml workflow - Removed Dockerfile.ci and build-ci-image.sh - Updated AGENTS.md and README.md to document the deprecation - Updated justfile to remove CI image commands The standard approach of running npm ci in each workflow is the recommended approach for Gitea Actions.
429 lines
12 KiB
Markdown
429 lines
12 KiB
Markdown
# 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](docs/FILE_ORGANIZATION.md) for detailed file organization.
|
|
|
|
## Features Implemented
|
|
|
|
### Epic 1: Authentication & User Management
|
|
- [x] User registration with email confirmation
|
|
- [x] Login with credentials
|
|
- [x] Password reset flow
|
|
- [x] Session management with Better Auth
|
|
- [x] Role-based access control (player, tournament_admin, club_admin)
|
|
|
|
### Epic 2: Player Profile & Analytics
|
|
- [x] Player profile page with statistics
|
|
- [x] Partnership performance table
|
|
- [x] Win rate and Elo display
|
|
- [x] Direct player stats (gamesPlayed, wins, losses)
|
|
|
|
### Epic 3: Rankings & Public Data
|
|
- [x] Player rankings page
|
|
- [x] Sortable rankings table
|
|
- [x] Public player profiles
|
|
- [x] Home page with top 10 players, recent tournament, club president
|
|
|
|
### Epic 4: Tournament Management
|
|
- [x] Create tournaments
|
|
- [x] Manage participants
|
|
- [x] Create teams
|
|
- [x] View tournament details
|
|
|
|
### Epic 5: Match Recording & CSV Import
|
|
- [x] Record match results via API
|
|
- [x] CSV upload for batch processing
|
|
- [x] Automatic Elo calculation
|
|
- [x] 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**
|
|
```bash
|
|
git clone <repository-url>
|
|
cd euchre_camp
|
|
```
|
|
|
|
2. **Install dependencies**
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
3. **Set up environment variables**
|
|
```bash
|
|
cp .env.example .env
|
|
# Edit .env to configure your database
|
|
```
|
|
|
|
4. **Set up the database**
|
|
|
|
**For SQLite (default):**
|
|
```bash
|
|
npx prisma migrate deploy
|
|
npx prisma generate
|
|
```
|
|
|
|
**For PostgreSQL:**
|
|
```bash
|
|
# Set up PostgreSQL database
|
|
npm run db:setup-postgres
|
|
|
|
# Or manually:
|
|
npx prisma migrate deploy
|
|
npx prisma generate
|
|
```
|
|
|
|
5. **Start the development server**
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Create a `.env` file:
|
|
|
|
```env
|
|
# 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:**
|
|
|
|
```env
|
|
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:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```bash
|
|
# 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
|
|
|
|
### Using just (recommended)
|
|
The project includes a `justfile` with common development tasks:
|
|
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)**
|
|
```bash
|
|
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**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
node scripts/list-users.js
|
|
```
|
|
|
|
**Update Admin Password:**
|
|
```bash
|
|
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
|
|
```bash
|
|
# 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](DOCKER.md) for detailed instructions.
|
|
|
|
**Quick Start:**
|
|
```bash
|
|
# Start all services (PostgreSQL + Next.js app)
|
|
docker-compose up -d
|
|
|
|
# Access the application
|
|
# http://localhost:3000
|
|
```
|
|
|
|
**Development Mode:**
|
|
```bash
|
|
# Start with hot reload
|
|
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
|
|
```
|
|
|
|
## License
|
|
|
|
MIT License
|