package handlers import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" apperrors "veza-backend-api/internal/errors" "veza-backend-api/internal/services" ) // ReportHandler handles moderation report endpoints (v0.803 ADM1) type ReportHandler struct { reportService *services.ReportService } // NewReportHandler creates a new ReportHandler func NewReportHandler(reportService *services.ReportService) *ReportHandler { return &ReportHandler{reportService: reportService} } // ListReports returns paginated reports (admin only) func (h *ReportHandler) ListReports(c *gin.Context) { status := c.DefaultQuery("status", "all") limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20")) limit = clampLimit(limit) // SECURITY(MEDIUM-004) offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0")) reports, total, err := h.reportService.List(c.Request.Context(), services.ListReportsParams{ Status: status, Limit: limit, Offset: offset, }) if err != nil { RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to list reports", err)) return } c.JSON(http.StatusOK, gin.H{ "reports": reports, "pagination": gin.H{ "total": total, "limit": limit, "offset": offset, }, }) } // ResolveReport resolves a report (admin only) func (h *ReportHandler) ResolveReport(c *gin.Context) { reportIDStr := c.Param("id") reportID, err := uuid.Parse(reportIDStr) if err != nil { RespondWithAppError(c, apperrors.NewValidationError("Invalid report ID")) return } userID, ok := GetUserIDUUID(c) if !ok || userID == uuid.Nil { RespondWithAppError(c, apperrors.NewUnauthorizedError("Authentication required")) return } var req services.ResolveReportRequest if err := c.ShouldBindJSON(&req); err != nil { RespondWithAppError(c, apperrors.NewValidationError("action is required")) return } if err := h.reportService.Resolve(c.Request.Context(), reportID, userID, req.Action); err != nil { RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to resolve report", err)) return } c.JSON(http.StatusOK, gin.H{"message": "Report resolved"}) } // CreateReport creates a report (authenticated user) func (h *ReportHandler) CreateReport(c *gin.Context) { userID, ok := GetUserIDUUID(c) if !ok || userID == uuid.Nil { RespondWithAppError(c, apperrors.NewUnauthorizedError("Authentication required")) return } var req services.CreateReportRequest if err := c.ShouldBindJSON(&req); err != nil { RespondWithAppError(c, apperrors.NewValidationError("content_type and reason are required")) return } report, err := h.reportService.Create(c.Request.Context(), userID, req) if err != nil { RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to create report", err)) return } c.JSON(http.StatusCreated, report) }