Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# DebateAI Backend Environment Configuration
# Copy this file to .env and fill in your actual values

# =============================================================================
# SERVER CONFIGURATION
# =============================================================================
# Port number for the backend server
SERVER_PORT=1313

# Application environment (development, staging, production)
APP_ENV=development

# Configuration file path (optional, defaults to ./config/config.prod.yml)
CONFIG_PATH=./config/config.prod.yml

# =============================================================================
# DATABASE CONFIGURATION
# =============================================================================
# MongoDB connection string
# For MongoDB Atlas: mongodb+srv://<username>:<password>@<cluster-url>/<database-name>
# For local MongoDB: mongodb://localhost:27017/debateai
DATABASE_URI=mongodb://localhost:27017/debateai

# =============================================================================
# AI SERVICE CONFIGURATION
# =============================================================================
# Google Gemini API Key
# Get from: https://ai.google.dev/gemini-api/docs/api-key
GEMINI_API_KEY=your_gemini_api_key_here

# OpenAI API Key (if using OpenAI models)
# Get from: https://platform.openai.com/api-keys
OPENAI_API_KEY=your_openai_api_key_here

# =============================================================================
# JWT CONFIGURATION
# =============================================================================
# Secret key for JWT token signing (generate with: openssl rand -hex 32)
JWT_SECRET=your_jwt_secret_key_here

# JWT token expiry time in minutes (1440 = 24 hours)
JWT_EXPIRY=1440

# =============================================================================
# EMAIL CONFIGURATION (SMTP)
# =============================================================================
# SMTP server configuration for sending emails
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587

# Email credentials
[email protected]
SMTP_PASSWORD=your_app_password_here

# Sender information
[email protected]
SENDER_NAME="DebateAI Team"

# =============================================================================
# GOOGLE OAUTH CONFIGURATION
# =============================================================================
# Google OAuth Client ID for social login
# Get from: Google Cloud Console > APIs & Services > Credentials
GOOGLE_OAUTH_CLIENT_ID=your_google_oauth_client_id_here

# =============================================================================
# AWS COGNITO CONFIGURATION (if using AWS Cognito)
# =============================================================================
# AWS Cognito configuration
COGNITO_APP_CLIENT_ID=your_cognito_app_client_id
COGNITO_APP_CLIENT_SECRET=your_cognito_app_client_secret
COGNITO_USER_POOL_ID=your_cognito_user_pool_id
COGNITO_REGION=us-east-1

# =============================================================================
# REDIS CONFIGURATION (Optional - for real-time features)
# =============================================================================
# Redis connection URL (optional, for real-time debate features)
# For local Redis: redis://localhost:6379
# For Redis Cloud: redis://username:password@host:port
REDIS_URL=redis://localhost:6379

# Redis password (if required)
REDIS_PASSWORD=

# Redis database number (default: 0)
REDIS_DB=0

# =============================================================================
# DEVELOPMENT/TESTING
# =============================================================================
# Set to true to enable debug endpoints and test features
DEBUG_MODE=true

# =============================================================================
# INSTRUCTIONS
# =============================================================================
# 1. Copy this file to .env: cp .env.example .env
# 2. Fill in your actual values for each variable
# 3. Never commit the .env file to version control
# 4. Make sure to add .env to your .gitignore file
#
# Required for basic functionality:
# - DATABASE_URI
# - GEMINI_API_KEY (for AI features)
# - JWT_SECRET
# - SMTP credentials (for email features)
#
# Optional but recommended:
# - REDIS_URL (for real-time debate features)
# - GOOGLE_OAUTH_CLIENT_ID (for social login)
#
# For production deployment:
# - Set APP_ENV=production
# - Use strong, unique values for all secrets
# - Use environment-specific database and Redis instances
47 changes: 32 additions & 15 deletions backend/cmd/server/main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package main

