package handlers import ( "net/http" "strings" "time" apperrors "veza-backend-api/internal/errors" "github.com/gin-gonic/gin" "go.uber.org/zap" "gorm.io/gorm" ) // SupportTicket represents a support contact request (v0.13.5 TASK-MKT-004) type SupportTicket struct { ID string `json:"id" gorm:"type:uuid;primaryKey;default:gen_random_uuid()"` UserID string `json:"user_id,omitempty" gorm:"type:uuid"` Email string `json:"email" gorm:"type:varchar(255);not null"` Subject string `json:"subject" gorm:"type:varchar(500);not null"` Message string `json:"message" gorm:"type:text;not null"` Category string `json:"category" gorm:"type:varchar(100)"` Status string `json:"status" gorm:"type:varchar(50);default:'open'"` CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` } func (SupportTicket) TableName() string { return "support_tickets" } // SupportHandler handles support/contact form submissions type SupportHandler struct { db *gorm.DB logger *zap.Logger } // NewSupportHandler creates a new support handler func NewSupportHandler(db *gorm.DB, logger *zap.Logger) *SupportHandler { return &SupportHandler{ db: db, logger: logger, } } // SubmitTicketRequest is the request body for submitting a support ticket type SubmitTicketRequest struct { Email string `json:"email" binding:"required,email"` Subject string `json:"subject" binding:"required,min=3,max=500"` Message string `json:"message" binding:"required,min=10,max=5000"` Category string `json:"category"` } // SubmitTicket creates a new support ticket from the contact form func (h *SupportHandler) SubmitTicket(c *gin.Context) { var req SubmitTicketRequest if err := c.ShouldBindJSON(&req); err != nil { RespondWithAppError(c, apperrors.NewValidationError("Invalid request: email, subject (3-500 chars), and message (10-5000 chars) are required")) return } // Sanitize req.Email = strings.TrimSpace(req.Email) req.Subject = strings.TrimSpace(req.Subject) req.Message = strings.TrimSpace(req.Message) if req.Category == "" { req.Category = "general" } // Get user ID if authenticated (optional) var userID string if uid, exists := c.Get("user_id"); exists { userID = uid.(interface{ String() string }).String() } ticket := SupportTicket{ UserID: userID, Email: req.Email, Subject: req.Subject, Message: req.Message, Category: req.Category, Status: "open", } if err := h.db.WithContext(c.Request.Context()).Create(&ticket).Error; err != nil { h.logger.Error("Failed to create support ticket", zap.Error(err)) RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to submit support request", err)) return } h.logger.Info("Support ticket created", zap.String("ticket_id", ticket.ID), zap.String("email", req.Email), zap.String("category", req.Category), ) RespondSuccess(c, http.StatusCreated, gin.H{ "ticket_id": ticket.ID, "message": "Your support request has been submitted. We'll respond to your email within 48 hours.", }) }