house/backend/routes/task-add-categories.go
2025-06-14 23:47:44 -04:00

89 lines
2.3 KiB
Go

package routes
import (
// "net/http"
"fmt"
"net/http"
"git.red-panda.pet/pandaware/house/backend/db"
"git.red-panda.pet/pandaware/house/backend/middleware"
"git.red-panda.pet/pandaware/house/backend/router"
)
func init() {
routes["POST"]["/task/{id}/categories"] = new(TaskAddCategories)
}
type taskAddCategoriesBody struct {
TaskID int64 `json:"task_id"`
CategoryIDs []int64 `json:"category_ids"`
}
type taskAddCategoriesResponse struct {
TaskCategories []db.TaskCategory `json:"task_categories"`
}
type TaskAddCategories struct{}
// ValidateBody implements router.ValidatedBodyRoute.
func (t *TaskAddCategories) ValidateBody(ctx *router.Context) error {
return middleware.ParseJSONBody[taskAddCategoriesBody](ctx)
}
// ValidateParams implements router.ValidatedParamRoute.
func (t *TaskAddCategories) ValidateParams(ctx *router.Context) error {
return middleware.ValidateUUIDParam(ctx, "id")
}
// Authorize implements router.AuthorizedRoute.
func (t *TaskAddCategories) Authorize(ctx *router.Context) error {
return middleware.Authenticated(ctx)
}
// Handle implements router.Route.
func (t *TaskAddCategories) Handle(ctx *router.Context) error {
user := middleware.User(t, ctx)
body := middleware.JSONBody[taskAddCategoriesBody](t, ctx)
tx, err := ctx.DB.BeginTx(ctx, nil)
if err != nil {
return ctx.GenericError(err, http.StatusInternalServerError)
}
query := ctx.Query.WithTx(tx)
task, err := query.TaskByID(ctx, body.TaskID)
if err != nil {
tx.Rollback()
return ctx.GenericError(err, http.StatusNotFound)
}
if user.ID != task.CreatedBy && user.ID != task.AssignedTo {
return ctx.GenericError(err, http.StatusForbidden)
}
taskCategories := make([]db.TaskCategory, len(body.CategoryIDs))
for _, categoryID := range body.CategoryIDs {
tc, err := query.AddTaskCategory(ctx, db.AddTaskCategoryParams{
TaskID: task.ID,
CategoryID: categoryID,
})
if err != nil {
tx.Rollback()
return ctx.Error(err, http.StatusNotFound, fmt.Sprintf("Category ID %d not found", categoryID))
}
taskCategories = append(taskCategories, tc)
}
return ctx.JSON(200, taskAddCategoriesResponse{
TaskCategories: taskCategories,
})
}
var _ router.AuthorizedRoute = new(TaskAddCategories)
var _ router.ValidatedBodyRoute = new(TaskAddCategories)
var _ router.ValidatedParamRoute = new(TaskAddCategories)