package router import ( "net/http" "os" "time" "github.com/rede5/gohorsejobs/backend/internal/api/middleware" "github.com/rede5/gohorsejobs/backend/internal/database" "github.com/rede5/gohorsejobs/backend/internal/handlers" "github.com/rede5/gohorsejobs/backend/internal/infrastructure/persistence/postgres" "github.com/rede5/gohorsejobs/backend/internal/services" // Core Imports apiHandlers "github.com/rede5/gohorsejobs/backend/internal/api/handlers" authUC "github.com/rede5/gohorsejobs/backend/internal/core/usecases/auth" tenantUC "github.com/rede5/gohorsejobs/backend/internal/core/usecases/tenant" userUC "github.com/rede5/gohorsejobs/backend/internal/core/usecases/user" authInfra "github.com/rede5/gohorsejobs/backend/internal/infrastructure/auth" legacyMiddleware "github.com/rede5/gohorsejobs/backend/internal/middleware" _ "github.com/rede5/gohorsejobs/backend/docs" // Import generated docs httpSwagger "github.com/swaggo/http-swagger/v2" ) func NewRouter() http.Handler { mux := http.NewServeMux() // Initialize Services jobService := services.NewJobService(database.DB) applicationService := services.NewApplicationService(database.DB) // --- CORE ARCHITECTURE INITIALIZATION --- // Infrastructure // Infrastructure, userRepo := postgres.NewUserRepository(database.DB) companyRepo := postgres.NewCompanyRepository(database.DB) jwtSecret := os.Getenv("JWT_SECRET") if jwtSecret == "" { // Fallback for dev, but really should be in env jwtSecret = "default-dev-secret-do-not-use-in-prod" } authService := authInfra.NewJWTService(jwtSecret, "todai-jobs") // UseCases loginUC := authUC.NewLoginUseCase(userRepo, authService) createCompanyUC := tenantUC.NewCreateCompanyUseCase(companyRepo, userRepo, authService) createUserUC := userUC.NewCreateUserUseCase(userRepo, authService) listUsersUC := userUC.NewListUsersUseCase(userRepo) deleteUserUC := userUC.NewDeleteUserUseCase(userRepo) // Handlers & Middleware coreHandlers := apiHandlers.NewCoreHandlers(loginUC, createCompanyUC, createUserUC, listUsersUC, deleteUserUC) authMiddleware := middleware.NewMiddleware(authService) // Initialize Legacy Handlers jobHandler := handlers.NewJobHandler(jobService) applicationHandler := handlers.NewApplicationHandler(applicationService) mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) }) // --- CORE ROUTES --- // Public mux.HandleFunc("POST /api/v1/auth/login", coreHandlers.Login) mux.HandleFunc("POST /api/v1/companies", coreHandlers.CreateCompany) // Protected // Note: In Go 1.22+, we can wrap specific patterns. Or we can just wrap the handler. // For simplicity, we wrap the handler function. mux.Handle("POST /api/v1/users", authMiddleware.HeaderAuthGuard(http.HandlerFunc(coreHandlers.CreateUser))) mux.Handle("GET /api/v1/users", authMiddleware.HeaderAuthGuard(http.HandlerFunc(coreHandlers.ListUsers))) mux.Handle("DELETE /api/v1/users/{id}", authMiddleware.HeaderAuthGuard(http.HandlerFunc(coreHandlers.DeleteUser))) // Job Routes mux.HandleFunc("GET /jobs", jobHandler.GetJobs) mux.HandleFunc("POST /jobs", jobHandler.CreateJob) mux.HandleFunc("GET /jobs/{id}", jobHandler.GetJobByID) mux.HandleFunc("PUT /jobs/{id}", jobHandler.UpdateJob) mux.HandleFunc("DELETE /jobs/{id}", jobHandler.DeleteJob) // Application Routes mux.HandleFunc("POST /applications", applicationHandler.CreateApplication) mux.HandleFunc("GET /applications", applicationHandler.GetApplications) mux.HandleFunc("GET /applications/{id}", applicationHandler.GetApplicationByID) mux.HandleFunc("PUT /applications/{id}/status", applicationHandler.UpdateApplicationStatus) // Swagger Route mux.HandleFunc("/swagger/", httpSwagger.WrapHandler) // Apply middleware chain: Security Headers -> Rate Limiting -> CORS -> Router // Order matters: outer middleware runs first var handler http.Handler = mux handler = middleware.CORSMiddleware(handler) handler = legacyMiddleware.RateLimitMiddleware(100, time.Minute)(handler) // 100 req/min per IP handler = legacyMiddleware.SecurityHeadersMiddleware(handler) return handler }