first commit
This commit is contained in:
212
backend/internal/interfaces/handlers/category_handler.go
Normal file
212
backend/internal/interfaces/handlers/category_handler.go
Normal file
@@ -0,0 +1,212 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
|
||||
"github.com/noteapp/backend/internal/application/dto"
|
||||
"github.com/noteapp/backend/internal/application/services"
|
||||
"github.com/noteapp/backend/internal/interfaces/middleware"
|
||||
)
|
||||
|
||||
// CategoryHandler handles category endpoints
|
||||
type CategoryHandler struct {
|
||||
categoryService *services.CategoryService
|
||||
}
|
||||
|
||||
// NewCategoryHandler creates a new category handler
|
||||
func NewCategoryHandler(categoryService *services.CategoryService) *CategoryHandler {
|
||||
return &CategoryHandler{categoryService: categoryService}
|
||||
}
|
||||
|
||||
// GetCategoryTree returns the full category tree for a space
|
||||
func (h *CategoryHandler) GetCategoryTree(w http.ResponseWriter, r *http.Request) {
|
||||
userID, err := getUserObjectID(r)
|
||||
if err != nil {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
tree, err := h.categoryService.GetCategoryTree(r.Context(), spaceID, userID)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(tree)
|
||||
}
|
||||
|
||||
// CreateCategory creates a new category in a space
|
||||
func (h *CategoryHandler) CreateCategory(w http.ResponseWriter, r *http.Request) {
|
||||
userID, err := getUserObjectID(r)
|
||||
if err != nil {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.CreateCategoryRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
category, err := h.categoryService.CreateCategory(r.Context(), spaceID, userID, &req)
|
||||
if err != nil {
|
||||
if err.Error() == "unauthorized" {
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(category)
|
||||
}
|
||||
|
||||
// UpdateCategory updates a category
|
||||
func (h *CategoryHandler) UpdateCategory(w http.ResponseWriter, r *http.Request) {
|
||||
userID, err := getUserObjectID(r)
|
||||
if err != nil {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
categoryID, err := bson.ObjectIDFromHex(vars["categoryId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid category id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.UpdateCategoryRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
category, err := h.categoryService.UpdateCategory(r.Context(), categoryID, spaceID, userID, &req)
|
||||
if err != nil {
|
||||
if err.Error() == "unauthorized" {
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(category)
|
||||
}
|
||||
|
||||
// DeleteCategory deletes a category
|
||||
func (h *CategoryHandler) DeleteCategory(w http.ResponseWriter, r *http.Request) {
|
||||
userID, err := getUserObjectID(r)
|
||||
if err != nil {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
categoryID, err := bson.ObjectIDFromHex(vars["categoryId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid category id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var moveNotesTo *string
|
||||
if v := r.URL.Query().Get("moveNotesTo"); v != "" {
|
||||
moveNotesTo = &v
|
||||
}
|
||||
|
||||
if err := h.categoryService.DeleteCategory(r.Context(), categoryID, spaceID, userID, moveNotesTo); err != nil {
|
||||
if err.Error() == "unauthorized" {
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// MoveCategory moves a category to a new parent
|
||||
func (h *CategoryHandler) MoveCategory(w http.ResponseWriter, r *http.Request) {
|
||||
userID, err := getUserObjectID(r)
|
||||
if err != nil {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
categoryID, err := bson.ObjectIDFromHex(vars["categoryId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid category id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var body struct {
|
||||
ParentID *string `json:"parent_id"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
http.Error(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
category, err := h.categoryService.MoveCategory(r.Context(), categoryID, spaceID, userID, body.ParentID)
|
||||
if err != nil {
|
||||
if err.Error() == "unauthorized" {
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(category)
|
||||
}
|
||||
|
||||
// getUserObjectID extracts the user ObjectID from the request context
|
||||
func getUserObjectID(r *http.Request) (bson.ObjectID, error) {
|
||||
userIDStr, ok := r.Context().Value(middleware.UserIDKey).(string)
|
||||
if !ok || userIDStr == "" {
|
||||
return bson.NilObjectID, http.ErrNoCookie
|
||||
}
|
||||
return bson.ObjectIDFromHex(userIDStr)
|
||||
}
|
||||
Reference in New Issue
Block a user