admin-dashboard-backend/routers/router/api/v1/grouptask/grouptask.go

145 lines
4.2 KiB
Go

package grouptask
import (
"encoding/json"
"janex/admin-dashboard-backend/modules/cache"
"janex/admin-dashboard-backend/modules/grouptasks"
"janex/admin-dashboard-backend/modules/structs"
"janex/admin-dashboard-backend/modules/utils"
"janex/admin-dashboard-backend/socketclients"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
func StartGroupTask(c *fiber.Ctx) error {
// swagger:operation POST /grouptasks/start grouptasks grouptasksStart
// ---
// summary: Start a new group task
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: X-Api-Key
// in: header
// description: You can create a new api key in your user profile
// - name: body
// in: body
// description: JSON -> Category str, GroupId str, Description str, GlobalInputs [{key, value}, {...}]
// responses:
// '200':
// description: New group task created successfully
// '400':
// description: Invalid request body
// '401':
// description: No permissions
// '422':
// description: No group tasks in this category or provided global inputs incomplete
var body structs.ApiGroupTaskRequest
if err := c.BodyParser(&body); err != nil {
log.Error().Msg("Failed to parse body, err: " + err.Error())
return c.Status(fiber.StatusBadRequest).JSON(err)
}
if errValidation := utils.ValidateStruct(body); errValidation != nil {
log.Error().Msgf("Failed to validate body, err: %v", errValidation)
return c.Status(fiber.StatusBadRequest).JSON(errValidation)
}
userId := c.Locals("userId").(string)
if !socketclients.HasPermission(userId, utils.PermissionUserProfileApiKeys) || !socketclients.HasXYPermission(userId, utils.PermissionGroupTasksOverviewXYNewTask, body.Category) {
return c.SendStatus(fiber.StatusUnauthorized)
}
categoryGroup := cache.GetCategoryGroupByCategory(body.Category)
if categoryGroup.Category == "" {
return c.Status(fiber.StatusBadRequest).JSONP(fiber.Map{"err": "Category not found"})
}
group := getGroupFromCategoryGroup(categoryGroup, body.GroupId)
if group.Category == "" {
return c.Status(fiber.StatusBadRequest).JSONP(fiber.Map{"err": "GroupId not found"})
}
var bodyGlobalInputs []map[string]string
err := json.Unmarshal(body.GlobalInputs, &bodyGlobalInputs)
if err != nil {
log.Error().Msgf("Failed to unmarshal body global inputs: %v", err)
return c.SendStatus(fiber.StatusBadRequest)
}
if len(group.Tasks) == 0 || !globalInputsComplete(bodyGlobalInputs, group.GlobalInputs) {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
grouptasks.StartGroupTask(userId, structs.GroupTasks{
Category: body.Category,
GroupId: body.GroupId,
GroupName: group.Name,
Description: body.Description,
NumberOfSteps: uint8(len(group.Tasks)),
GlobalInputs: convertJsonGlobalInputToStruct(bodyGlobalInputs, group.GlobalInputs),
})
return c.SendStatus(fiber.StatusOK)
}
func getGroupFromCategoryGroup(categoryGroup structs.CategoryGroup, groupId string) structs.Group {
for _, group := range categoryGroup.Groups {
if group.Id == groupId {
return group
}
}
return structs.Group{}
}
func globalInputsComplete(bodyGlobalInputs []map[string]string, groupGlobalInputs []structs.GlobalInputs) bool {
for _, gGlobalInput := range groupGlobalInputs {
if !isInList(gGlobalInput.ParameterName, bodyGlobalInputs) {
return false
}
}
return true
}
func isInList(gParameterName string, bodyInputs []map[string]string) bool {
for _, bInput := range bodyInputs {
if bInput[gParameterName] != "" {
return true
}
}
return false
}
type GlobalInputs struct {
ParameterName string `json:"parameterName"`
Value string `json:"value"`
}
func convertJsonGlobalInputToStruct(bodyGlobalInputs []map[string]string, groupGlobalInputs []structs.GlobalInputs) string {
var globalInputs []GlobalInputs
for _, gGlobalInput := range groupGlobalInputs {
for _, bInput := range bodyGlobalInputs {
if bInput[gGlobalInput.ParameterName] != "" {
globalInputs = append(globalInputs, GlobalInputs{
ParameterName: gGlobalInput.ParameterName,
Value: bInput[gGlobalInput.ParameterName],
})
}
}
}
return utils.MarshalJson(globalInputs)
}