package v1 import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/service" applogger "github.com/gochat/gochat/pkg/logger" "github.com/gochat/gochat/pkg/pagination" "github.com/gochat/gochat/pkg/response" ) // FolderHandler handles Folder CRUD endpoints. type FolderHandler struct { svc *service.FolderService } // NewFolderHandler creates a new FolderHandler. func NewFolderHandler(svc *service.FolderService) *FolderHandler { return &FolderHandler{svc: svc} } // Create creates a new folder. // POST /api/v1/accounts/:account_id/portals/:portal_id/folders func (h *FolderHandler) Create(c *gin.Context) { portalID, err := strconv.ParseUint(c.Param("portal_id"), 10, 64) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid portal_id") return } var req service.CreateFolderRequest if err := c.ShouldBindJSON(&req); err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error()) return } folder, err := h.svc.Create(c.Request.Context(), uint(portalID), &req) if err != nil { applogger.L().Errorf("Create folder: %v", err) response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "failed to create folder") return } response.Created(c, folder) } // Get retrieves a folder by ID. // GET /api/v1/accounts/:account_id/portals/:portal_id/folders/:folder_id func (h *FolderHandler) Get(c *gin.Context) { folderID, err := strconv.ParseUint(c.Param("folder_id"), 10, 64) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid folder_id") return } folder, err := h.svc.GetByID(c.Request.Context(), uint(folderID)) if err != nil { applogger.L().Errorf("Get folder: %v", err) response.AbortWithStatusError(c, http.StatusNotFound, response.ErrNotFound, "folder not found") return } response.OK(c, folder) } // Update modifies an existing folder. // PUT /api/v1/accounts/:account_id/portals/:portal_id/folders/:folder_id func (h *FolderHandler) Update(c *gin.Context) { folderID, err := strconv.ParseUint(c.Param("folder_id"), 10, 64) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid folder_id") return } var req service.UpdateFolderRequest if err := c.ShouldBindJSON(&req); err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error()) return } folder, err := h.svc.Update(c.Request.Context(), uint(folderID), &req) if err != nil { applogger.L().Errorf("Update folder: %v", err) response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "failed to update folder") return } response.OK(c, folder) } // Delete removes a folder. // DELETE /api/v1/accounts/:account_id/portals/:portal_id/folders/:folder_id func (h *FolderHandler) Delete(c *gin.Context) { folderID, err := strconv.ParseUint(c.Param("folder_id"), 10, 64) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid folder_id") return } if err := h.svc.Delete(c.Request.Context(), uint(folderID)); err != nil { applogger.L().Errorf("Delete folder: %v", err) response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "failed to delete folder") return } response.NoContent(c) } // List returns all folders for a portal (paginated). // GET /api/v1/accounts/:account_id/portals/:portal_id/folders func (h *FolderHandler) List(c *gin.Context) { portalID, err := strconv.ParseUint(c.Param("portal_id"), 10, 64) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid portal_id") return } pg := pagination.Parse(c) folders, count, err := h.svc.ListByPortalID(c.Request.Context(), uint(portalID), pg.Page, pg.PerPage) if err != nil { applogger.L().Errorf("List folders: %v", err) response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "failed to list folders") return } response.OKWithMeta(c, folders, pg.Page, pg.PerPage, count) }