f1909da1ad
Go CI / build (push) Failing after 2m42s
feat: create basic server to manage google oauth, account, sessions, places, attributes and ratings.
95 lines
2.6 KiB
Go
95 lines
2.6 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"
|
|
)
|
|
|
|
// PlacesHandler handles HTTP requests for places.
|
|
type PlacesHandler struct {
|
|
Store *store.Store
|
|
}
|
|
|
|
// HandleGetPlaces returns a list of all places.
|
|
func (h *PlacesHandler) HandleGetPlaces(c *gin.Context) {
|
|
h.Store.Mu.RLock()
|
|
defer h.Store.Mu.RUnlock()
|
|
places := h.Store.Data.Places
|
|
c.JSON(http.StatusOK, places)
|
|
}
|
|
|
|
// HandleCreatePlace creates a new place.
|
|
func (h *PlacesHandler) HandleCreatePlace(c *gin.Context) {
|
|
var newPlace models.Place
|
|
if err := c.ShouldBindJSON(&newPlace); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
|
return
|
|
}
|
|
|
|
if newPlace.Name == "" || newPlace.Category == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Name and Category are required fields"})
|
|
return
|
|
}
|
|
|
|
newPlace.ID = "place-" + uuid.New().String()
|
|
newPlace.CreatedAt = time.Now().UTC().Format(time.RFC3339)
|
|
|
|
// Extract UserID from context after authentication middleware
|
|
user, exists := c.Get("user")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: User not found in context"})
|
|
return
|
|
}
|
|
|
|
if user.(models.User).Role > models.TRUSTED {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: User not allowed to perform this action"})
|
|
return
|
|
}
|
|
|
|
if err := h.Store.CreatePlace(newPlace); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save place"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, newPlace)
|
|
}
|
|
|
|
// HandleGetPlaceByID returns a single place by its ID.
|
|
func (h *PlacesHandler) HandleGetPlaceByID(c *gin.Context) {
|
|
id := c.Param("id")
|
|
place, found := h.Store.GetPlaceByID(id)
|
|
if !found {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Place not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, place)
|
|
}
|
|
|
|
// HandleGetPlaceRatings returns all ratings for a specific place.
|
|
func (h *PlacesHandler) HandleGetPlaceRatings(c *gin.Context) {
|
|
placeID := c.Param("id")
|
|
if _, found := h.Store.GetPlaceByID(placeID); !found {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Place not found"})
|
|
return
|
|
}
|
|
ratings := h.Store.GetRatingsByPlaceID(placeID)
|
|
c.JSON(http.StatusOK, ratings)
|
|
}
|
|
|
|
// HandleGetPlaceAttributes returns all relevant attributes for a specific place.
|
|
func (h *PlacesHandler) HandleGetPlaceAttributes(c *gin.Context) {
|
|
placeID := c.Param("id")
|
|
place, found := h.Store.GetPlaceByID(placeID)
|
|
if !found {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Place not found"})
|
|
return
|
|
}
|
|
attributes := h.Store.GetAttributesByPlace(place)
|
|
c.JSON(http.StatusOK, attributes)
|
|
}
|