package main import ( "database/sql" "fmt" "log" "net/http" _ "github.com/lib/pq" "aggios-app/backend/internal/api/handlers" "aggios-app/backend/internal/api/middleware" "aggios-app/backend/internal/config" "aggios-app/backend/internal/repository" "aggios-app/backend/internal/service" ) func initDB(cfg *config.Config) (*sql.DB, error) { connStr := fmt.Sprintf( "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", cfg.Database.Host, cfg.Database.Port, cfg.Database.User, cfg.Database.Password, cfg.Database.Name, ) db, err := sql.Open("postgres", connStr) if err != nil { return nil, fmt.Errorf("erro ao abrir conexΓ£o: %v", err) } if err = db.Ping(); err != nil { return nil, fmt.Errorf("erro ao conectar ao banco: %v", err) } log.Println("βœ… Conectado ao PostgreSQL") return db, nil } func main() { // Load configuration cfg := config.Load() // Initialize database db, err := initDB(cfg) if err != nil { log.Fatalf("❌ Erro ao inicializar banco: %v", err) } defer db.Close() // Initialize repositories userRepo := repository.NewUserRepository(db) tenantRepo := repository.NewTenantRepository(db) companyRepo := repository.NewCompanyRepository(db) // Initialize services authService := service.NewAuthService(userRepo, tenantRepo, cfg) agencyService := service.NewAgencyService(userRepo, tenantRepo, cfg) tenantService := service.NewTenantService(tenantRepo) companyService := service.NewCompanyService(companyRepo) // Initialize handlers healthHandler := handlers.NewHealthHandler() authHandler := handlers.NewAuthHandler(authService) agencyProfileHandler := handlers.NewAgencyHandler(tenantRepo) agencyHandler := handlers.NewAgencyRegistrationHandler(agencyService, cfg) tenantHandler := handlers.NewTenantHandler(tenantService) companyHandler := handlers.NewCompanyHandler(companyService) // Create middleware chain tenantDetector := middleware.TenantDetector(tenantRepo) corsMiddleware := middleware.CORS(cfg) securityMiddleware := middleware.SecurityHeaders rateLimitMiddleware := middleware.RateLimit(cfg) authMiddleware := middleware.Auth(cfg) // Setup routes mux := http.NewServeMux() // Health check (no auth) mux.HandleFunc("/health", healthHandler.Check) mux.HandleFunc("/api/health", healthHandler.Check) // Auth routes (public with rate limiting) mux.HandleFunc("/api/auth/login", authHandler.Login) // Protected auth routes mux.Handle("/api/auth/change-password", authMiddleware(http.HandlerFunc(authHandler.ChangePassword))) // Agency management (SUPERADMIN only) mux.HandleFunc("/api/admin/agencies/register", agencyHandler.RegisterAgency) mux.HandleFunc("/api/admin/agencies", tenantHandler.ListAll) mux.HandleFunc("/api/admin/agencies/", agencyHandler.HandleAgency) mux.HandleFunc("/api/tenant/check", tenantHandler.CheckExists) // Client registration (ADMIN_AGENCIA only - requires auth) mux.Handle("/api/agencies/clients/register", authMiddleware(http.HandlerFunc(agencyHandler.RegisterClient))) // Agency profile routes (protected) mux.Handle("/api/agency/profile", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { agencyProfileHandler.GetProfile(w, r) } else if r.Method == http.MethodPut || r.Method == http.MethodPatch { agencyProfileHandler.UpdateProfile(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } }))) // Protected routes (require authentication) mux.Handle("/api/companies", authMiddleware(http.HandlerFunc(companyHandler.List))) mux.Handle("/api/companies/create", authMiddleware(http.HandlerFunc(companyHandler.Create))) // Apply global middlewares: tenant -> cors -> security -> rateLimit -> mux handler := tenantDetector(corsMiddleware(securityMiddleware(rateLimitMiddleware(mux)))) // Start server addr := fmt.Sprintf(":%s", cfg.Server.Port) log.Printf("πŸš€ Server starting on %s", addr) log.Printf("πŸ“ Health check: http://localhost:%s/health", cfg.Server.Port) log.Printf("πŸ”— API: http://localhost:%s/api/health", cfg.Server.Port) log.Printf("🏒 Register Agency (SUPERADMIN): http://localhost:%s/api/admin/agencies/register", cfg.Server.Port) log.Printf("πŸ” Login: http://localhost:%s/api/auth/login", cfg.Server.Port) if err := http.ListenAndServe(addr, handler); err != nil { log.Fatalf("❌ Server error: %v", err) } }