559 lines
14 KiB
Go
559 lines
14 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"customer-support-system/internal/conversation"
|
|
"customer-support-system/internal/models"
|
|
"customer-support-system/pkg/logger"
|
|
)
|
|
|
|
// ConversationHandler handles conversation-related HTTP requests
|
|
type ConversationHandler struct {
|
|
conversationService *conversation.ConversationService
|
|
}
|
|
|
|
// NewConversationHandler creates a new conversation handler
|
|
func NewConversationHandler() *ConversationHandler {
|
|
return &ConversationHandler{
|
|
conversationService: conversation.NewConversationService(),
|
|
}
|
|
}
|
|
|
|
// CreateConversation handles creating a new conversation
|
|
func (h *ConversationHandler) CreateConversation(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.CreateConversationRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.WithError(err).Error("Failed to parse create conversation request")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid request body",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Create conversation
|
|
conv, err := h.conversationService.CreateConversation(userID.(uint), &req)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to create conversation")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to create conversation",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, gin.H{
|
|
"success": true,
|
|
"message": "Conversation created successfully",
|
|
"data": gin.H{
|
|
"conversation": conv,
|
|
},
|
|
})
|
|
}
|
|
|
|
// GetConversation handles getting a conversation by ID
|
|
func (h *ConversationHandler) GetConversation(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation
|
|
conv, err := h.conversationService.GetConversation(uint(conversationID), userID.(uint))
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to get conversation")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to get conversation",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"data": gin.H{
|
|
"conversation": conv,
|
|
},
|
|
})
|
|
}
|
|
|
|
// ListConversations handles listing conversations for a user
|
|
func (h *ConversationHandler) ListConversations(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Parse query parameters
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
|
status := c.DefaultQuery("status", "")
|
|
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if pageSize < 1 || pageSize > 100 {
|
|
pageSize = 10
|
|
}
|
|
|
|
// List conversations
|
|
response, err := h.conversationService.ListConversations(userID.(uint), page, pageSize, status)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to list conversations")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to list conversations",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"data": gin.H{
|
|
"conversations": response.Conversations,
|
|
"total": response.Total,
|
|
"page": response.Page,
|
|
"pageSize": response.PageSize,
|
|
},
|
|
})
|
|
}
|
|
|
|
// UpdateConversation handles updating a conversation
|
|
func (h *ConversationHandler) UpdateConversation(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.UpdateConversationRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.WithError(err).Error("Failed to parse update conversation request")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid request body",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Update conversation
|
|
conv, err := h.conversationService.UpdateConversation(uint(conversationID), userID.(uint), &req)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to update conversation")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to update conversation",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "Conversation updated successfully",
|
|
"data": gin.H{
|
|
"conversation": conv,
|
|
},
|
|
})
|
|
}
|
|
|
|
// DeleteConversation handles deleting a conversation
|
|
func (h *ConversationHandler) DeleteConversation(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Delete conversation
|
|
err = h.conversationService.DeleteConversation(uint(conversationID), userID.(uint))
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to delete conversation")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to delete conversation",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "Conversation deleted successfully",
|
|
})
|
|
}
|
|
|
|
// CreateMessage handles creating a new message in a conversation
|
|
func (h *ConversationHandler) CreateMessage(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.CreateMessageRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.WithError(err).Error("Failed to parse create message request")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid request body",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Create message
|
|
message, err := h.conversationService.CreateMessage(uint(conversationID), userID.(uint), &req)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to create message")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to create message",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, gin.H{
|
|
"success": true,
|
|
"message": "Message created successfully",
|
|
"data": gin.H{
|
|
"message": message,
|
|
},
|
|
})
|
|
}
|
|
|
|
// GetMessages handles getting messages in a conversation
|
|
func (h *ConversationHandler) GetMessages(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Parse query parameters
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
|
|
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if pageSize < 1 || pageSize > 100 {
|
|
pageSize = 20
|
|
}
|
|
|
|
// Get messages
|
|
response, err := h.conversationService.GetMessages(uint(conversationID), userID.(uint), page, pageSize)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to get messages")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to get messages",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"data": gin.H{
|
|
"messages": response.Messages,
|
|
"total": response.Total,
|
|
"page": response.Page,
|
|
"pageSize": response.PageSize,
|
|
},
|
|
})
|
|
}
|
|
|
|
// UpdateMessage handles updating a message
|
|
func (h *ConversationHandler) UpdateMessage(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get message ID from URL params
|
|
messageID, err := strconv.ParseUint(c.Param("messageId"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse message ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid message ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.UpdateMessageRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.WithError(err).Error("Failed to parse update message request")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid request body",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Update message
|
|
message, err := h.conversationService.UpdateMessage(uint(messageID), userID.(uint), &req)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to update message")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to update message",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "Message updated successfully",
|
|
"data": gin.H{
|
|
"message": message,
|
|
},
|
|
})
|
|
}
|
|
|
|
// DeleteMessage handles deleting a message
|
|
func (h *ConversationHandler) DeleteMessage(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get message ID from URL params
|
|
messageID, err := strconv.ParseUint(c.Param("messageId"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse message ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid message ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Delete message
|
|
err = h.conversationService.DeleteMessage(uint(messageID), userID.(uint))
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to delete message")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to delete message",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "Message deleted successfully",
|
|
})
|
|
}
|
|
|
|
// SendMessageWithAI handles sending a message and getting an AI response
|
|
func (h *ConversationHandler) SendMessageWithAI(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Content string `json:"content" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.WithError(err).Error("Failed to parse send message request")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid request body",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Send message and get AI response
|
|
userMessage, aiMessage, err := h.conversationService.SendMessageWithAI(uint(conversationID), userID.(uint), req.Content)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to send message with AI")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to send message with AI",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, gin.H{
|
|
"success": true,
|
|
"message": "Message sent and AI response received",
|
|
"data": gin.H{
|
|
"userMessage": userMessage,
|
|
"aiMessage": aiMessage,
|
|
},
|
|
})
|
|
}
|
|
|
|
// GetConversationStats handles getting statistics for a conversation
|
|
func (h *ConversationHandler) GetConversationStats(c *gin.Context) {
|
|
// Get user ID from context
|
|
userID, exists := c.Get("userID")
|
|
if !exists {
|
|
logger.Error("Failed to get user ID from context")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"success": false,
|
|
"message": "Unauthorized",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation ID from URL params
|
|
conversationID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to parse conversation ID")
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"success": false,
|
|
"message": "Invalid conversation ID",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get conversation stats
|
|
stats, err := h.conversationService.GetConversationStats(uint(conversationID), userID.(uint))
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to get conversation stats")
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": "Failed to get conversation stats",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"data": gin.H{
|
|
"stats": stats,
|
|
},
|
|
})
|
|
}
|