package main import ( "log" "github.com/gin-gonic/gin" "dating-app/internal/config" "dating-app/internal/database" "dating-app/internal/handler" "dating-app/internal/repository" "dating-app/internal/router" "dating-app/internal/service" "dating-app/internal/utils" ) func main() { cfg := config.Load() db, err := database.Connect(cfg) if err != nil { log.Fatalf("اتصال به دیتابیس ناموفق بود: %v", err) } if err := database.AutoMigrate(db); err != nil { log.Fatalf("migrate ناموفق بود: %v", err) } if err := database.SeedCategories(db); err != nil { log.Fatalf("seed کردن دسته‌ها ناموفق بود: %v", err) } if err := database.BootstrapAdmin(db, cfg.AdminBootstrapPhone); err != nil { log.Fatalf("ساخت ادمین اولیه ناموفق بود: %v", err) } // -------- Repositories -------- userRepo := repository.NewUserRepository(db) optionRepo := repository.NewOptionRepository(db) questionRepo := repository.NewQuestionRepository(db) photoRepo := repository.NewPhotoRepository(db) swipeRepo := repository.NewSwipeRepository(db) matchRepo := repository.NewMatchRepository(db) messageRepo := repository.NewMessageRepository(db) // -------- Utils / Infra -------- jwtManager := utils.NewJWTManager( cfg.JWTAccessSecret, cfg.JWTRefreshSecret, cfg.JWTAccessTTL, cfg.JWTRefreshTTL, ) // برای اتصال به یک گیت‌وی پیامک واقعی، این خط رو با پیاده‌سازی خودت // (که service.OTPSender رو implement می‌کنه) عوض کن. otpSender := service.NewMockOTPSender(cfg.AppEnv != "production") // برای اتصال به یک object storage واقعی، این خط رو با پیاده‌سازی خودت // (که service.PhotoStorage رو implement می‌کنه) عوض کن. photoStorage := service.NewLocalPhotoStorage("./uploads/photos", "/uploads/photos") // -------- Services -------- authService := service.NewAuthService( userRepo, otpSender, jwtManager, cfg.OTPExpirySeconds, cfg.OTPLength, cfg.OTPHashSecret, ) onboardingService := service.NewOnboardingService(userRepo, optionRepo, questionRepo) adminService := service.NewAdminService(optionRepo, questionRepo, userRepo) profileService := service.NewProfileService(photoRepo, userRepo, photoStorage) discoveryService := service.NewDiscoveryService(userRepo, photoRepo, swipeRepo, matchRepo, optionRepo, questionRepo) chatService := service.NewChatService(matchRepo, messageRepo, userRepo, photoRepo) // -------- Handlers -------- handlers := router.Handlers{ Auth: handler.NewAuthHandler(authService), Onboarding: handler.NewOnboardingHandler(onboardingService), Profile: handler.NewProfileHandler(optionRepo, questionRepo, photoRepo, onboardingService, profileService), Admin: handler.NewAdminHandler(adminService, optionRepo, questionRepo, photoRepo, onboardingService), Discovery: handler.NewDiscoveryHandler(discoveryService), Chat: handler.NewChatHandler(chatService), } if cfg.AppEnv == "production" { gin.SetMode(gin.ReleaseMode) } engine := gin.Default() router.Setup(engine, handlers, jwtManager, userRepo) log.Printf("سرور روی پورت %s در حال اجراست (env=%s)", cfg.AppPort, cfg.AppEnv) if err := engine.Run(":" + cfg.AppPort); err != nil { log.Fatalf("اجرای سرور ناموفق بود: %v", err) } }