128 lines
3.7 KiB
Go
128 lines
3.7 KiB
Go
// Path: Backend/internal/httpx/api_project_decode.go
|
|
|
|
package httpx
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type createProjectFolderRequest struct {
|
|
Name string `json:"name"`
|
|
ParentFolderPath string `json:"parentFolderId"`
|
|
}
|
|
|
|
type renameProjectFolderRequest struct {
|
|
FolderPath string `json:"folderId"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type deleteProjectFolderRequest struct {
|
|
FolderPath string `json:"folderId"`
|
|
}
|
|
|
|
// Keep the existing JSON contract for the frontend, but use clearer path-vs-stable-ID
|
|
// names internally so the move flow is easier to reason about.
|
|
type moveProjectFolderRequest struct {
|
|
FolderPath string `json:"folderId"`
|
|
FolderStableID string `json:"folderNodeId"`
|
|
ParentFolderPath string `json:"parentFolderId"`
|
|
ParentStableID string `json:"parentNodeId"`
|
|
TargetIndex int `json:"targetIndex"`
|
|
}
|
|
|
|
type createProjectItemRequest struct {
|
|
Name string `json:"name"`
|
|
ParentFolderPath string `json:"parentFolderId"`
|
|
ItemType string `json:"itemType"`
|
|
}
|
|
|
|
type deleteProjectItemRequest struct {
|
|
ItemPath string `json:"itemId"`
|
|
}
|
|
|
|
type moveProjectItemRequest struct {
|
|
ItemPath string `json:"itemId"`
|
|
ItemStableID string `json:"itemNodeId"`
|
|
ParentFolderPath string `json:"parentFolderId"`
|
|
ParentStableID string `json:"parentNodeId"`
|
|
TargetIndex int `json:"targetIndex"`
|
|
}
|
|
|
|
func decodeMoveProjectFolderRequest(w http.ResponseWriter, r *http.Request) (moveProjectFolderRequest, bool) {
|
|
var payload moveProjectFolderRequest
|
|
if !decodeJSONObjectBody(w, r, &payload) {
|
|
return payload, false
|
|
}
|
|
return payload, true
|
|
}
|
|
|
|
func decodeDeleteProjectFolderRequest(r *http.Request) deleteProjectFolderRequest {
|
|
return deleteProjectFolderRequest{
|
|
FolderPath: strings.TrimSpace(r.URL.Query().Get("folderId")),
|
|
}
|
|
}
|
|
|
|
func decodeDeleteProjectItemRequest(r *http.Request) deleteProjectItemRequest {
|
|
return deleteProjectItemRequest{
|
|
ItemPath: strings.TrimSpace(r.URL.Query().Get("itemId")),
|
|
}
|
|
}
|
|
|
|
func decodeRenameProjectFolderRequest(w http.ResponseWriter, r *http.Request) (renameProjectFolderRequest, bool) {
|
|
var payload renameProjectFolderRequest
|
|
if !decodeJSONObjectBody(w, r, &payload) {
|
|
return payload, false
|
|
}
|
|
return payload, true
|
|
}
|
|
|
|
func decodeProjectFolderRequest(w http.ResponseWriter, r *http.Request) (createProjectFolderRequest, bool) {
|
|
var payload createProjectFolderRequest
|
|
if !decodeJSONObjectBody(w, r, &payload) {
|
|
return payload, false
|
|
}
|
|
return payload, true
|
|
}
|
|
|
|
func decodeProjectItemRequest(w http.ResponseWriter, r *http.Request) (createProjectItemRequest, bool) {
|
|
var payload createProjectItemRequest
|
|
if !decodeJSONObjectBody(w, r, &payload) {
|
|
return payload, false
|
|
}
|
|
return payload, true
|
|
}
|
|
|
|
func decodeMoveProjectItemRequest(w http.ResponseWriter, r *http.Request) (moveProjectItemRequest, bool) {
|
|
var payload moveProjectItemRequest
|
|
if !decodeJSONObjectBody(w, r, &payload) {
|
|
return payload, false
|
|
}
|
|
return payload, true
|
|
}
|
|
|
|
func decodeJSONObjectBody(w http.ResponseWriter, r *http.Request, target any) bool {
|
|
decoder := json.NewDecoder(r.Body)
|
|
decoder.DisallowUnknownFields()
|
|
|
|
if err := decoder.Decode(target); err != nil {
|
|
if errors.Is(err, io.EOF) {
|
|
WriteError(w, http.StatusBadRequest, RequestIDFromContext(r.Context()), "invalid_json", "The request body is required and must be valid JSON.")
|
|
return false
|
|
}
|
|
|
|
WriteError(w, http.StatusBadRequest, RequestIDFromContext(r.Context()), "invalid_json", "The request body must be valid JSON.")
|
|
return false
|
|
}
|
|
|
|
if err := decoder.Decode(&struct{}{}); !errors.Is(err, io.EOF) {
|
|
WriteError(w, http.StatusBadRequest, RequestIDFromContext(r.Context()), "invalid_json", "The request body must contain a single JSON object.")
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|