chore(release): snapshot 1.4.2
This commit is contained in:
470
backend/internal/api/handlers/crm.go
Normal file
470
backend/internal/api/handlers/crm.go
Normal file
@@ -0,0 +1,470 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"aggios-app/backend/internal/domain"
|
||||
"aggios-app/backend/internal/repository"
|
||||
"aggios-app/backend/internal/api/middleware"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type CRMHandler struct {
|
||||
repo *repository.CRMRepository
|
||||
}
|
||||
|
||||
func NewCRMHandler(repo *repository.CRMRepository) *CRMHandler {
|
||||
return &CRMHandler{repo: repo}
|
||||
}
|
||||
|
||||
// ==================== CUSTOMERS ====================
|
||||
|
||||
func (h *CRMHandler) CreateCustomer(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
userID, _ := r.Context().Value(middleware.UserIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var customer domain.CRMCustomer
|
||||
if err := json.NewDecoder(r.Body).Decode(&customer); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Invalid request body",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
customer.ID = uuid.New().String()
|
||||
customer.TenantID = tenantID
|
||||
customer.CreatedBy = userID
|
||||
customer.IsActive = true
|
||||
|
||||
if err := h.repo.CreateCustomer(&customer); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to create customer",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"customer": customer,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) GetCustomers(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
customers, err := h.repo.GetCustomersByTenant(tenantID)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to fetch customers",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if customers == nil {
|
||||
customers = []domain.CRMCustomer{}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"customers": customers,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) GetCustomer(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
customerID := vars["id"]
|
||||
|
||||
customer, err := h.repo.GetCustomerByID(customerID, tenantID)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Customer not found",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Buscar listas do cliente
|
||||
lists, _ := h.repo.GetCustomerLists(customerID)
|
||||
if lists == nil {
|
||||
lists = []domain.CRMList{}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"customer": customer,
|
||||
"lists": lists,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) UpdateCustomer(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
customerID := vars["id"]
|
||||
|
||||
var customer domain.CRMCustomer
|
||||
if err := json.NewDecoder(r.Body).Decode(&customer); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Invalid request body",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
customer.ID = customerID
|
||||
customer.TenantID = tenantID
|
||||
|
||||
if err := h.repo.UpdateCustomer(&customer); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to update customer",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "Customer updated successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) DeleteCustomer(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
customerID := vars["id"]
|
||||
|
||||
if err := h.repo.DeleteCustomer(customerID, tenantID); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to delete customer",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "Customer deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== LISTS ====================
|
||||
|
||||
func (h *CRMHandler) CreateList(w http.ResponseWriter, r *http.Request) {
|
||||
tenantIDVal := r.Context().Value(middleware.TenantIDKey)
|
||||
userIDVal := r.Context().Value(middleware.UserIDKey)
|
||||
|
||||
log.Printf("🔍 CreateList DEBUG: tenantID type=%T value=%v | userID type=%T value=%v",
|
||||
tenantIDVal, tenantIDVal, userIDVal, userIDVal)
|
||||
|
||||
tenantID, ok := tenantIDVal.(string)
|
||||
if !ok || tenantID == "" {
|
||||
log.Printf("❌ CreateList: Missing or invalid tenant_id")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
userID, _ := userIDVal.(string)
|
||||
|
||||
var list domain.CRMList
|
||||
if err := json.NewDecoder(r.Body).Decode(&list); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Invalid request body",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
list.ID = uuid.New().String()
|
||||
list.TenantID = tenantID
|
||||
list.CreatedBy = userID
|
||||
|
||||
if list.Color == "" {
|
||||
list.Color = "#3b82f6"
|
||||
}
|
||||
|
||||
if err := h.repo.CreateList(&list); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to create list",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"list": list,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) GetLists(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
lists, err := h.repo.GetListsByTenant(tenantID)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to fetch lists",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if lists == nil {
|
||||
lists = []domain.CRMListWithCustomers{}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"lists": lists,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) GetList(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
listID := vars["id"]
|
||||
|
||||
list, err := h.repo.GetListByID(listID, tenantID)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "List not found",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Buscar clientes da lista
|
||||
customers, _ := h.repo.GetListCustomers(listID, tenantID)
|
||||
if customers == nil {
|
||||
customers = []domain.CRMCustomer{}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"list": list,
|
||||
"customers": customers,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) UpdateList(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
listID := vars["id"]
|
||||
|
||||
var list domain.CRMList
|
||||
if err := json.NewDecoder(r.Body).Decode(&list); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Invalid request body",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
list.ID = listID
|
||||
list.TenantID = tenantID
|
||||
|
||||
if err := h.repo.UpdateList(&list); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to update list",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "List updated successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) DeleteList(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
||||
|
||||
if tenantID == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Missing tenant_id",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
listID := vars["id"]
|
||||
|
||||
if err := h.repo.DeleteList(listID, tenantID); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to delete list",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "List deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== CUSTOMER <-> LIST ====================
|
||||
|
||||
func (h *CRMHandler) AddCustomerToList(w http.ResponseWriter, r *http.Request) {
|
||||
userID, _ := r.Context().Value(middleware.UserIDKey).(string)
|
||||
|
||||
vars := mux.Vars(r)
|
||||
customerID := vars["customer_id"]
|
||||
listID := vars["list_id"]
|
||||
|
||||
if err := h.repo.AddCustomerToList(customerID, listID, userID); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to add customer to list",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "Customer added to list successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CRMHandler) RemoveCustomerFromList(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
customerID := vars["customer_id"]
|
||||
listID := vars["list_id"]
|
||||
|
||||
if err := h.repo.RemoveCustomerFromList(customerID, listID); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"error": "Failed to remove customer from list",
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "Customer removed from list successfully",
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user