package api import ( "net/http" "git.kirlllll.ru/volontery/backend/internal/api/handlers" "git.kirlllll.ru/volontery/backend/internal/api/middleware" "git.kirlllll.ru/volontery/backend/internal/config" "git.kirlllll.ru/volontery/backend/internal/pkg/jwt" "git.kirlllll.ru/volontery/backend/internal/service" "github.com/go-chi/chi/v5" chiMiddleware "github.com/go-chi/chi/v5/middleware" ) // Server представляет HTTP сервер type Server struct { router *chi.Mux authHandler *handlers.AuthHandler adminHandler *handlers.AdminHandler userHandler *handlers.UserHandler requestHandler *handlers.RequestHandler jwtManager *jwt.Manager userService *service.UserService config *config.Config } // NewServer создает новый HTTP сервер func NewServer( cfg *config.Config, authService *service.AuthService, userService *service.UserService, requestService *service.RequestService, jwtManager *jwt.Manager, ) *Server { s := &Server{ router: chi.NewRouter(), authHandler: handlers.NewAuthHandler(authService), adminHandler: handlers.NewAdminHandler(userService), userHandler: handlers.NewUserHandler(userService), requestHandler: handlers.NewRequestHandler(requestService), jwtManager: jwtManager, userService: userService, config: cfg, } s.setupRoutes() return s } // setupRoutes настраивает маршруты func (s *Server) setupRoutes() { r := s.router // Глобальные middleware r.Use(chiMiddleware.RequestID) r.Use(chiMiddleware.RealIP) r.Use(middleware.Logger) r.Use(middleware.Recovery) r.Use(middleware.CORS(s.config.CORSAllowedOrigins)) // Health check r.Get("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) }) // API v1 r.Route("/api/v1", func(r chi.Router) { // Публичные маршруты (без аутентификации) r.Group(func(r chi.Router) { r.Post("/auth/register", s.authHandler.Register) r.Post("/auth/login", s.authHandler.Login) r.Post("/auth/refresh", s.authHandler.RefreshToken) // Типы заявок (публичные) r.Get("/request-types", s.requestHandler.ListRequestTypes) }) // Защищенные маршруты (требуют аутентификации) r.Group(func(r chi.Router) { r.Use(middleware.AuthMiddleware(s.jwtManager)) // Auth r.Get("/auth/me", s.authHandler.Me) r.Post("/auth/logout", s.authHandler.Logout) // Users r.Get("/users/me", s.userHandler.GetMyProfile) r.Patch("/users/me", s.userHandler.UpdateProfile) r.Post("/users/me/location", s.userHandler.UpdateLocation) r.Post("/users/me/verify-email", s.userHandler.VerifyEmail) r.Get("/users/me/roles", s.userHandler.GetMyRoles) r.Get("/users/me/permissions", s.userHandler.GetMyPermissions) r.Get("/users/{id}", s.userHandler.GetProfile) // Requests r.Post("/requests", s.requestHandler.CreateRequest) r.Get("/requests/my", s.requestHandler.GetMyRequests) r.Get("/requests/nearby", s.requestHandler.FindNearbyRequests) r.Get("/requests/bounds", s.requestHandler.FindRequestsInBounds) r.Get("/requests/{id}", s.requestHandler.GetRequest) r.Post("/requests/{id}/responses", s.requestHandler.CreateVolunteerResponse) r.Get("/requests/{id}/responses", s.requestHandler.GetRequestResponses) r.Post("/requests/{id}/responses/{response_id}/accept", s.requestHandler.AcceptVolunteerResponseHandler) r.Post("/requests/{id}/complete", s.requestHandler.CompleteRequestWithRatingHandler) }) // Маршруты для модераторов (требуют роль moderator или admin) r.Group(func(r chi.Router) { r.Use(middleware.AuthMiddleware(s.jwtManager)) r.Use(middleware.RequireAnyRole(s.userService, "moderator", "admin")) // Модерация заявок r.Get("/moderation/requests/pending", s.requestHandler.GetPendingModerationRequests) r.Get("/moderation/requests/my", s.requestHandler.GetMyModeratedRequests) r.Post("/moderation/requests/{id}/approve", s.requestHandler.ApproveRequest) r.Post("/moderation/requests/{id}/reject", s.requestHandler.RejectRequest) r.Post("/moderation/requests/{id}/moderate", s.requestHandler.ModerateRequestProcedure) }) // Маршруты для администраторов (требуют роль admin) r.Group(func(r chi.Router) { r.Use(middleware.AuthMiddleware(s.jwtManager)) r.Use(middleware.RequireRole(s.userService, "admin")) // Админские маршруты можно добавить позже r.Get("/admin/users/{id}/roles/{role_id}", s.adminHandler.AssignRole) }) }) } // ServeHTTP реализует интерфейс http.Handler func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.router.ServeHTTP(w, r) } // Router возвращает роутер Chi func (s *Server) Router() *chi.Mux { return s.router }