A comprehensive web application for managing hackathon judging, scoring, and team management. Built with Node.js, Express, SQLite, and Handlebars.
- Judge Queue System: Intelligent team assignment ensuring each team gets the required number of judges
- Score Entry: Easy-to-use interface for entering scores with notes
- My Scores: View and edit all scores you've entered
- Live Leaderboard: Real-time score updates with division-based rankings
- Team Dashboard: View your team's scores, rank, and statistics
- Team Registration: Register your team with project details
- Live Scores: Track your team's performance across rounds
- Team Information: Update project details and contact information
- Admin Dashboard: Comprehensive overview of teams, judges, and event status
- User Management: Add judges individually or import via CSV
- Team Management: View, edit, and manage all registered teams
- Event Settings: Configure event name, dates, divisions, logo, and rounds
- Table Management: Manage table assignments and generate chessboard layout
- Round Management: Lock rounds and increment to next round
- Backend: Node.js, Express.js
- Database: SQLite3
- Templating: Handlebars.js
- Authentication: JWT (JSON Web Tokens) with magic link login
- Email: Mailgun integration
- Styling: Tailwind CSS
- Testing: Jest
- Node.js (v14 or higher)
- npm or yarn
- Mailgun account (for email functionality)
- SQLite3
- Clone the repository:
git clone <repository-url>
cd code-camp-judging-app- Install dependencies:
npm install- Create a
.envfile in the root directory:
# Server Configuration
PORT=3000
NODE_ENV=development
# Session & JWT
SESSION_SECRET=your-session-secret-here
JWT_SECRET=your-jwt-secret-here
# Mailgun Configuration (for email functionality)
MAILGUN_API_KEY=your-mailgun-api-key
MAILGUN_DOMAIN=your-mailgun-domain
MAILGUN_FROM_EMAIL=noreply@yourdomain.com
# Judge Queue Configuration
JUDGES_PER_TEAM=2- Initialize the database:
npm startThe database will be automatically created on first run.
- Access the application:
http://localhost:3000
| Variable | Description | Default | Required |
|---|---|---|---|
PORT |
Server port | 3000 | No |
NODE_ENV |
Environment (development/production) | development | No |
SESSION_SECRET |
Secret for session encryption | - | Yes |
JWT_SECRET |
Secret for JWT token signing | - | Yes |
MAILGUN_API_KEY |
Mailgun API key for emails | - | Yes |
MAILGUN_DOMAIN |
Mailgun domain | - | Yes |
MAILGUN_FROM_EMAIL |
From email address | - | Yes |
JUDGES_PER_TEAM |
Number of judges required per team per round | 2 | No |
-
Create Admin Account: The system automatically creates a default admin account on first run. Check the console for login credentials.
-
Configure Event Settings:
- Navigate to Admin Dashboard → Event Settings
- Set event name, dates, divisions, and upload logo
- Configure initial round settings
-
Add Judges:
- Individual: Admin Dashboard → Add User
- Bulk Import: Admin Dashboard → Import Judges (CSV)
-
Set Up Tables:
- Admin Dashboard → Manage Tables
- Use "Quick Setup" to generate chessboard layout (A1-P10)
- Or add tables manually
-
Team Registration:
- Teams can register at
/register - Or admins can add teams manually
- Teams can register at
The judge queue system ensures fair distribution of judges:
- Each team gets exactly
JUDGES_PER_TEAMjudges per round - Judges never judge the same team twice (across all rounds)
- System automatically routes judges to teams needing judges
- Load balancing prioritizes teams with fewer judges
Usage:
- Judges click "Judge Queue" from the dashboard
- Click "Get Next Team" to be assigned a team
- Enter score and submit
- System automatically assigns next team
- When all teams are judged, judges see completion message
-
Cumulative Scoring: Scores accumulate across rounds
- Round 1: Only Round 1 scores
- Round 2: Round 1 + Round 2 scores
- Round 3: Round 1 + Round 2 + Round 3 scores
- And so on...
-
Division-based Rankings: Teams are ranked within their division
-
Round Locking: Admins can lock rounds to prevent score edits
- Admin: Full access to all features
- Judge: Can enter scores, view leaderboard, use judge queue
- Participant: Can view their team's scores and update team info
code-camp-judging-app/
├── db/
│ └── database.js # Database operations
├── middleware/
│ ├── rbac.js # Role-based access control
│ └── validation.js # Input validation
├── routes/
│ ├── admin.js # Admin routes
│ ├── auth.js # Authentication routes
│ ├── index.js # Main dashboard
│ ├── participant.js # Participant routes
│ ├── register.js # Team registration
│ └── scores.js # Score management
├── scripts/
│ └── create-sample-data.js # Sample data generator
├── services/
│ ├── email.js # Email service (Mailgun)
│ └── profanity-filter.js # Profanity filtering
├── tests/
│ ├── database.test.js # Database tests
│ ├── judge-queue.test.js # Judge queue tests
│ ├── profanity-filter.test.js
│ ├── rbac.test.js # RBAC tests
│ ├── scores.test.js # Score tests
│ └── validation.test.js # Validation tests
├── views/
│ ├── admin/ # Admin views
│ ├── auth/ # Authentication views
│ ├── layouts/ # Layout templates
│ ├── participant/ # Participant views
│ ├── scores/ # Score views
│ └── partials/ # Reusable partials
├── public/
│ └── uploads/ # Uploaded files (logos)
├── server.js # Main server file
└── package.json
# Start the server
npm start
# Start in development mode (with auto-reload)
npm run dev
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageThe project includes comprehensive unit tests. See tests/README.md for detailed information.
Run all tests:
npm testRun specific test suite:
npm test -- tests/judge-queue.test.js- JWT Authentication: Secure token-based authentication
- SQL Injection Protection: All queries use parameterized statements
- Profanity Filter: Input validation using external wordlist
- Role-Based Access Control: Middleware ensures proper authorization
- Session Security: Secure session cookies in production
The system sends emails for:
- Magic link login
- Team registration confirmation
- Judge account creation (individual and bulk)
Configure Mailgun in your .env file to enable email functionality.
The application uses SQLite3 for data storage. The database file (judging.db) is created automatically in the db/ directory.
users: User accounts (judges, admins, participants)teams: Registered teamsscores: Judge scoresjudge_team_assignments: Judge queue assignmentsevent_settings: Event configurationmagic_tokens: Authentication tokenstables: Table assignments
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
ISC
For issues, questions, or contributions, please open an issue on the repository.