package controllers import ( "net/http" "time" "github.com/gin-gonic/gin" "errors" "autostore/internal/application/commands" "autostore/internal/application/dto" "autostore/internal/application/interfaces" "autostore/internal/application/queries" ) type ItemsController struct { addItemCmd *commands.AddItemCommand getItemQry *queries.GetItemQuery listItemsQry *queries.ListItemsQuery deleteItemCmd *commands.DeleteItemCommand logger interfaces.ILogger } func NewItemsController( addItemCmd *commands.AddItemCommand, getItemQry *queries.GetItemQuery, listItemsQry *queries.ListItemsQuery, deleteItemCmd *commands.DeleteItemCommand, logger interfaces.ILogger, ) *ItemsController { return &ItemsController{ addItemCmd: addItemCmd, getItemQry: getItemQry, listItemsQry: listItemsQry, deleteItemCmd: deleteItemCmd, logger: logger, } } func (ctrl *ItemsController) CreateItem(c *gin.Context) { userID, exists := c.Get("userID") if !exists { c.JSON(http.StatusUnauthorized, dto.JSendError("Unauthorized", http.StatusUnauthorized)) return } var createItemDTO dto.CreateItemDTO if err := c.ShouldBindJSON(&createItemDTO); err != nil { c.JSON(http.StatusBadRequest, dto.JSendError("Invalid request body", http.StatusBadRequest)) return } if err := createItemDTO.Validate(); err != nil { c.JSON(http.StatusBadRequest, dto.JSendError(err.Error(), http.StatusBadRequest)) return } itemID, err := ctrl.addItemCmd.Execute(c.Request.Context(), createItemDTO.Name, createItemDTO.ExpirationDate.Time, createItemDTO.OrderURL, userID.(string)) if err != nil { c.JSON(http.StatusInternalServerError, dto.JSendError(err.Error(), http.StatusInternalServerError)) return } response := &dto.ItemResponseDTO{ ID: itemID, Name: createItemDTO.Name, ExpirationDate: createItemDTO.ExpirationDate, OrderURL: createItemDTO.OrderURL, UserID: userID.(string), CreatedAt: dto.JSONTime{Time: time.Now()}, } c.JSON(http.StatusCreated, dto.JSendSuccess(response)) } func (ctrl *ItemsController) GetItem(c *gin.Context) { userID, exists := c.Get("userID") if !exists { c.JSON(http.StatusUnauthorized, dto.JSendError("Unauthorized", http.StatusUnauthorized)) return } itemID := c.Param("id") if itemID == "" { c.JSON(http.StatusBadRequest, dto.JSendError("Item ID is required", http.StatusBadRequest)) return } item, err := ctrl.getItemQry.Execute(c.Request.Context(), itemID, userID.(string)) if err != nil { if errors.Is(err, queries.ErrItemNotFound) { c.JSON(http.StatusNotFound, dto.JSendError("Item not found", http.StatusNotFound)) return } if errors.Is(err, queries.ErrUnauthorizedAccess) { c.JSON(http.StatusNotFound, dto.JSendError("Item not found", http.StatusNotFound)) return } c.JSON(http.StatusInternalServerError, dto.JSendError(err.Error(), http.StatusInternalServerError)) return } response := (&dto.ItemResponseDTO{}).FromEntity(item) c.JSON(http.StatusOK, dto.JSendSuccess(response)) } func (ctrl *ItemsController) ListItems(c *gin.Context) { userID, exists := c.Get("userID") if !exists { c.JSON(http.StatusUnauthorized, dto.JSendError("Unauthorized", http.StatusUnauthorized)) return } items, err := ctrl.listItemsQry.Execute(c.Request.Context(), userID.(string)) if err != nil { c.JSON(http.StatusInternalServerError, dto.JSendError(err.Error(), http.StatusInternalServerError)) return } var response []*dto.ItemResponseDTO for _, item := range items { response = append(response, (&dto.ItemResponseDTO{}).FromEntity(item)) } c.JSON(http.StatusOK, dto.JSendSuccess(response)) } func (ctrl *ItemsController) DeleteItem(c *gin.Context) { userID, exists := c.Get("userID") if !exists { c.JSON(http.StatusUnauthorized, dto.JSendError("Unauthorized", http.StatusUnauthorized)) return } itemID := c.Param("id") if itemID == "" { c.JSON(http.StatusBadRequest, dto.JSendError("Item ID is required", http.StatusBadRequest)) return } err := ctrl.deleteItemCmd.Execute(c.Request.Context(), itemID, userID.(string)) if err != nil { if errors.Is(err, commands.ErrItemNotFound) { c.JSON(http.StatusNotFound, dto.JSendError("Item not found", http.StatusNotFound)) return } if errors.Is(err, commands.ErrUnauthorizedAccess) { c.JSON(http.StatusNotFound, dto.JSendError("Item not found", http.StatusNotFound)) return } c.JSON(http.StatusInternalServerError, dto.JSendError(err.Error(), http.StatusInternalServerError)) return } c.JSON(http.StatusNoContent, dto.JSendSuccess(nil)) }