Collaborative-pixel-art/backend/src/config/env.ts
martin 98f290a662 Rewrite with modern stack
Major refactor from simple HTML/JS app to modern full-stack TypeScript application:

## Architecture Changes
- Migrated to monorepo structure with workspaces (backend, frontend, shared)
- Backend: Node.js + Express + TypeScript + Socket.IO
- Frontend: Next.js 15.5 + React 19 + TypeScript + Tailwind CSS
- Shared: Common types and utilities across packages

## Key Features Implemented
- Real-time WebSocket collaboration via Socket.IO
- Virtual canvas with chunked loading for performance
- Modern UI with dark mode and responsive design
- Mock database system for easy development (Redis/PostgreSQL compatible)
- Comprehensive error handling and rate limiting
- User presence and cursor tracking
- Infinite canvas support with zoom/pan controls

## Performance Optimizations
- Canvas virtualization - only renders visible viewport
- Chunked pixel data loading (64x64 pixel chunks)
- Optimized WebSocket protocol
- Memory-efficient state management with Zustand

## Development Experience
- Full TypeScript support across all packages
- Hot reload for both frontend and backend
- Docker support for production deployment
- Comprehensive linting and formatting
- Automated development server startup

## Fixed Issues
- Corrected start script paths
- Updated environment configuration
- Fixed ESLint configuration issues
- Ensured all dependencies are properly installed
- Verified build process works correctly

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 19:28:05 +02:00

43 lines
No EOL
1.4 KiB
TypeScript

import dotenv from 'dotenv';
dotenv.config();
export const config = {
port: parseInt(process.env.PORT || '3001'),
host: process.env.HOST || 'localhost',
nodeEnv: process.env.NODE_ENV || 'development',
jwtSecret: process.env.JWT_SECRET || 'your-super-secret-jwt-key-change-in-production',
corsOrigin: process.env.CORS_ORIGIN ? process.env.CORS_ORIGIN.split(',') : ['http://localhost:3000'],
// Rate limiting
rateLimits: {
pixelsPerMinute: parseInt(process.env.RATE_LIMIT_PIXELS_PER_MINUTE || '60'),
pixelsPerHour: parseInt(process.env.RATE_LIMIT_PIXELS_PER_HOUR || '1000'),
cursorUpdatesPerSecond: parseInt(process.env.RATE_LIMIT_CURSOR_PER_SECOND || '10'),
},
// Canvas settings
canvas: {
maxSize: parseInt(process.env.MAX_CANVAS_SIZE || '10000'),
defaultSize: parseInt(process.env.DEFAULT_CANVAS_SIZE || '1000'),
chunkSize: parseInt(process.env.CHUNK_SIZE || '64'),
},
// Redis settings
redis: {
url: process.env.REDIS_URL || 'redis://localhost:6379',
keyPrefix: process.env.REDIS_KEY_PREFIX || 'gaplace:',
},
// Logging
logLevel: process.env.LOG_LEVEL || 'info',
} as const;
export function validateConfig(): void {
const required = ['JWT_SECRET'];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0 && config.nodeEnv === 'production') {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
}