f1909da1ad
Go CI / build (push) Failing after 2m42s
feat: create basic server to manage google oauth, account, sessions, places, attributes and ratings.
125 lines
3.5 KiB
Go
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)
|
|
}
|