Files
noteplace-server/internal/api/ratings.go
T
haopengzhan f1909da1ad
Go CI / build (push) Failing after 2m42s
Initial commit
feat: create basic server to manage google oauth, account, sessions, places, attributes and ratings.
2025-09-19 02:43:04 -07:00

125 lines
3.5 KiB
Go

package api
import (
"net/http"
"time"
"git.pengzhan.dev/noteplace-server/internal/models"
"git.pengzhan.dev/noteplace-server/internal/store"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// RatingsHandler handles HTTP requests for ratings.
type RatingsHandler struct {
Store *store.Store
}
// HandleCreateRating creates a new rating.
func (h *RatingsHandler) HandleCreateRating(c *gin.Context) {
user, exists := c.Get("user")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: User not found in context"})
return
}
var newRating models.Rating
if err := c.ShouldBindJSON(&newRating); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
return
}
if newRating.PlaceID == "" || newRating.AttributeID == "" || newRating.Score < 1 || newRating.Score > 10 {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input: PlaceID, AttributeID, and Score (1-10) are required"})
return
}
newRating.ID = "rating-" + uuid.New().String()
newRating.CreatedAt = time.Now().UTC().Format(time.RFC3339)
newRating.UserID = user.(models.User).ID
if err := h.Store.CreateRating(newRating); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save rating"})
return
}
c.JSON(http.StatusCreated, newRating)
}
// HandleUpdateRating updates an existing rating.
func (h *RatingsHandler) HandleUpdateRating(c *gin.Context) {
user, exists := c.Get("user")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: User not found in context"})
return
}
id := c.Param("id")
var reqBody struct {
Score int `json:"score"`
Comment string `json:"comment"`
}
if err := c.ShouldBindJSON(&reqBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
return
}
if reqBody.Score < 1 || reqBody.Score > 10 {
c.JSON(http.StatusBadRequest, gin.H{"error": "Score must be between 1 and 10"})
return
}
rating, found := h.Store.GetRatingByID(id)
if !found {
c.JSON(http.StatusNotFound, gin.H{"error": "Rating not found"})
return
}
if rating.UserID != user.(models.User).ID {
c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden: You can only update your own ratings"})
return
}
updatedRating, found := h.Store.UpdateRating(id, reqBody.Score, reqBody.Comment)
if !found {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update rating"})
return
}
c.JSON(http.StatusOK, updatedRating)
}
// HandleDeleteRating deletes a rating.
func (h *RatingsHandler) HandleDeleteRating(c *gin.Context) {
user, exists := c.Get("user")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: User not found in context"})
return
}
id := c.Param("id")
rating, found := h.Store.GetRatingByID(id)
if !found {
c.JSON(http.StatusNotFound, gin.H{"error": "Rating not found"})
return
}
if rating.UserID != user.(models.User).ID {
c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden: You can only delete your own ratings"})
return
}
if !h.Store.DeleteRating(id) {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete rating"})
return
}
c.Status(http.StatusNoContent)
}
// HandleGetMyRatings gets all ratings for the current user.
func (h *RatingsHandler) HandleGetMyRatings(c *gin.Context) {
user, exists := c.Get("user")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: User not found in context"})
return
}
ratings := h.Store.GetRatingsByUserID(user.(models.User).ID)
c.JSON(http.StatusOK, ratings)
}