1cd2cbd0a6
- Update Dockerfile to use oven/bun:alpine image - Update PR workflow to use Bun (oven/setup-bun action) - Update Test workflow to use Bun - Update Release workflow to use Bun - Remove test.yml workflow (redundant with PR workflow) - Update Docker build commands to use Bun - Docker build verified working
284 lines
9.3 KiB
Markdown
284 lines
9.3 KiB
Markdown
# 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 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.
|
|
|
|
### 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 <migration-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: `<type>: <description>`
|
|
- 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/
|