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)