package router import ( "github.com/gin-gonic/gin" "dating-app/internal/handler" "dating-app/internal/middleware" "dating-app/internal/repository" "dating-app/internal/utils" ) type Handlers struct { Auth *handler.AuthHandler Onboarding *handler.OnboardingHandler Profile *handler.ProfileHandler Admin *handler.AdminHandler Discovery *handler.DiscoveryHandler Chat *handler.ChatHandler Monitoring *handler.MonitoringHandler Backup *handler.BackupHandler } func Setup( engine *gin.Engine, h Handlers, jwtManager *utils.JWTManager, userRepo *repository.UserRepository, ) { engine.Use(middleware.CORS()) engine.Use(middleware.Gzip()) engine.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) }) // فایل‌های عکس آپلودشده (خارج از /api/v1، چون فایل استاتیکه نه API) engine.Static("/uploads", "./uploads") api := engine.Group("/api/v1") // -------- احراز هویت (عمومی) -------- // درخواست OTP هزینه‌ی پیامک داره و هدف مناسبی برای اسپم/brute-force هست؛ // حداکثر ۵ درخواست، بعد هر ثانیه یک توکن شارژ می‌شه (یعنی حدود ۵ تا در دقیقه‌ی اول و بعدش پیوسته). otpRateLimit := middleware.RateLimiter(5, 1.0/12.0) auth := api.Group("/auth") { auth.POST("/request-otp", otpRateLimit, h.Auth.RequestOTP) auth.POST("/verify-otp", otpRateLimit, h.Auth.VerifyOTP) auth.POST("/token/refresh", h.Auth.RefreshToken) } authRequired := middleware.AuthRequired(jwtManager, userRepo) // -------- پروفایل -------- profile := api.Group("/profile", authRequired) { profile.GET("/me", h.Profile.Me) profile.POST("/photos", h.Profile.UploadPhoto) profile.DELETE("/photos/:id", h.Profile.DeletePhoto) profile.PATCH("/location", h.Profile.UpdateLocation) } // -------- آنبوردینگ (نیاز به ورود) -------- onboarding := api.Group("/onboarding", authRequired) { onboarding.GET("/status", h.Onboarding.Status) onboarding.POST("/basic-info", h.Onboarding.BasicInfo) onboarding.POST("/photos", h.Onboarding.Photos) onboarding.POST("/body-info", h.Onboarding.BodyInfo) onboarding.GET("/profile-questions", h.Onboarding.AvailableQuestions) onboarding.POST("/profile-questions", h.Onboarding.SetProfileQuestions) onboarding.POST("/education", h.Onboarding.Education) onboarding.POST("/occupations", h.Onboarding.Occupations) onboarding.POST("/relationship-importance", h.Onboarding.RelationshipImportance) onboarding.POST("/interests", h.Onboarding.Interests) onboarding.POST("/looking-for", h.Onboarding.LookingFor) // لیست گزینه‌های فعال هر دسته، برای نمایش در فرم هر مرحله // category یکی از: education_level, field_of_study, occupation, // important_in_relationship, interest, looking_for onboarding.GET("/options/:category", h.Onboarding.Options) } // -------- دوستیابی (نیاز به ورود) -------- api.GET("/discover", authRequired, h.Discovery.Feed) api.GET("/discover/:id", authRequired, h.Discovery.CandidateDetail) api.POST("/discover/:id/swipe", authRequired, h.Discovery.Swipe) // -------- مچ‌ها و گفتگو (نیاز به ورود) -------- matches := api.Group("/matches", authRequired) { matches.GET("", h.Chat.ListMatches) matches.GET("/:id/messages", h.Chat.ListMessages) matches.POST("/:id/messages", h.Chat.SendMessage) } // -------- پنل ادمین (نیاز به ورود + نقش ادمین) -------- admin := api.Group("/admin", authRequired, middleware.AdminRequired()) { admin.GET("/users", h.Admin.ListAllUsers) admin.GET("/users/pending", h.Admin.ListPendingUsers) admin.GET("/users/:id", h.Admin.GetUserDetail) admin.POST("/users/:id/approve", h.Admin.ApproveUser) admin.POST("/users/:id/reject", h.Admin.RejectUser) admin.POST("/users/:id/block", h.Admin.BlockUser) admin.POST("/users/:id/unblock", h.Admin.UnblockUser) admin.POST("/users/:id/report", h.Admin.ReportUser) admin.GET("/users/:id/reports", h.Admin.ListUserReports) // رفقا (مچ‌ها) admin.GET("/matches", h.Admin.ListAllMatches) // نظارت بر عکس‌های آپلودشده admin.GET("/photos", h.Admin.ListAllPhotos) admin.DELETE("/photos/:id", h.Admin.DeletePhoto) admin.GET("/categories/:key", h.Admin.GetCategory) admin.PATCH("/categories/:key", h.Admin.UpdateCategory) admin.GET("/categories/:key/options", h.Admin.ListOptions) admin.POST("/categories/:key/options", h.Admin.CreateOption) admin.PATCH("/options/:id", h.Admin.UpdateOption) admin.DELETE("/options/:id", h.Admin.DeleteOption) admin.GET("/profile-questions", h.Admin.ListQuestions) admin.POST("/profile-questions", h.Admin.CreateQuestion) admin.PATCH("/profile-questions/:id", h.Admin.UpdateQuestion) admin.DELETE("/profile-questions/:id", h.Admin.DeleteQuestion) // مانیتورینگ: بار/زمان/ریسپانس درخواست‌های اخیر سرور admin.GET("/monitoring/summary", h.Monitoring.Summary) admin.GET("/monitoring/requests", h.Monitoring.RecentRequests) // بک‌آپ دیتابیس admin.GET("/backups", h.Backup.List) admin.POST("/backups", h.Backup.Create) admin.GET("/backups/:filename", h.Backup.Download) } }