171 lines
6.1 KiB
Go
171 lines
6.1 KiB
Go
package main
|
||
|
||
import (
|
||
"flag"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"strings"
|
||
|
||
"gobeyhan/app/routes"
|
||
"gobeyhan/config"
|
||
"gobeyhan/database"
|
||
"gobeyhan/pkg/utils"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
swaggerFiles "github.com/swaggo/files"
|
||
ginSwagger "github.com/swaggo/gin-swagger"
|
||
|
||
_ "gobeyhan/docs" // Swagger docs
|
||
)
|
||
|
||
// @title Beyhan Backend API
|
||
// @version 2.0
|
||
// @description Modular REST API with Blog, Account, and Settings apps
|
||
// @termsOfService http://swagger.io/terms/
|
||
|
||
// @contact.name API Support
|
||
// @contact.email support@beyhan.com
|
||
|
||
// @license.name MIT
|
||
// @license.url https://opensource.org/licenses/MIT
|
||
|
||
// @host localhost:8080
|
||
// @BasePath /
|
||
|
||
// @securityDefinitions.apikey BearerAuth
|
||
// @in header
|
||
// @name Authorization
|
||
// @description Type "Bearer" followed by a space and JWT token.
|
||
|
||
func main() {
|
||
config.LoadConfig()
|
||
|
||
migrateFlag := flag.Bool("migrate", false, "Run database migrations (AutoMigrate)")
|
||
seedFlag := flag.Bool("seed", false, "Run database seeds (may include creating admin user)")
|
||
migrateOnlyFlag := flag.Bool("migrate-only", false, "Run migrations and exit (don't start server)")
|
||
flag.Parse()
|
||
|
||
database.ConnectDB()
|
||
|
||
// If seed flag passed, run full seed (includes migrations) immediately regardless of env
|
||
if *seedFlag {
|
||
database.SeedAll()
|
||
log.Println("Seeding complete")
|
||
return
|
||
}
|
||
|
||
// Determine environment: prefer config.AppConfig.Env (set by LoadConfig), else fallback to APP_ENV env var
|
||
env := "development"
|
||
if config.AppConfig != nil && config.AppConfig.Env != "" {
|
||
env = config.AppConfig.Env
|
||
} else if v := os.Getenv("APP_ENV"); v != "" {
|
||
env = v
|
||
}
|
||
|
||
// Migration handling
|
||
shouldMigrate := *migrateFlag || *migrateOnlyFlag || env == "development"
|
||
if shouldMigrate {
|
||
if err := database.Migrate(database.DB); err != nil {
|
||
log.Fatalf("Migration Yapılamadı: %v", err)
|
||
}
|
||
log.Println("Migration complete")
|
||
}
|
||
|
||
// If migrate-only flag, exit after migration
|
||
if *migrateOnlyFlag {
|
||
return
|
||
}
|
||
|
||
forceSeed := os.Getenv("FORCE_SEED")
|
||
if strings.ToLower(forceSeed) == "true" {
|
||
database.SeedAll()
|
||
log.Println("Seeding complete")
|
||
}
|
||
|
||
// Setup Redis
|
||
database.ConnectRedis()
|
||
if err := database.FlushAll(); err != nil {
|
||
log.Printf("Warning: Failed to flush Redis cache: %v", err)
|
||
}
|
||
|
||
// Print banner
|
||
fmt.Println(`
|
||
╔════════════════════════════════════════════════════════╗
|
||
║ ║
|
||
║ ██████╗ ███████╗██╗ ██╗██╗ ██╗ █████╗ ███╗ ██╗ ║
|
||
║ ██╔══██╗██╔════╝╚██╗ ██╔╝██║ ██║██╔══██╗████╗ ██║ ║
|
||
║ ██████╔╝█████╗ ╚████╔╝ ███████║███████║██╔██╗ ██║ ║
|
||
║ ██╔══██╗██╔══╝ ╚██╔╝ ██╔══██║██╔══██║██║╚██╗██║ ║
|
||
║ ██████╔╝███████╗ ██║ ██║ ██║██║ ██║██║ ╚████║ ║
|
||
║ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ║
|
||
║ ║
|
||
║ ██████╗ █████╗ ██████╗██╗ ██╗ ║
|
||
║ ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝ ║
|
||
║ ██████╔╝███████║██║ █████╔╝ ║
|
||
║ ██╔══██╗██╔══██║██║ ██╔═██╗ ║
|
||
║ ██████╔╝██║ ██║╚██████╗██║ ██╗ ║
|
||
║ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ║
|
||
║ BACKEND ║
|
||
║ ║
|
||
╚════════════════════════════════════════════════════════╝
|
||
`)
|
||
fmt.Println(" Go Backend | v2.0.0 | " + utils.ColorGreen + "Running" + utils.ColorReset)
|
||
fmt.Println()
|
||
|
||
// Initialize Gin
|
||
if env == "production" {
|
||
gin.SetMode(gin.ReleaseMode)
|
||
}
|
||
|
||
r := gin.Default()
|
||
|
||
// Disable automatic redirects to prevent infinite loops with SPA routing
|
||
r.RedirectTrailingSlash = false
|
||
r.RedirectFixedPath = false
|
||
|
||
// Swagger endpoint
|
||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||
|
||
// Setup routes from modular apps
|
||
routes.SetupRoutes(r)
|
||
|
||
// Register Web Handlers (Frontend / Admin Panel)
|
||
// admin_panel.RegisterHandlers(r)
|
||
|
||
trustedEnv := strings.TrimSpace(os.Getenv("TRUSTED_PROXIES"))
|
||
var trusted []string
|
||
if trustedEnv != "" {
|
||
for _, s := range strings.Split(trustedEnv, ",") {
|
||
if t := strings.TrimSpace(s); t != "" {
|
||
trusted = append(trusted, t)
|
||
}
|
||
}
|
||
} else {
|
||
// Nil ile çağırmak, "hiçbir proxy'ye güvenme" davranışını sağlar
|
||
trusted = nil
|
||
}
|
||
|
||
// Set trusted proxies on Gin router to avoid the "trusted all proxies" warning.
|
||
// If `trusted` is nil, no proxies will be trusted. This will error if the list contains an invalid entry.
|
||
if err := r.SetTrustedProxies(trusted); err != nil {
|
||
log.Fatalf("Failed to set trusted proxies: %v", err)
|
||
}
|
||
log.Printf("Trusted proxies configured: %v", trusted)
|
||
|
||
// Get port from config
|
||
port := config.AppConfig.Port
|
||
if port == "" {
|
||
port = "8080"
|
||
}
|
||
|
||
// Start server
|
||
log.Printf("🚀 Server starting on port %s", port)
|
||
log.Printf("📚 Swagger UI: http://localhost:%s/swagger/index.html", port)
|
||
log.Printf("🌐 API Base: http://localhost:%s/api/v1", port)
|
||
|
||
if err := r.Run(":" + port); err != nil {
|
||
log.Fatalf("Failed to start server: %v", err)
|
||
}
|
||
}
|