diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a41b8c4 --- /dev/null +++ b/.env.example @@ -0,0 +1,45 @@ +# Server +PORT=3000 +HOST=0.0.0.0 +NODE_ENV=development + +# Database +DATABASE_URL=postgresql://samreshu:samreshu_dev@localhost:5432/samreshu + +# Redis +REDIS_URL=redis://localhost:6379 + +# Auth +JWT_SECRET=dev-secret-change-in-production-min-32-chars +JWT_ACCESS_TTL=15m +JWT_REFRESH_TTL=7d + +# LLM +LLM_BASE_URL=http://localhost:11434/v1 +LLM_MODEL=qwen2.5:14b +LLM_API_KEY= +LLM_TIMEOUT_MS=15000 +LLM_MAX_RETRIES=1 +LLM_TEMPERATURE=0.7 +LLM_MAX_TOKENS=2048 + +# Rate limits +RATE_LIMIT_LOGIN=5 +RATE_LIMIT_REGISTER=3 +RATE_LIMIT_FORGOT_PASSWORD=3 +RATE_LIMIT_VERIFY_EMAIL=5 +RATE_LIMIT_API_AUTHED=100 +RATE_LIMIT_API_GUEST=30 + +# CORS (comma-separated origins) +CORS_ORIGINS=http://localhost:5173,http://localhost:3000 + +# Email (dev — mailpit / mailtrap) +SMTP_HOST=localhost +SMTP_PORT=1025 +SMTP_USER= +SMTP_PASS= +EMAIL_FROM=noreply@samreshu.dev + +# Sentry (optional for dev) +SENTRY_DSN= diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..dcbf5f7 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,29 @@ +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_USER: samreshu + POSTGRES_PASSWORD: samreshu_dev + POSTGRES_DB: samreshu + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U samreshu -d samreshu"] + interval: 5s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 5 + +volumes: + pgdata: diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 0000000..510756f --- /dev/null +++ b/src/server.ts @@ -0,0 +1,26 @@ +import 'dotenv/config'; +import { buildApp } from './app.js'; +import { env } from './config/env.js'; + +async function main() { + const app = await buildApp(); + + try { + await app.listen({ port: env.PORT, host: env.HOST }); + app.log.info({ port: env.PORT }, 'Server started'); + } catch (err) { + app.log.error(err); + process.exit(1); + } + + const shutdown = async () => { + app.log.info('Shutting down...'); + await app.close(); + process.exit(0); + }; + + process.on('SIGINT', shutdown); + process.on('SIGTERM', shutdown); +} + +main();