# EuchreCamp - Agent Guide This document provides guidance for AI agents working on the EuchreCamp project. ## Project Overview EuchreCamp is a Next.js 14+ application for managing Euchre tournaments and tracking partnership analytics. ### Key Technologies - **Next.js 14+** (App Router) - **TypeScript** - **Prisma ORM** (SQLite/PostgreSQL) - **Tailwind CSS** - **Better Auth** (Authentication) - **Bun** (Package Manager & Test Runner) - **Playwright** (Acceptance Testing) - **Vitest** (Legacy - migrated to Bun test runner) ## Architecture Patterns ### Authentication & Authorization - **Session Management**: Better Auth with cookie-based sessions - **Role-Based Access Control**: Three roles (player, tournament_admin, club_admin) - **Permission Functions**: Located in `src/lib/permissions.ts` - **Session Cache**: Disabled to avoid stale role data ### Database Schema - **Players**: `id`, `name`, `currentElo`, `gamesPlayed`, `wins`, `losses` - **Users**: `id`, `email`, `role`, `playerId` (foreign key to players) - **Events**: Tournaments with `ownerId` for ownership tracking - **Matches**: Individual match results with `createdById` for tracking ### Data Flow 1. User authentication via Better Auth 2. Session stored in HTTP-only cookies 3. Permission checks read directly from database 4. API routes enforce authorization ## Common Tasks ### Package Manager: Bun This project uses **Bun** as the package manager and test runner: ```bash # Install dependencies bun install # Run development server bun run dev # Build the application bun run build # Run unit/component tests bun test # Run unit tests only bun run test:unit # Run component tests only bun run test:component # Run acceptance tests (Playwright) bun run test:acceptance # Run linting bun run lint ``` **Note**: E2E tests still use Playwright, as Bun's test runner doesn't support browser automation. Unit and component tests have been migrated to Bun's native test runner for faster execution. E2E tests are located in the `e2e/` directory (not `src/__tests__/e2e/`). ### CI/CD with Bun All CI/CD workflows have been updated to use Bun: - **Dockerfile**: Uses `oven/bun:alpine` base image for all stages - **PR Workflow**: Uses `oven/setup-bun` action and `bun install`, `bun test` - **Release Workflow**: Uses Bun for version bumping and Docker builds **Note**: The `test.yml` workflow has been removed as it's redundant with the PR workflow. ### Admin User Creation To create an admin user, use the provided scripts: **Option 1: Using Better Auth API (Recommended)** ```bash bun run 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. ### Fixing Authentication Issues If users are redirected incorrectly or permissions aren't working: 1. Check if cookie cache is disabled in `src/lib/auth.ts` 2. Verify permission functions read from database, not session 3. Ensure `getSession()` uses `disableCookieCache=true` ### Adding New Features 1. Create API route in `src/app/api/` 2. Add permission checks using functions from `src/lib/permissions.ts` 3. Create UI component in `src/app/` or `src/components/` 4. Add tests in `src/__tests__/` 5. Run tests: `npm run test` and `npm run test:acceptance` ### Database Changes 1. Edit `prisma/schema.prisma` 2. Run `npx prisma migrate dev --name ` 3. Run `npx prisma generate` 4. Update affected API routes and components ### Database Provider Switching The application supports both SQLite (default) and PostgreSQL databases. **To switch between databases:** ```bash # Switch to SQLite npm run db:switch sqlite # Switch to PostgreSQL npm run db:switch postgresql ``` **To set up PostgreSQL:** ```bash npm run db:setup-postgres ``` **Database Configuration:** - Edit `.env` file to set `DATABASE_PROVIDER` and `DATABASE_URL` - For PostgreSQL, also set `DATABASE_SHADOW_URL` for migrations **Note:** The database provider is automatically detected by Better Auth and Prisma. ### Running Tests **Using just (recommended):** - **All tests**: `just test` (unit + acceptance with SQLite) - **Unit tests**: `just test-unit` - **Acceptance tests (SQLite)**: `just test-acceptance-sqlite` - **Acceptance tests (PostgreSQL)**: `just test-acceptance-postgres` - **PR validation**: `just pr-validate` (what runs on pull requests) **Using npm scripts:** - **Unit tests**: `npm run test` - **Acceptance tests**: `npm run test:acceptance` - **Specific test**: `npm run test:acceptance -- --grep "test name"` **CI-style acceptance tests with SQLite:** ```bash DATABASE_PROVIDER=sqlite DATABASE_URL=file:./prisma/ci.db npm run test:acceptance ``` ### 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 **Alternative for performance:** If CI performance becomes an issue, consider: - Using GitHub Actions cache for node_modules - Using a self-hosted runner with persistent workspace - Using the main Dockerfile's `test-runner` target for release workflows (which works because it builds a complete image) ### CI/CD Pipeline The project uses Gitea Actions for continuous integration: **PR Workflow** (`.gitea/workflows/pr.yml`): - Runs on pull requests to main - Executes unit tests and acceptance tests with SQLite - Analyzes commits for semantic versioning - Comments suggested bump type on PRs **Test Workflow** (`.gitea/workflows/test.yml`): - Runs on all branch pushes - Executes unit tests for quick feedback - Skips auto-generated version bump commits **Release Workflow** (`.gitea/workflows/release.yml`): - Runs on main branch pushes - Determines version bump type - Bumps version and creates git tags - Builds Docker images and runs tests - Pushes to registry and deploys **Database Strategy**: - CI tests use SQLite (fast, no server required) - Production uses PostgreSQL - Switch with `DATABASE_PROVIDER` environment variable ## Key Files ### Configuration - `src/lib/auth.ts` - Better Auth configuration - `src/lib/permissions.ts` - Authorization functions - `src/lib/elo-utils.ts` - Elo calculation logic ### API Routes - `src/app/api/auth/[[...all]]/route.ts` - Better Auth API - `src/app/api/tournaments/route.ts` - Tournament management - `src/app/api/matches/upload/route.ts` - CSV upload processing ### UI Components - `src/components/Navigation.tsx` - Navigation with role-based links - `src/app/page.tsx` - Home page with top players, recent tournament, club president - `src/app/players/[id]/profile/page.tsx` - Player profile with stats ### Tests - `src/__tests__/unit/permissions.test.ts` - Permission function tests - `src/__tests__/unit/elo.test.ts` - Elo calculation tests - `src/__tests__/e2e/global.setup.ts` - Test setup with admin user creation - `src/__tests__/e2e/home-page.test.ts` - Home page tests ## Troubleshooting ### Session Cache Issues **Problem**: Updated user roles don't reflect in session **Solution**: Ensure cookie cache is disabled and permission functions read from database ### Test Failures **Problem**: Tests timing out or failing unexpectedly **Solution**: - Check if dev server is running - Verify database is accessible - Run tests with `--headed` to see browser ### Database Conflicts **Problem**: Tests interfering with each other **Solution**: Tests run sequentially with `fullyParallel: false` and `workers: 1` ## Conventions ### Commit Messages - Use conventional commit format: `: ` - Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `ci` ### Code Style - Use TypeScript for type safety - Prefer React Server Components for data fetching - Keep business logic in `src/lib/` directory - Write tests for new features ### File Naming - Components: PascalCase (e.g., `Navigation.tsx`) - Utilities: camelCase (e.g., `elo-utils.ts`) - Tests: `.test.ts` or `.test.tsx` suffix ## File Organization See [docs/FILE_ORGANIZATION.md](docs/FILE_ORGANIZATION.md) for detailed file organization and structure. ## Resources - **Better Auth Docs**: https://better-auth.com/docs - **Next.js Docs**: https://nextjs.org/docs - **Prisma Docs**: https://www.prisma.io/docs - **Playwright Docs**: https://playwright.dev - **Vitest Docs**: https://vitest.dev/