A TypeScript-based backend API for the Tic Tac Toe game, using PostgreSQL with Knex.js for database management and Socket.io for real-time gameplay.
- TypeScript: Fully typed codebase for better maintainability
- PostgreSQL: Reliable relational database
- Knex.js: SQL query builder and migration tool
- Socket.io: Real-time multiplayer game support with authentication
- JWT Authentication: Secure token-based authentication
- bcrypt: Password hashing for security
- Rate Limiting: Protection against brute force attacks
- Input Validation: Zod-based schema validation
- Structured Logging: Winston logger with file output
- API Documentation: Swagger/OpenAPI documentation
- Health Checks: Database and server health monitoring
- Security Headers: Helmet.js for security
- Error Handling: Centralized error handling middleware
- Testing: Jest test framework setup
- CI/CD: GitHub Actions workflow
- Node.js (v18 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
-
Clone the repository
-
Install dependencies:
npm install
-
Set up environment variables:
cp .env.example .env
Edit
.envwith your database credentials and JWT secret. -
Run database migrations:
npm run migrate
Run the development server with hot reload:
npm run devBuild the TypeScript code:
npm run buildStart the production server:
npm startCreate a new migration:
npm run migrate:make migration_nameRun migrations:
npm run migrateRollback last migration:
npm run migrate:rollbackPORT: Server port (default: 8082)NODE_ENV: Environment (development/production/test)DB_HOST: PostgreSQL host (required)DB_PORT: PostgreSQL port (default: 5432)DB_NAME: Database name (required)DB_USER: Database user (required)DB_PASSWORD: Database password (required)DB_SSL: Use SSL connection (true/false)DATABASE_URL: Alternative connection stringJWT_SECRET: JWT secret key (required, minimum 32 characters)CORS_ORIGIN: CORS origin (use specific origin in production, not*)LOG_LEVEL: Logging level (error/warn/info/debug, default: info)
Create a new user account.
Request Body:
{
"username": "player1",
"password": "password123"
}Response:
{
"token": "jwt_token_here",
"user": {
"id": "uuid",
"username": "player1",
"points": 0
}
}Authenticate user and get JWT token.
Request Body:
{
"username": "player1",
"password": "password123"
}Response:
{
"token": "jwt_token_here",
"user": {
"id": "uuid",
"username": "player1",
"points": 0
}
}Get top 100 players by points.
Response:
{
"leaders": [
{
"id": "uuid",
"username": "player1",
"points": 100
}
]
}setPlayers(username): Join waiting room for matchmakingcancel: Leave waiting roomplay({ box, opponentId }): Make a movewinner({ side, opponentId }): Declare winnerupdateuserpoints(token): Add points after winning
matched(payload): Match found with opponent detailsplay({ box, timeObject }): Opponent made a movewinner(side): Game ended, winner declaredupdated: Points updated successfullyan error: Error occurred
src/
├── api/ # API routes and controllers
├── database/ # Database connection and migrations
├── model/ # Data models
├── services/ # Business logic
├── types/ # TypeScript type definitions
├── utilities/ # Utility functions
└── server.ts # Main server file
- Password hashing with bcrypt
- JWT token authentication (required for socket connections)
- Input validation with Zod schemas
- SQL injection prevention (via Knex)
- CORS configuration (environment-based)
- Rate limiting (5 requests/15min for auth, 100/15min for API)
- Security headers (Helmet.js)
- Request size limits (10kb)
- Socket.io authentication middleware
Interactive API documentation is available at /api-docs when the server is running. This provides:
- Complete API endpoint documentation
- Request/response schemas
- Try-it-out functionality
- Authentication examples
Run tests:
npm testRun tests in watch mode:
npm test:watchGenerate coverage report:
npm test:coverageThe API provides health check endpoints:
GET /healthGET /api/health
Returns server status, database connectivity, and uptime information.
Logs are written to:
- Console (all environments)
logs/error.log(production, errors only)logs/combined.log(production, all logs)
Log levels can be controlled via LOG_LEVEL environment variable.
ISC