package handler import ( "errors" "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/yuxingu/digital-psychology/apps/api/internal/middleware" "github.com/yuxingu/digital-psychology/apps/api/internal/service/admin" "github.com/yuxingu/digital-psychology/apps/api/pkg/response" ) func (h *AdminHandler) registerQualityFeedback(authed *gin.RouterGroup) { authed.GET("/ask/feedback", middleware.RequireAdminPermission(h.Svc, admin.PermAskRead), h.ListAskFeedback) authed.POST("/ask/threads/:id/feedback", middleware.RequireAdminPermission(h.Svc, admin.PermAskFeedbackWrite), h.CreateAskFeedback) } func (h *AdminHandler) ListAskFeedback(c *gin.Context) { limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20")) offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0")) items, err := h.Svc.ListQualityFeedback(c.Request.Context(), limit, offset) if err != nil { response.Fail(c, http.StatusInternalServerError, 50025, "list feedback failed") return } response.OK(c, gin.H{"items": items}) } func (h *AdminHandler) CreateAskFeedback(c *gin.Context) { adminID, ok := middleware.AdminIDFromContext(c) if !ok { response.Fail(c, http.StatusUnauthorized, 40102, "admin session invalid") return } threadID, err := uuid.Parse(c.Param("id")) if err != nil { response.Fail(c, http.StatusBadRequest, 40002, "invalid thread id") return } var body struct { Rating int `json:"rating"` Tag string `json:"tag"` Note string `json:"note"` MessageID *string `json:"message_id"` } if err := c.ShouldBindJSON(&body); err != nil { response.Fail(c, http.StatusBadRequest, 40000, "invalid body") return } var msgID *uuid.UUID if body.MessageID != nil && *body.MessageID != "" { id, err := uuid.Parse(*body.MessageID) if err != nil { response.Fail(c, http.StatusBadRequest, 40002, "invalid message_id") return } msgID = &id } row, err := h.Svc.CreateQualityFeedback(c.Request.Context(), adminID, threadID, msgID, body.Rating, body.Tag, body.Note) if errors.Is(err, admin.ErrBadFeedbackRating) || errors.Is(err, admin.ErrBadFeedbackTag) || errors.Is(err, admin.ErrFeedbackNoteLong) { response.Fail(c, http.StatusBadRequest, 40000, err.Error()) return } if errors.Is(err, admin.ErrAskThreadNotFound) { response.Fail(c, http.StatusNotFound, 40402, "ask thread not found") return } if errors.Is(err, admin.ErrMessageNotInThread) { response.Fail(c, http.StatusBadRequest, 40030, "message not in thread") return } if err != nil { response.Fail(c, http.StatusInternalServerError, 50026, "create feedback failed") return } response.OK(c, row) }