Files
chat_room/cmd/api/main.go
T
mobiniqow 2823fb45f5 Initial commit: dating app backend (Go/Gin/GORM/Postgres)
Phone+OTP auth, staged onboarding, admin approval workflow, and a
full discovery/swipe/match/chat system with photo upload and
approximate distance (haversine) based on user location.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 23:23:47 +03:30

90 lines
3.3 KiB
Go

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)
}
}