2026-09-15 23:23:47 +03:30
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Setup(
|
|
|
|
|
engine *gin.Engine,
|
|
|
|
|
h Handlers,
|
|
|
|
|
jwtManager *utils.JWTManager,
|
|
|
|
|
userRepo *repository.UserRepository,
|
|
|
|
|
) {
|
|
|
|
|
engine.Use(middleware.CORS())
|
|
|
|
|
|
|
|
|
|
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")
|
|
|
|
|
|
|
|
|
|
// -------- احراز هویت (عمومی) --------
|
|
|
|
|
auth := api.Group("/auth")
|
|
|
|
|
{
|
|
|
|
|
auth.POST("/request-otp", h.Auth.RequestOTP)
|
|
|
|
|
auth.POST("/verify-otp", 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)
|
2026-09-16 09:21:50 +03:30
|
|
|
onboarding.POST("/photos", h.Onboarding.Photos)
|
2026-09-15 23:23:47 +03:30
|
|
|
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/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.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)
|
|
|
|
|
}
|
|
|
|
|
}
|