I am batman
This commit is contained in:
327
internal/handlers/taskHandler.go
Normal file
327
internal/handlers/taskHandler.go
Normal file
@@ -0,0 +1,327 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"OpsMastery.v5/internal/database"
|
||||
"OpsMastery.v5/internal/models"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type sectionPayload struct {
|
||||
Title string `json:"title"`
|
||||
TitleAlt string `json:"Title"`
|
||||
Position *int `json:"position"`
|
||||
PositionAlt *int `json:"Position"`
|
||||
}
|
||||
|
||||
type taskPayload struct {
|
||||
Title string `json:"title"`
|
||||
TitleAlt string `json:"Title"`
|
||||
Description string `json:"description"`
|
||||
DescriptionAlt string `json:"Description"`
|
||||
Position *int `json:"position"`
|
||||
PositionAlt *int `json:"Position"`
|
||||
SectionID *uint `json:"section_id"`
|
||||
SectionIDAlt *uint `json:"SectionID"`
|
||||
}
|
||||
|
||||
func (p sectionPayload) normalizedTitle() string {
|
||||
title := strings.TrimSpace(p.Title)
|
||||
if title == "" {
|
||||
title = strings.TrimSpace(p.TitleAlt)
|
||||
}
|
||||
return title
|
||||
}
|
||||
|
||||
func (p sectionPayload) normalizedPosition() int {
|
||||
if p.Position != nil {
|
||||
return *p.Position
|
||||
}
|
||||
if p.PositionAlt != nil {
|
||||
return *p.PositionAlt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p taskPayload) normalizedTask() models.Tasks {
|
||||
title := strings.TrimSpace(p.Title)
|
||||
if title == "" {
|
||||
title = strings.TrimSpace(p.TitleAlt)
|
||||
}
|
||||
|
||||
description := p.Description
|
||||
if description == "" {
|
||||
description = p.DescriptionAlt
|
||||
}
|
||||
|
||||
position := 0
|
||||
if p.Position != nil {
|
||||
position = *p.Position
|
||||
} else if p.PositionAlt != nil {
|
||||
position = *p.PositionAlt
|
||||
}
|
||||
|
||||
sectionID := uint(0)
|
||||
if p.SectionID != nil {
|
||||
sectionID = *p.SectionID
|
||||
} else if p.SectionIDAlt != nil {
|
||||
sectionID = *p.SectionIDAlt
|
||||
}
|
||||
|
||||
return models.Tasks{
|
||||
Title: title,
|
||||
Description: description,
|
||||
Position: position,
|
||||
SectionID: sectionID,
|
||||
}
|
||||
}
|
||||
|
||||
func sectionExists(sectionID uint) (bool, error) {
|
||||
var count int64
|
||||
err := database.DB().Model(&models.TaskSection{}).Where("id = ?", sectionID).Count(&count).Error
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func CreateTaskSection(c *fiber.Ctx) error {
|
||||
var payload sectionPayload
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
section := models.TaskSection{
|
||||
Title: payload.normalizedTitle(),
|
||||
Position: payload.normalizedPosition(),
|
||||
}
|
||||
|
||||
if section.Title == "" {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "title is required"})
|
||||
}
|
||||
|
||||
if err := database.DB().Create(§ion).Error; err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.Status(http.StatusCreated).JSON(section)
|
||||
}
|
||||
|
||||
func ListTaskSections(c *fiber.Ctx) error {
|
||||
var sections []models.TaskSection
|
||||
err := database.DB().
|
||||
Preload("Tasks", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("position asc, id asc")
|
||||
}).
|
||||
Order("position asc, id asc").
|
||||
Find(§ions).Error
|
||||
if err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(sections)
|
||||
}
|
||||
|
||||
func UpdateTaskSectionByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
sectionID, err := strconv.ParseUint(id, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid section ID"})
|
||||
}
|
||||
|
||||
var payload sectionPayload
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
updates := map[string]any{}
|
||||
if title := payload.normalizedTitle(); title != "" {
|
||||
updates["title"] = title
|
||||
}
|
||||
if payload.Position != nil || payload.PositionAlt != nil {
|
||||
updates["position"] = payload.normalizedPosition()
|
||||
}
|
||||
|
||||
if len(updates) == 0 {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "at least one field is required"})
|
||||
}
|
||||
|
||||
result := database.DB().Model(&models.TaskSection{}).Where("id = ?", sectionID).Updates(updates)
|
||||
if result.Error != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": result.Error.Error()})
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "Section not found"})
|
||||
}
|
||||
|
||||
var section models.TaskSection
|
||||
if err := database.DB().First(§ion, sectionID).Error; err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(section)
|
||||
}
|
||||
|
||||
func DeleteTaskSectionByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
sectionID, err := strconv.ParseUint(id, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid section ID"})
|
||||
}
|
||||
|
||||
result := database.DB().Unscoped().Delete(&models.TaskSection{}, sectionID)
|
||||
if result.RowsAffected == 0 {
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Section not found"})
|
||||
}
|
||||
if result.Error != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": result.Error.Error()})
|
||||
}
|
||||
|
||||
return c.Status(http.StatusOK).JSON(fiber.Map{"message": "Section deleted successfully"})
|
||||
}
|
||||
|
||||
func CreateTask(c *fiber.Ctx) error {
|
||||
var payload taskPayload
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
task := payload.normalizedTask()
|
||||
if task.Title == "" || task.SectionID == 0 {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "title and section_id are required"})
|
||||
}
|
||||
|
||||
exists, err := sectionExists(task.SectionID)
|
||||
if err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
if !exists {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "section not found"})
|
||||
}
|
||||
|
||||
if err := database.DB().Create(&task).Error; err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.Status(http.StatusCreated).JSON(task)
|
||||
}
|
||||
|
||||
func ListTasks(c *fiber.Ctx) error {
|
||||
var tasks []models.Tasks
|
||||
err := database.DB().
|
||||
Preload("Section").
|
||||
Order("position asc, id asc").
|
||||
Find(&tasks).Error
|
||||
if err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(tasks)
|
||||
}
|
||||
|
||||
func GetTaskByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
var task models.Tasks
|
||||
|
||||
taskID, err := strconv.ParseUint(id, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid task ID"})
|
||||
}
|
||||
|
||||
if err := database.DB().Preload("Section").First(&task, taskID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Task not found"})
|
||||
}
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(task)
|
||||
}
|
||||
|
||||
func DeleteTaskByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
taskID, err := strconv.ParseUint(id, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid task ID"})
|
||||
}
|
||||
|
||||
result := database.DB().Unscoped().Delete(&models.Tasks{}, taskID)
|
||||
if result.RowsAffected == 0 {
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Task not found"})
|
||||
}
|
||||
if result.Error != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": result.Error.Error()})
|
||||
}
|
||||
return c.Status(http.StatusOK).JSON(fiber.Map{"message": "Task deleted successfully"})
|
||||
}
|
||||
|
||||
func UpdateTaskByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
taskID, err := strconv.ParseUint(id, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid task ID"})
|
||||
}
|
||||
|
||||
var payload taskPayload
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
updates := map[string]any{}
|
||||
title := strings.TrimSpace(payload.Title)
|
||||
if title == "" {
|
||||
title = strings.TrimSpace(payload.TitleAlt)
|
||||
}
|
||||
if title != "" {
|
||||
updates["title"] = title
|
||||
}
|
||||
|
||||
if payload.Description != "" || payload.DescriptionAlt != "" {
|
||||
description := payload.Description
|
||||
if description == "" {
|
||||
description = payload.DescriptionAlt
|
||||
}
|
||||
updates["description"] = description
|
||||
}
|
||||
|
||||
if payload.Position != nil {
|
||||
updates["position"] = *payload.Position
|
||||
} else if payload.PositionAlt != nil {
|
||||
updates["position"] = *payload.PositionAlt
|
||||
}
|
||||
|
||||
sectionID := uint(0)
|
||||
if payload.SectionID != nil {
|
||||
sectionID = *payload.SectionID
|
||||
} else if payload.SectionIDAlt != nil {
|
||||
sectionID = *payload.SectionIDAlt
|
||||
}
|
||||
if sectionID != 0 {
|
||||
exists, err := sectionExists(sectionID)
|
||||
if err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
if !exists {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "section not found"})
|
||||
}
|
||||
updates["section_id"] = sectionID
|
||||
}
|
||||
|
||||
if len(updates) == 0 {
|
||||
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "at least one field is required"})
|
||||
}
|
||||
|
||||
result := database.DB().Model(&models.Tasks{}).Where("id = ?", taskID).Updates(updates)
|
||||
if result.Error != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": result.Error.Error()})
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "Task not found"})
|
||||
}
|
||||
|
||||
var task models.Tasks
|
||||
if err := database.DB().Preload("Section").First(&task, taskID).Error; err != nil {
|
||||
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(task)
|
||||
}
|
||||
Reference in New Issue
Block a user