package main import ( "database/sql" "fmt" "log" "net/http" _ "github.com/lib/pq" "github.com/gorilla/mux" "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) signupTemplateRepo := repository.NewSignupTemplateRepository(db) agencyTemplateRepo := repository.NewAgencyTemplateRepository(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) signupTemplateHandler := handlers.NewSignupTemplateHandler(signupTemplateRepo, userRepo, tenantRepo, agencyService) agencyTemplateHandler := handlers.NewAgencyTemplateHandler(agencyTemplateRepo, agencyService, userRepo, tenantRepo) // Initialize upload handler uploadHandler, err := handlers.NewUploadHandler(cfg) if err != nil { log.Fatalf("❌ Erro ao inicializar upload handler: %v", err) } // Create middleware chain tenantDetector := middleware.TenantDetector(tenantRepo) corsMiddleware := middleware.CORS(cfg) securityMiddleware := middleware.SecurityHeaders rateLimitMiddleware := middleware.RateLimit(cfg) authMiddleware := middleware.Auth(cfg) // Setup routes router := mux.NewRouter() // Serve static files (uploads) fs := http.FileServer(http.Dir("./uploads")) router.PathPrefix("/uploads/").Handler(http.StripPrefix("/uploads", fs)) // ==================== PUBLIC ROUTES ==================== // Health check router.HandleFunc("/health", healthHandler.Check) router.HandleFunc("/api/health", healthHandler.Check) // Auth router.HandleFunc("/api/auth/login", authHandler.Login) router.HandleFunc("/api/auth/register", agencyHandler.PublicRegister).Methods("POST") // Public agency template registration (for creating new agencies) router.HandleFunc("/api/agency-templates", agencyTemplateHandler.GetTemplateBySlug).Methods("GET") router.HandleFunc("/api/agency-signup/register", agencyTemplateHandler.PublicRegisterAgency).Methods("POST") // Public client signup via templates router.HandleFunc("/api/signup-templates/slug/{slug}", signupTemplateHandler.GetTemplateBySlug).Methods("GET") router.HandleFunc("/api/signup/register", signupTemplateHandler.PublicRegister).Methods("POST") // File upload (public for signup, will also work with auth) router.HandleFunc("/api/upload", uploadHandler.Upload).Methods("POST") // Tenant check (public) router.HandleFunc("/api/tenant/check", tenantHandler.CheckExists).Methods("GET") // Hash generator (dev only - remove in production) router.HandleFunc("/api/hash", handlers.GenerateHash).Methods("POST") // ==================== PROTECTED ROUTES ==================== // Auth (protected) router.Handle("/api/auth/change-password", authMiddleware(http.HandlerFunc(authHandler.ChangePassword))).Methods("POST") // SUPERADMIN: Agency management router.HandleFunc("/api/admin/agencies/register", agencyHandler.RegisterAgency).Methods("POST") router.HandleFunc("/api/admin/agencies", tenantHandler.ListAll).Methods("GET") router.HandleFunc("/api/admin/agencies/{id}", agencyHandler.HandleAgency).Methods("GET", "PATCH", "DELETE") // SUPERADMIN: Agency template management router.Handle("/api/admin/agency-templates", authMiddleware(http.HandlerFunc(agencyTemplateHandler.ListTemplates))).Methods("GET") router.Handle("/api/admin/agency-templates", authMiddleware(http.HandlerFunc(agencyTemplateHandler.CreateTemplate))).Methods("POST") // SUPERADMIN: Client signup template management router.Handle("/api/admin/signup-templates", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { signupTemplateHandler.ListTemplates(w, r) } else if r.Method == http.MethodPost { signupTemplateHandler.CreateTemplate(w, r) } }))).Methods("GET", "POST") router.Handle("/api/admin/signup-templates/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: signupTemplateHandler.GetTemplateByID(w, r) case http.MethodPut, http.MethodPatch: signupTemplateHandler.UpdateTemplate(w, r) case http.MethodDelete: signupTemplateHandler.DeleteTemplate(w, r) } }))).Methods("GET", "PUT", "PATCH", "DELETE") // ADMIN_AGENCIA: Client registration router.Handle("/api/agencies/clients/register", authMiddleware(http.HandlerFunc(agencyHandler.RegisterClient))).Methods("POST") // Agency profile routes (protected) router.Handle("/api/agency/profile", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: agencyProfileHandler.GetProfile(w, r) case http.MethodPut, http.MethodPatch: agencyProfileHandler.UpdateProfile(w, r) } }))).Methods("GET", "PUT", "PATCH") // Agency logo upload (protected) router.Handle("/api/agency/logo", authMiddleware(http.HandlerFunc(agencyProfileHandler.UploadLogo))).Methods("POST") // Company routes (protected) router.Handle("/api/companies", authMiddleware(http.HandlerFunc(companyHandler.List))).Methods("GET") router.Handle("/api/companies/create", authMiddleware(http.HandlerFunc(companyHandler.Create))).Methods("POST") // Apply global middlewares: tenant -> cors -> security -> rateLimit -> router handler := tenantDetector(corsMiddleware(securityMiddleware(rateLimitMiddleware(router)))) // 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) } }