import (
"log"
"os"
"strconv"

"arguehub/config"
"arguehub/db"
"arguehub/internal/debate"
"arguehub/middlewares"
"arguehub/routes"
"arguehub/services"
Expand All @@ -21,19 +21,29 @@ func main() {
// Load the configuration from the specified YAML file
cfg, err := config.LoadConfig("./config/config.prod.yml")
if err != nil {
log.Fatalf("Failed to load config: %v", err)
panic("Failed to load config: " + err.Error())
}

services.InitDebateVsBotService(cfg)
services.InitDebateVsBotService(cfg)
services.InitCoachService()
services.InitRatingService(cfg)

// Connect to MongoDB using the URI from the configuration
if err := db.ConnectMongoDB(cfg.Database.URI); err != nil {
log.Fatalf("Failed to connect to MongoDB: %v", err)
panic("Failed to connect to MongoDB: " + err.Error())
}

// Connect to Redis if configured
if cfg.Redis.URL != "" {
redisURL := cfg.Redis.URL
if redisURL == "" {
redisURL = "localhost:6379"
}
if err := debate.InitRedis(redisURL, cfg.Redis.Password, cfg.Redis.DB); err != nil {
panic("Failed to initialize Redis: " + err.Error())
}
}
log.Println("Connected to MongoDB")


// Start the room watching service for matchmaking after DB connection
go websocket.WatchForNewRooms()

Expand All @@ -49,10 +59,9 @@ func main() {
// Set up the Gin router and configure routes
router := setupRouter(cfg)
port := strconv.Itoa(cfg.Server.Port)
log.Printf("Server starting on port %s", port)

if err := router.Run(":" + port); err != nil {
log.Fatalf("Failed to start server: %v", err)
panic("Failed to start server: " + err.Error())
}
}

Expand Down Expand Up @@ -80,7 +89,7 @@ func setupRouter(cfg *config.Config) *gin.Engine {
router.POST("/forgotPassword", routes.ForgotPasswordRouteHandler)
router.POST("/confirmForgotPassword", routes.VerifyForgotPasswordRouteHandler)
router.POST("/verifyToken", routes.VerifyTokenRouteHandler)

// Debug endpoint for matchmaking pool status
router.GET("/debug/matchmaking-pool", routes.GetMatchmakingPoolStatusHandler)

Expand All @@ -94,16 +103,15 @@ func setupRouter(cfg *config.Config) *gin.Engine {
auth.GET("/user/fetchprofile", routes.GetProfileRouteHandler)
auth.PUT("/user/updateprofile", routes.UpdateProfileRouteHandler)
auth.GET("/leaderboard", routes.GetLeaderboardRouteHandler)
auth.POST("/debate/result", routes.UpdateRatingAfterDebateRouteHandler)
auth.POST("/debate/result", routes.UpdateRatingAfterDebateRouteHandler)
routes.SetupDebateVsBotRoutes(auth)

// WebSocket signaling endpoint (handles auth internally)
router.GET("/ws", websocket.WebsocketHandler)

// Set up transcript routes
routes.SetupTranscriptRoutes(auth)
log.Println("Transcript routes registered")


auth.GET("/coach/strengthen-argument/weak-statement", routes.GetWeakStatement)
auth.POST("/coach/strengthen-argument/evaluate", routes.EvaluateStrengthenedArgument)

Expand All @@ -115,9 +123,18 @@ func setupRouter(cfg *config.Config) *gin.Engine {

// Chat functionality is now handled by the main WebSocket handler

auth.GET("/coach/pros-cons/topic", routes.GetProsConsTopic)
auth.POST("/coach/pros-cons/submit", routes.SubmitProsCons)
// Team routes
routes.SetupTeamRoutes(auth)
routes.SetupTeamDebateRoutes(auth)
routes.SetupTeamChatRoutes(auth)
routes.SetupTeamMatchmakingRoutes(auth)
}

// Team WebSocket handler
router.GET("/ws/team", websocket.TeamWebsocketHandler)

// Debate spectator WebSocket handler (no auth required for anonymous spectators)
router.GET("/ws/debate/:debateID", DebateWebsocketHandler)

return router
}
Loading