committtttt

This commit is contained in:
Dev
2025-09-13 06:48:55 +03:00
commit 2d49f69be6
32 changed files with 6478 additions and 0 deletions

View File

@@ -0,0 +1,475 @@
package handlers
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"customer-support-system/internal/knowledge"
"customer-support-system/internal/models"
"customer-support-system/pkg/logger"
)
// KnowledgeHandler handles knowledge base-related HTTP requests
type KnowledgeHandler struct {
knowledgeService *knowledge.KnowledgeService
}
// NewKnowledgeHandler creates a new knowledge handler
func NewKnowledgeHandler() *KnowledgeHandler {
return &KnowledgeHandler{
knowledgeService: knowledge.NewKnowledgeService(),
}
}
// CreateKnowledgeEntry handles creating a new knowledge base entry
func (h *KnowledgeHandler) CreateKnowledgeEntry(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.CreateKnowledgeBaseRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.WithError(err).Error("Failed to parse create knowledge entry request")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid request body",
})
return
}
// Create knowledge entry
entry, err := h.knowledgeService.CreateKnowledgeEntry(userID.(uint), &req)
if err != nil {
logger.WithError(err).Error("Failed to create knowledge entry")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to create knowledge entry",
})
return
}
c.JSON(http.StatusCreated, gin.H{
"success": true,
"message": "Knowledge entry created successfully",
"data": gin.H{
"entry": entry,
},
})
}
// GetKnowledgeEntry handles getting a knowledge base entry by ID
func (h *KnowledgeHandler) GetKnowledgeEntry(c *gin.Context) {
// Get knowledge entry ID from URL params
entryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
logger.WithError(err).Error("Failed to parse knowledge entry ID")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid knowledge entry ID",
})
return
}
// Get knowledge entry
entry, err := h.knowledgeService.GetKnowledgeEntry(uint(entryID))
if err != nil {
logger.WithError(err).Error("Failed to get knowledge entry")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to get knowledge entry",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"entry": entry,
},
})
}
// ListKnowledgeEntries handles listing knowledge base entries
func (h *KnowledgeHandler) ListKnowledgeEntries(c *gin.Context) {
// Parse query parameters
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
category := c.DefaultQuery("category", "")
activeStr := c.DefaultQuery("active", "true")
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
// Parse active parameter
var active *bool
if activeStr != "" {
activeVal := activeStr == "true"
active = &activeVal
}
// List knowledge entries
response, err := h.knowledgeService.ListKnowledgeEntries(page, pageSize, category, active)
if err != nil {
logger.WithError(err).Error("Failed to list knowledge entries")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to list knowledge entries",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"entries": response.Entries,
"total": response.Total,
"page": response.Page,
"pageSize": response.PageSize,
},
})
}
// UpdateKnowledgeEntry handles updating a knowledge base entry
func (h *KnowledgeHandler) UpdateKnowledgeEntry(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 knowledge entry ID from URL params
entryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
logger.WithError(err).Error("Failed to parse knowledge entry ID")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid knowledge entry ID",
})
return
}
var req models.UpdateKnowledgeBaseRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.WithError(err).Error("Failed to parse update knowledge entry request")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid request body",
})
return
}
// Update knowledge entry
entry, err := h.knowledgeService.UpdateKnowledgeEntry(uint(entryID), userID.(uint), &req)
if err != nil {
logger.WithError(err).Error("Failed to update knowledge entry")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to update knowledge entry",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Knowledge entry updated successfully",
"data": gin.H{
"entry": entry,
},
})
}
// DeleteKnowledgeEntry handles deleting a knowledge base entry
func (h *KnowledgeHandler) DeleteKnowledgeEntry(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 knowledge entry ID from URL params
entryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
logger.WithError(err).Error("Failed to parse knowledge entry ID")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid knowledge entry ID",
})
return
}
// Delete knowledge entry
err = h.knowledgeService.DeleteKnowledgeEntry(uint(entryID), userID.(uint))
if err != nil {
logger.WithError(err).Error("Failed to delete knowledge entry")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to delete knowledge entry",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Knowledge entry deleted successfully",
})
}
// SearchKnowledge handles searching knowledge base entries
func (h *KnowledgeHandler) SearchKnowledge(c *gin.Context) {
// Parse query parameters
query := c.DefaultQuery("query", "")
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
category := c.DefaultQuery("category", "")
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
// Search knowledge entries
response, err := h.knowledgeService.SearchKnowledge(query, page, pageSize, category)
if err != nil {
logger.WithError(err).Error("Failed to search knowledge entries")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to search knowledge entries",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"results": response.Results,
"total": response.Total,
"query": response.Query,
"page": response.Page,
"pageSize": response.PageSize,
},
})
}
// GetCategories handles getting all unique categories in the knowledge base
func (h *KnowledgeHandler) GetCategories(c *gin.Context) {
// Get categories
categories, err := h.knowledgeService.GetCategories()
if err != nil {
logger.WithError(err).Error("Failed to get knowledge categories")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to get knowledge categories",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"categories": categories,
},
})
}
// GetTags handles getting all unique tags in the knowledge base
func (h *KnowledgeHandler) GetTags(c *gin.Context) {
// Get tags
tags, err := h.knowledgeService.GetTags()
if err != nil {
logger.WithError(err).Error("Failed to get knowledge tags")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to get knowledge tags",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"tags": tags,
},
})
}
// RateKnowledgeEntry handles rating a knowledge base entry as helpful or not
func (h *KnowledgeHandler) RateKnowledgeEntry(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 knowledge entry ID from URL params
entryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
logger.WithError(err).Error("Failed to parse knowledge entry ID")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid knowledge entry ID",
})
return
}
var req models.CreateKnowledgeBaseFeedbackRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.WithError(err).Error("Failed to parse rate knowledge entry request")
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Invalid request body",
})
return
}
// Rate knowledge entry
err = h.knowledgeService.RateKnowledgeEntry(uint(entryID), userID.(uint), req.Helpful, req.Comment)
if err != nil {
logger.WithError(err).Error("Failed to rate knowledge entry")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to rate knowledge entry",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Knowledge entry rated successfully",
})
}
// GetPopularKnowledge handles getting popular knowledge base entries
func (h *KnowledgeHandler) GetPopularKnowledge(c *gin.Context) {
// Parse query parameters
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
if limit < 1 || limit > 100 {
limit = 10
}
// Get popular knowledge entries
entries, err := h.knowledgeService.GetPopularKnowledge(limit)
if err != nil {
logger.WithError(err).Error("Failed to get popular knowledge entries")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to get popular knowledge entries",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"entries": entries,
},
})
}
// GetRecentKnowledge handles getting recent knowledge base entries
func (h *KnowledgeHandler) GetRecentKnowledge(c *gin.Context) {
// Parse query parameters
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
if limit < 1 || limit > 100 {
limit = 10
}
// Get recent knowledge entries
entries, err := h.knowledgeService.GetRecentKnowledge(limit)
if err != nil {
logger.WithError(err).Error("Failed to get recent knowledge entries")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to get recent knowledge entries",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"entries": entries,
},
})
}
// FindBestMatch handles finding the best matching knowledge base entry for a query
func (h *KnowledgeHandler) FindBestMatch(c *gin.Context) {
// Parse query parameters
query := c.DefaultQuery("query", "")
if query == "" {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "Query parameter is required",
})
return
}
// Find best match
entry, err := h.knowledgeService.FindBestMatch(query)
if err != nil {
logger.WithError(err).Error("Failed to find best match")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to find best match",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"entry": entry,
},
})
}
// GetKnowledgeStats handles getting statistics for the knowledge base
func (h *KnowledgeHandler) GetKnowledgeStats(c *gin.Context) {
// Get knowledge stats
stats, err := h.knowledgeService.GetKnowledgeStats()
if err != nil {
logger.WithError(err).Error("Failed to get knowledge stats")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "Failed to get knowledge stats",
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"stats": stats,
},
})
}