573 lines
23 KiB
Go
573 lines
23 KiB
Go
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 client_encoding=UTF8",
|
|
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)
|
|
planRepo := repository.NewPlanRepository(db)
|
|
subscriptionRepo := repository.NewSubscriptionRepository(db)
|
|
crmRepo := repository.NewCRMRepository(db)
|
|
solutionRepo := repository.NewSolutionRepository(db)
|
|
erpRepo := repository.NewERPRepository(db)
|
|
docRepo := repository.NewDocumentRepository(db)
|
|
|
|
// Initialize services
|
|
authService := service.NewAuthService(userRepo, tenantRepo, crmRepo, cfg)
|
|
agencyService := service.NewAgencyService(userRepo, tenantRepo, cfg, db)
|
|
tenantService := service.NewTenantService(tenantRepo, db)
|
|
companyService := service.NewCompanyService(companyRepo)
|
|
planService := service.NewPlanService(planRepo, subscriptionRepo)
|
|
|
|
// Initialize handlers
|
|
healthHandler := handlers.NewHealthHandler()
|
|
authHandler := handlers.NewAuthHandler(authService)
|
|
agencyProfileHandler := handlers.NewAgencyHandler(tenantRepo, cfg)
|
|
agencyHandler := handlers.NewAgencyRegistrationHandler(agencyService, cfg)
|
|
collaboratorHandler := handlers.NewCollaboratorHandler(userRepo, agencyService)
|
|
tenantHandler := handlers.NewTenantHandler(tenantService)
|
|
companyHandler := handlers.NewCompanyHandler(companyService)
|
|
planHandler := handlers.NewPlanHandler(planService)
|
|
crmHandler := handlers.NewCRMHandler(crmRepo)
|
|
solutionHandler := handlers.NewSolutionHandler(solutionRepo)
|
|
signupTemplateHandler := handlers.NewSignupTemplateHandler(signupTemplateRepo, userRepo, tenantRepo, agencyService)
|
|
agencyTemplateHandler := handlers.NewAgencyTemplateHandler(agencyTemplateRepo, agencyService, userRepo, tenantRepo)
|
|
filesHandler := handlers.NewFilesHandler(cfg)
|
|
customerPortalHandler := handlers.NewCustomerPortalHandler(crmRepo, authService, cfg)
|
|
erpHandler := handlers.NewERPHandler(erpRepo)
|
|
docHandler := handlers.NewDocumentHandler(docRepo)
|
|
|
|
// Initialize upload handler
|
|
uploadHandler, err := handlers.NewUploadHandler(cfg)
|
|
if err != nil {
|
|
log.Fatalf("❌ Erro ao inicializar upload handler: %v", err)
|
|
}
|
|
|
|
// Initialize backup handler
|
|
backupHandler := handlers.NewBackupHandler()
|
|
|
|
// 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.UnifiedLogin) // Nova rota unificada
|
|
router.HandleFunc("/api/auth/login/legacy", authHandler.Login) // Antiga rota (deprecada)
|
|
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")
|
|
|
|
// Public plans (for signup flow)
|
|
router.HandleFunc("/api/plans", planHandler.ListActivePlans).Methods("GET")
|
|
router.HandleFunc("/api/plans/{id}", planHandler.GetActivePlan).Methods("GET")
|
|
|
|
// 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")
|
|
router.HandleFunc("/api/tenant/config", tenantHandler.GetPublicConfig).Methods("GET")
|
|
router.HandleFunc("/api/tenants/{id}/profile", tenantHandler.GetProfile).Methods("GET")
|
|
|
|
// Tenant branding (protected - used by both agency and customer portal)
|
|
router.Handle("/api/tenant/branding", middleware.RequireAnyAuthenticated(cfg)(http.HandlerFunc(tenantHandler.GetBranding))).Methods("GET")
|
|
|
|
// Public customer registration (for agency portal signup)
|
|
router.HandleFunc("/api/public/customers/register", crmHandler.PublicRegisterCustomer).Methods("POST")
|
|
|
|
// 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: Backup & Restore
|
|
router.Handle("/api/superadmin/backups", authMiddleware(http.HandlerFunc(backupHandler.ListBackups))).Methods("GET")
|
|
router.Handle("/api/superadmin/backup/create", authMiddleware(http.HandlerFunc(backupHandler.CreateBackup))).Methods("POST")
|
|
router.Handle("/api/superadmin/backup/restore", authMiddleware(http.HandlerFunc(backupHandler.RestoreBackup))).Methods("POST")
|
|
router.Handle("/api/superadmin/backup/download/{filename}", authMiddleware(http.HandlerFunc(backupHandler.DownloadBackup))).Methods("GET")
|
|
|
|
// 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")
|
|
|
|
// SUPERADMIN: Plans management
|
|
planHandler.RegisterRoutes(router)
|
|
|
|
// SUPERADMIN: Solutions management
|
|
router.Handle("/api/admin/solutions", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
solutionHandler.GetAllSolutions(w, r)
|
|
case http.MethodPost:
|
|
solutionHandler.CreateSolution(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/admin/solutions/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
solutionHandler.GetSolution(w, r)
|
|
case http.MethodPut, http.MethodPatch:
|
|
solutionHandler.UpdateSolution(w, r)
|
|
case http.MethodDelete:
|
|
solutionHandler.DeleteSolution(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT", "PATCH", "DELETE")
|
|
|
|
// SUPERADMIN: Plan <-> Solutions
|
|
router.Handle("/api/admin/plans/{plan_id}/solutions", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
solutionHandler.GetPlanSolutions(w, r)
|
|
case http.MethodPut:
|
|
solutionHandler.SetPlanSolutions(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT")
|
|
|
|
// 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")
|
|
|
|
// File serving route (public - serves files from MinIO through API)
|
|
router.PathPrefix("/api/files/{bucket}/").HandlerFunc(filesHandler.ServeFile).Methods("GET")
|
|
|
|
// 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")
|
|
|
|
// ==================== CRM ROUTES (TENANT) ====================
|
|
|
|
// Tenant solutions (which solutions the tenant has access to)
|
|
router.Handle("/api/tenant/solutions", authMiddleware(http.HandlerFunc(solutionHandler.GetTenantSolutions))).Methods("GET")
|
|
|
|
// Dashboard
|
|
router.Handle("/api/crm/dashboard", authMiddleware(http.HandlerFunc(crmHandler.GetDashboard))).Methods("GET")
|
|
|
|
// Customers
|
|
router.Handle("/api/crm/customers", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetCustomers(w, r)
|
|
case http.MethodPost:
|
|
crmHandler.CreateCustomer(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/crm/customers/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetCustomer(w, r)
|
|
case http.MethodPut, http.MethodPatch:
|
|
crmHandler.UpdateCustomer(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.DeleteCustomer(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT", "PATCH", "DELETE")
|
|
|
|
// Lists
|
|
router.Handle("/api/crm/lists", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetLists(w, r)
|
|
case http.MethodPost:
|
|
crmHandler.CreateList(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/crm/lists/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetList(w, r)
|
|
case http.MethodPut, http.MethodPatch:
|
|
crmHandler.UpdateList(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.DeleteList(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT", "PATCH", "DELETE")
|
|
|
|
router.Handle("/api/crm/lists/{id}/leads", authMiddleware(http.HandlerFunc(crmHandler.GetLeadsByList))).Methods("GET")
|
|
|
|
// Customer <-> List relationship
|
|
router.Handle("/api/crm/customers/{customer_id}/lists/{list_id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPost:
|
|
crmHandler.AddCustomerToList(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.RemoveCustomerFromList(w, r)
|
|
}
|
|
}))).Methods("POST", "DELETE")
|
|
|
|
// Leads
|
|
router.Handle("/api/crm/leads", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetLeads(w, r)
|
|
case http.MethodPost:
|
|
crmHandler.CreateLead(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/crm/leads/export", authMiddleware(http.HandlerFunc(crmHandler.ExportLeads))).Methods("GET")
|
|
router.Handle("/api/crm/leads/import", authMiddleware(http.HandlerFunc(crmHandler.ImportLeads))).Methods("POST")
|
|
router.Handle("/api/crm/leads/{leadId}/stage", authMiddleware(http.HandlerFunc(crmHandler.UpdateLeadStage))).Methods("PUT")
|
|
|
|
router.Handle("/api/crm/leads/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetLead(w, r)
|
|
case http.MethodPut, http.MethodPatch:
|
|
crmHandler.UpdateLead(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.DeleteLead(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT", "PATCH", "DELETE")
|
|
|
|
// Funnels & Stages
|
|
router.Handle("/api/crm/funnels", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.ListFunnels(w, r)
|
|
case http.MethodPost:
|
|
crmHandler.CreateFunnel(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/crm/funnels/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.GetFunnel(w, r)
|
|
case http.MethodPut:
|
|
crmHandler.UpdateFunnel(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.DeleteFunnel(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT", "DELETE")
|
|
|
|
router.Handle("/api/crm/funnels/{funnelId}/stages", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
crmHandler.ListStages(w, r)
|
|
case http.MethodPost:
|
|
crmHandler.CreateStage(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/crm/stages/{id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPut:
|
|
crmHandler.UpdateStage(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.DeleteStage(w, r)
|
|
}
|
|
}))).Methods("PUT", "DELETE")
|
|
|
|
// Lead ingest (integrations)
|
|
router.Handle("/api/crm/leads/ingest", authMiddleware(http.HandlerFunc(crmHandler.IngestLead))).Methods("POST")
|
|
|
|
// Share tokens (generate)
|
|
router.Handle("/api/crm/customers/share-token", authMiddleware(http.HandlerFunc(crmHandler.GenerateShareToken))).Methods("POST")
|
|
|
|
// Share data (public endpoint - no auth required)
|
|
router.HandleFunc("/api/crm/share/{token}", crmHandler.GetSharedData).Methods("GET")
|
|
|
|
// ==================== CUSTOMER PORTAL ====================
|
|
// Customer portal login (public endpoint)
|
|
router.HandleFunc("/api/portal/login", customerPortalHandler.Login).Methods("POST")
|
|
|
|
// Customer portal dashboard (requires customer auth)
|
|
router.Handle("/api/portal/dashboard", middleware.RequireCustomer(cfg)(http.HandlerFunc(customerPortalHandler.GetPortalDashboard))).Methods("GET")
|
|
|
|
// Customer portal leads (requires customer auth)
|
|
router.Handle("/api/portal/leads", middleware.RequireCustomer(cfg)(http.HandlerFunc(customerPortalHandler.GetPortalLeads))).Methods("GET")
|
|
|
|
// Customer portal lists (requires customer auth)
|
|
router.Handle("/api/portal/lists", middleware.RequireCustomer(cfg)(http.HandlerFunc(customerPortalHandler.GetPortalLists))).Methods("GET")
|
|
|
|
// Customer portal profile (requires customer auth)
|
|
router.Handle("/api/portal/profile", middleware.RequireCustomer(cfg)(http.HandlerFunc(customerPortalHandler.GetPortalProfile))).Methods("GET")
|
|
|
|
// Customer portal change password (requires customer auth)
|
|
router.Handle("/api/portal/change-password", middleware.RequireCustomer(cfg)(http.HandlerFunc(customerPortalHandler.ChangePassword))).Methods("POST")
|
|
|
|
// Customer portal logo upload (requires customer auth)
|
|
router.Handle("/api/portal/logo", middleware.RequireCustomer(cfg)(http.HandlerFunc(customerPortalHandler.UploadLogo))).Methods("POST")
|
|
|
|
// ==================== AGENCY COLLABORATORS ====================
|
|
// List collaborators (requires agency auth, owner only)
|
|
router.Handle("/api/agency/collaborators", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(collaboratorHandler.ListCollaborators))).Methods("GET")
|
|
|
|
// Invite collaborator (requires agency auth, owner only)
|
|
router.Handle("/api/agency/collaborators/invite", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(collaboratorHandler.InviteCollaborator))).Methods("POST")
|
|
|
|
// Remove collaborator (requires agency auth, owner only)
|
|
router.Handle("/api/agency/collaborators/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(collaboratorHandler.RemoveCollaborator))).Methods("DELETE")
|
|
|
|
// Generate customer portal access (agency staff)
|
|
router.Handle("/api/crm/customers/{id}/portal-access", authMiddleware(http.HandlerFunc(crmHandler.GenerateCustomerPortalAccess))).Methods("POST")
|
|
|
|
// Lead <-> List relationship
|
|
router.Handle("/api/crm/leads/{lead_id}/lists/{list_id}", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPost:
|
|
crmHandler.AddLeadToList(w, r)
|
|
case http.MethodDelete:
|
|
crmHandler.RemoveLeadFromList(w, r)
|
|
}
|
|
}))).Methods("POST", "DELETE")
|
|
|
|
// ==================== ERP ROUTES (TENANT) ====================
|
|
|
|
// Finance
|
|
router.Handle("/api/erp/finance/categories", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
erpHandler.GetFinancialCategories(w, r)
|
|
case http.MethodPost:
|
|
erpHandler.CreateFinancialCategory(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/erp/finance/accounts", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
erpHandler.GetBankAccounts(w, r)
|
|
case http.MethodPost:
|
|
erpHandler.CreateBankAccount(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/erp/finance/accounts/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPut:
|
|
erpHandler.UpdateBankAccount(w, r)
|
|
case http.MethodDelete:
|
|
erpHandler.DeleteBankAccount(w, r)
|
|
}
|
|
}))).Methods("PUT", "DELETE")
|
|
|
|
router.Handle("/api/erp/finance/transactions", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
erpHandler.GetTransactions(w, r)
|
|
case http.MethodPost:
|
|
erpHandler.CreateTransaction(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/erp/finance/transactions/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPut:
|
|
erpHandler.UpdateTransaction(w, r)
|
|
case http.MethodDelete:
|
|
erpHandler.DeleteTransaction(w, r)
|
|
}
|
|
}))).Methods("PUT", "DELETE")
|
|
|
|
// Products
|
|
router.Handle("/api/erp/products", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
erpHandler.GetProducts(w, r)
|
|
case http.MethodPost:
|
|
erpHandler.CreateProduct(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/erp/products/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPut:
|
|
erpHandler.UpdateProduct(w, r)
|
|
case http.MethodDelete:
|
|
erpHandler.DeleteProduct(w, r)
|
|
}
|
|
}))).Methods("PUT", "DELETE")
|
|
|
|
// Orders
|
|
router.Handle("/api/erp/orders", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
erpHandler.GetOrders(w, r)
|
|
case http.MethodPost:
|
|
erpHandler.CreateOrder(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/erp/orders/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodDelete:
|
|
erpHandler.DeleteOrder(w, r)
|
|
}
|
|
}))).Methods("DELETE")
|
|
|
|
// Entities
|
|
router.Handle("/api/erp/entities", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
erpHandler.GetEntities(w, r)
|
|
case http.MethodPost:
|
|
erpHandler.CreateEntity(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/erp/entities/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodPut, http.MethodPatch:
|
|
erpHandler.UpdateEntity(w, r)
|
|
case http.MethodDelete:
|
|
erpHandler.DeleteEntity(w, r)
|
|
}
|
|
}))).Methods("PUT", "PATCH", "DELETE")
|
|
|
|
// Documents
|
|
router.Handle("/api/documents", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
docHandler.List(w, r)
|
|
case http.MethodPost:
|
|
docHandler.Create(w, r)
|
|
}
|
|
}))).Methods("GET", "POST")
|
|
|
|
router.Handle("/api/documents/{id}", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
docHandler.Get(w, r)
|
|
case http.MethodPut:
|
|
docHandler.Update(w, r)
|
|
case http.MethodDelete:
|
|
docHandler.Delete(w, r)
|
|
}
|
|
}))).Methods("GET", "PUT", "DELETE")
|
|
|
|
router.Handle("/api/documents/{id}/subpages", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(docHandler.GetSubpages))).Methods("GET")
|
|
router.Handle("/api/documents/{id}/activities", middleware.RequireAgencyUser(cfg)(http.HandlerFunc(docHandler.GetActivities))).Methods("GET")
|
|
|
|
// 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)
|
|
}
|
|
}
|