15357fd3c0
yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarba
306 lines
11 KiB
Go
306 lines
11 KiB
Go
// routes/routes.go
|
|
package routes
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"gorm.io/gorm"
|
|
|
|
"api_bb/internal/config"
|
|
"api_bb/internal/handlers"
|
|
"api_bb/internal/repository"
|
|
"api_bb/internal/service"
|
|
"api_bb/pkg/logger"
|
|
"api_bb/pkg/middleware"
|
|
)
|
|
|
|
func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
|
|
r := chi.NewRouter()
|
|
|
|
// Apply common middleware
|
|
for _, m := range middleware.CommonMiddleware() {
|
|
r.Use(m)
|
|
}
|
|
|
|
// handler
|
|
h := handlers.NewHandler(db, config)
|
|
|
|
// Serve static files (avatars)
|
|
r.Handle("/uploads/*", http.StripPrefix("/uploads/",
|
|
http.FileServer(http.Dir("./uploads"))))
|
|
|
|
// Initialize repositories
|
|
userRepo := repository.NewUserRepository(db)
|
|
|
|
// Initialize logger
|
|
baseLogger := logger.NewWrapper(logger.Get())
|
|
|
|
// Initialize services with logger
|
|
jwtService := service.NewJWTService(config.JWTSecret)
|
|
|
|
// Email service initialization with fallback
|
|
var emailHandler *handlers.EmailHandler
|
|
if h.EmailHandler() != nil {
|
|
emailHandler = h.EmailHandler()
|
|
}
|
|
|
|
// Health routes
|
|
r.Route("/api", func(r chi.Router) {
|
|
r.Get("/health", h.HealthHandler().HealthCheck)
|
|
r.Get("/check", h.HealthHandler().Check)
|
|
})
|
|
|
|
// API v1 routes
|
|
r.Route("/v1", func(r chi.Router) {
|
|
|
|
// Email verification (public) - только если доступен
|
|
if emailHandler != nil {
|
|
r.Get("/verify-email", emailHandler.VerifyEmail)
|
|
}
|
|
|
|
// Public auth routes
|
|
r.Route("/auth", func(r chi.Router) {
|
|
r.Post("/register", h.AuthHandler().Register)
|
|
r.Post("/login", h.AuthHandler().Login)
|
|
r.Post("/logout", h.AuthHandler().Logout)
|
|
|
|
// Email routes (only if email handler is available)
|
|
if emailHandler != nil {
|
|
r.Post("/verify-email/resend", emailHandler.ResendVerification)
|
|
r.Post("/password-reset/request", emailHandler.RequestPasswordReset)
|
|
r.Post("/password-reset/confirm", emailHandler.ConfirmPasswordReset)
|
|
}
|
|
})
|
|
|
|
// Публичные маршруты для достижений (если нужны)
|
|
r.Route("/achievements", func(r chi.Router) {
|
|
// Публичные маршруты для просмотра достижений других пользователей
|
|
r.Get("/user/{userID}", h.UserAchievementHandler().GetPublicUserAchievements)
|
|
r.Get("/user/{userID}/summary", h.UserAchievementHandler().GetPublicUserAchievementsSummary)
|
|
r.Get("/user/{userID}/recent", h.UserAchievementHandler().GetPublicRecentAchievements)
|
|
})
|
|
|
|
// Protected routes
|
|
r.Route("/user", func(r chi.Router) {
|
|
r.Use(middleware.AuthMiddleware(jwtService, userRepo))
|
|
r.Use(middleware.RequireAuth)
|
|
|
|
// user profile routes
|
|
r.Get("/profile", h.UserHandler().GetProfile)
|
|
r.Post("/editProfile", h.UserHandler().UpdateProfile)
|
|
r.Get("/", h.UserHandler().GetUsers)
|
|
|
|
// Все операции с аватарами теперь через AvatarHandler
|
|
r.Route("/avatars", func(r chi.Router) {
|
|
r.Post("/upload", h.AvatarHandler().UploadAvatar)
|
|
r.Delete("/delete", h.AvatarHandler().DeleteAvatar)
|
|
r.Get("/{filename}", h.AvatarHandler().GetAvatar)
|
|
})
|
|
|
|
r.Route("/stats", func(r chi.Router) {
|
|
r.Get("/", h.UserStatsHandler().GetUserStats)
|
|
r.Get("/{userID}", h.UserStatsHandler().GetUserStatsByID)
|
|
r.Post("/workout", h.UserStatsHandler().IncrementWorkout)
|
|
r.Put("/personal-best", h.UserStatsHandler().UpdatePersonalBest)
|
|
r.Post("/weekly/reset", h.UserStatsHandler().ResetWeeklyDistance)
|
|
r.Post("/monthly/reset", h.UserStatsHandler().ResetMonthlyDistance)
|
|
})
|
|
|
|
// Маршруты для тренировок
|
|
r.Route("/workouts", func(r chi.Router) {
|
|
r.Post("/", h.UserWorkoutHandler().CreateWorkout)
|
|
r.Get("/", h.UserWorkoutHandler().GetWorkouts)
|
|
r.Get("/stats", h.UserWorkoutHandler().GetWorkoutStats)
|
|
r.Get("/type/{type}", h.UserWorkoutHandler().GetWorkoutsByType)
|
|
|
|
r.Route("/{id}", func(r chi.Router) {
|
|
r.Get("/", h.UserWorkoutHandler().GetWorkoutByID)
|
|
r.Put("/", h.UserWorkoutHandler().UpdateWorkout)
|
|
r.Delete("/", h.UserWorkoutHandler().DeleteWorkout)
|
|
})
|
|
})
|
|
|
|
// Маршруты для достижений (achievements)
|
|
r.Route("/achievements", func(r chi.Router) {
|
|
// Создание нового достижения
|
|
r.Post("/", h.UserAchievementHandler().CreateAchievement)
|
|
|
|
// Получение всех достижений пользователя
|
|
r.Get("/", h.UserAchievementHandler().GetUserAchievements)
|
|
|
|
// Получение сводки по достижениям
|
|
r.Get("/summary", h.UserAchievementHandler().GetUserAchievementsSummary)
|
|
|
|
// Получение последних достижений (с опциональным лимитом)
|
|
r.Get("/recent", h.UserAchievementHandler().GetRecentAchievements)
|
|
|
|
// Получение достижений по типу
|
|
r.Get("/type/{type}", h.UserAchievementHandler().GetAchievementsByType)
|
|
|
|
// Операции с конкретным достижением
|
|
r.Route("/{id}", func(r chi.Router) {
|
|
// Получение достижения по ID
|
|
r.Get("/", h.UserAchievementHandler().GetAchievementByID)
|
|
|
|
// Обновление достижения
|
|
r.Put("/", h.UserAchievementHandler().UpdateAchievement)
|
|
|
|
// Удаление достижения
|
|
r.Delete("/", h.UserAchievementHandler().DeleteAchievement)
|
|
|
|
// Подтверждение достижения
|
|
r.Patch("/verify", h.UserAchievementHandler().VerifyAchievement)
|
|
})
|
|
})
|
|
// Personal Best routes
|
|
r.Route("/personal-bests", func(r chi.Router) {
|
|
// CRUD operations
|
|
r.Post("/", h.PersonalBestHandler().CreatePersonalBest)
|
|
r.Get("/", h.PersonalBestHandler().GetUserPersonalBests)
|
|
r.Get("/recent", h.PersonalBestHandler().GetRecentPersonalBests)
|
|
r.Get("/summary", h.PersonalBestHandler().GetPersonalBestsSummary)
|
|
r.Post("/calculate-pace", h.PersonalBestHandler().CalculatePace)
|
|
|
|
// Distance-specific routes
|
|
r.Route("/distance/{distanceType}", func(r chi.Router) {
|
|
r.Get("/", h.PersonalBestHandler().GetPersonalBestsByDistance)
|
|
r.Get("/best", h.PersonalBestHandler().GetBestByDistance)
|
|
})
|
|
|
|
// Individual personal best routes
|
|
r.Route("/{id}", func(r chi.Router) {
|
|
r.Get("/", h.PersonalBestHandler().GetPersonalBest)
|
|
r.Put("/", h.PersonalBestHandler().UpdatePersonalBest)
|
|
r.Delete("/", h.PersonalBestHandler().DeletePersonalBest)
|
|
r.Patch("/verify", h.PersonalBestHandler().VerifyPersonalBest)
|
|
})
|
|
})
|
|
|
|
// Маршруты для тренировочных планов (Training Plans)
|
|
r.Route("/training-plans", func(r chi.Router) {
|
|
// Создание нового тренировочного плана
|
|
r.Post("/", h.TrainingPlanHandler().CreateTrainingPlan)
|
|
|
|
// Получение всех тренировочных планов пользователя
|
|
r.Get("/", h.TrainingPlanHandler().GetTrainingPlans)
|
|
|
|
// Получение активного тренировочного плана
|
|
r.Get("/active", h.TrainingPlanHandler().GetActiveTrainingPlan)
|
|
|
|
// Обновление текущей недели плана
|
|
r.Patch("/current-week", h.TrainingPlanHandler().UpdateCurrentWeek)
|
|
|
|
// Операции с конкретным тренировочным планом
|
|
r.Route("/{id}", func(r chi.Router) {
|
|
// Получение тренировочного плана по ID
|
|
r.Get("/", h.TrainingPlanHandler().GetTrainingPlanByID)
|
|
|
|
// Обновление тренировочного плана
|
|
r.Put("/", h.TrainingPlanHandler().UpdateTrainingPlan)
|
|
|
|
// Удаление тренировочного плана
|
|
r.Delete("/", h.TrainingPlanHandler().DeleteTrainingPlan)
|
|
|
|
// Пометить план как завершенный
|
|
r.Patch("/complete", h.TrainingPlanHandler().MarkTrainingPlanAsCompleted)
|
|
})
|
|
})
|
|
|
|
})
|
|
|
|
r.Route("/news", func(r chi.Router) {
|
|
|
|
// Публичные маршруты
|
|
r.Get("/", h.NewsHandler().GetNews)
|
|
r.Get("/{id}", h.NewsHandler().GetNewsByID)
|
|
r.Get("/{id}/comments", h.NewsHandler().GetComments)
|
|
r.Get("/check", h.HealthHandler().Check)
|
|
|
|
// Защищенные маршруты
|
|
r.Group(func(r chi.Router) {
|
|
r.Use(middleware.AuthMiddleware(jwtService, userRepo))
|
|
r.Use(middleware.RequireAuth)
|
|
|
|
// News EndPoints
|
|
r.Post("/", h.NewsHandler().CreateNews)
|
|
r.Put("/{id}", h.NewsHandler().UpdateNews)
|
|
r.Delete("/{id}", h.NewsHandler().DeleteNews)
|
|
r.Get("/my/news", h.NewsHandler().GetUserNews)
|
|
|
|
r.Post("/{id}/comments", h.NewsHandler().CreateComment)
|
|
r.Delete("/comments/{commentId}", h.NewsHandler().DeleteComment)
|
|
|
|
r.Get("/check", h.HealthHandler().Check)
|
|
})
|
|
})
|
|
|
|
// Маршруты для отзывов
|
|
r.Route("/reviews", func(r chi.Router) {
|
|
// Публичные маршруты
|
|
r.Get("/", h.ReviewHandler().GetReviews)
|
|
r.Get("/stats", h.ReviewHandler().GetReviewsStats)
|
|
r.Get("/{id}", h.ReviewHandler().GetReviewByID)
|
|
|
|
// Защищенные маршруты
|
|
r.Group(func(r chi.Router) {
|
|
r.Use(middleware.AuthMiddleware(jwtService, userRepo))
|
|
r.Use(middleware.RequireAuth)
|
|
|
|
r.Post("/", h.ReviewHandler().CreateReview)
|
|
r.Get("/my", h.ReviewHandler().GetMyReviews)
|
|
r.Put("/{id}", h.ReviewHandler().UpdateReview)
|
|
r.Delete("/{id}", h.ReviewHandler().DeleteReview)
|
|
})
|
|
})
|
|
|
|
// Events
|
|
r.Route("/events", func(r chi.Router) {
|
|
|
|
// Публичные маршруты
|
|
r.Get("/", h.EventHandler().GetAllEvents)
|
|
r.Get("/upcoming", h.EventHandler().GetUpcomingEvents)
|
|
r.Get("/type/{type}", h.EventHandler().GetEventsByType)
|
|
r.Get("/{id}", h.EventHandler().GetEvent)
|
|
r.Get("/{eventId}/availability", h.EventRegistrationHandler().CheckEventAvailability)
|
|
|
|
// Защищенные маршруты (требуют аутентификации)
|
|
r.Group(func(r chi.Router) {
|
|
r.Use(middleware.AuthMiddleware(jwtService, userRepo))
|
|
r.Use(middleware.RequireAuth)
|
|
|
|
// Регистрации пользователя
|
|
r.Post("/register", h.EventRegistrationHandler().RegisterForEvent)
|
|
r.Get("/my/registrations", h.EventRegistrationHandler().GetUserRegistrations)
|
|
r.Delete("/registrations/{id}", h.EventRegistrationHandler().CancelRegistration)
|
|
r.Get("/registrations/{id}", h.EventRegistrationHandler().GetRegistration)
|
|
})
|
|
|
|
// Админские маршруты
|
|
r.Group(func(r chi.Router) {
|
|
r.Use(middleware.AuthMiddleware(jwtService, userRepo))
|
|
r.Use(middleware.RequireAuth)
|
|
r.Use(middleware.AdminMiddleware)
|
|
|
|
// Управление событиями
|
|
r.Post("/", h.EventHandler().CreateEvent)
|
|
r.Put("/{id}", h.EventHandler().UpdateEvent)
|
|
r.Delete("/{id}", h.EventHandler().DeleteEvent)
|
|
r.Patch("/{id}/registration-status", h.EventHandler().ToggleRegistrationStatus)
|
|
|
|
// Управление регистрациями
|
|
r.Get("/{eventId}/registrations", h.EventRegistrationHandler().GetEventRegistrations)
|
|
r.Patch("/registrations/{id}/status", h.EventRegistrationHandler().UpdateRegistrationStatus)
|
|
r.Patch("/registrations/{id}/result-time", h.EventRegistrationHandler().UpdateResultTime)
|
|
})
|
|
})
|
|
|
|
})
|
|
|
|
// Логируем все зарегистрированные маршруты
|
|
routeLogger := logger.NewRouteLogger(baseLogger)
|
|
routeLogger.LogRoutes(r)
|
|
|
|
return r
|
|
}
|