diff --git a/backend/internal/api/handlers/admin_handlers.go b/backend/internal/api/handlers/admin_handlers.go index 2444858..dcf397b 100644 --- a/backend/internal/api/handlers/admin_handlers.go +++ b/backend/internal/api/handlers/admin_handlers.go @@ -11,10 +11,11 @@ import ( ) type AdminHandlers struct { - adminService *services.AdminService - auditService *services.AuditService - jobService *services.JobService - cloudflareService *services.CloudflareService + adminService *services.AdminService + auditService *services.AuditService + jobService *services.JobService + cloudflareService *services.CloudflareService + notificationService *services.NotificationService } type RoleAccess struct { @@ -42,13 +43,21 @@ type UpdateTagRequest struct { Active *bool `json:"active,omitempty"` } -func NewAdminHandlers(adminService *services.AdminService, auditService *services.AuditService, jobService *services.JobService, cloudflareService *services.CloudflareService) *AdminHandlers { +func NewAdminHandlers( + adminService *services.AdminService, + auditService *services.AuditService, + jobService *services.JobService, + cloudflareService *services.CloudflareService, + notificationService *services.NotificationService, +) *AdminHandlers { return &AdminHandlers{ - adminService: adminService, - auditService: auditService, - jobService: jobService, - cloudflareService: cloudflareService, + adminService: adminService, + auditService: auditService, + jobService: jobService, + cloudflareService: cloudflareService, + notificationService: notificationService, } +} } } func (h *AdminHandlers) ListAccessRoles(w http.ResponseWriter, r *http.Request) { @@ -158,6 +167,25 @@ func (h *AdminHandlers) UpdateCompanyStatus(w http.ResponseWriter, r *http.Reque return } + // Notify Company Owner + if req.Verified != nil { + statusText := "rejeitada" + if *req.Verified { + statusText = "aprovada" + } + + // Find owner of the company to notify + owner, err := h.adminService.GetCompanyOwner(r.Context(), id) + if err == nil && owner != nil { + title := "Status da Empresa Atualizado" + msg := "Sua empresa '" + company.Name + "' foi " + statusText + " pela moderação." + link := "/dashboard/profile" + + // This call now automatically publishes to LavinMQ for async Push/Email + _ = h.notificationService.CreateNotification(r.Context(), owner.ID, "system", title, msg, &link) + } + } + w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(company) } diff --git a/backend/internal/services/admin_service.go b/backend/internal/services/admin_service.go index b4c2192..1f3081e 100644 --- a/backend/internal/services/admin_service.go +++ b/backend/internal/services/admin_service.go @@ -572,6 +572,21 @@ func isActiveApplicationStatus(status string) bool { } } +func (s *AdminService) GetCompanyOwner(ctx context.Context, companyID string) (*dto.User, error) { + query := ` + SELECT id, email, full_name + FROM users + WHERE tenant_id = $1 AND role IN ('admin', 'company') + LIMIT 1 + ` + var u dto.User + err := s.DB.QueryRowContext(ctx, query, companyID).Scan(&u.ID, &u.Email, &u.Name) + if err != nil { + return nil, err + } + return &u, nil +} + func (s *AdminService) GetCompanyByID(ctx context.Context, id string) (*models.Company, error) { query := ` SELECT id, name, slug, type, document, address, region_id, city_id, phone, email, website, logo_url, description, active, verified, created_at, updated_at