package controller import ( "netidhub-saas-be/app/module/articles/request" "netidhub-saas-be/app/module/articles/service" "netidhub-saas-be/utils/paginator" "strconv" "github.com/gofiber/fiber/v2" "github.com/rs/zerolog" utilRes "netidhub-saas-be/utils/response" utilVal "netidhub-saas-be/utils/validator" ) type articlesController struct { articlesService service.ArticlesService Log zerolog.Logger } type ArticlesController interface { All(c *fiber.Ctx) error Show(c *fiber.Ctx) error ShowByOldId(c *fiber.Ctx) error Save(c *fiber.Ctx) error SaveThumbnail(c *fiber.Ctx) error Update(c *fiber.Ctx) error UpdateBanner(c *fiber.Ctx) error Delete(c *fiber.Ctx) error Viewer(c *fiber.Ctx) error SummaryStats(c *fiber.Ctx) error ArticlePerUserLevelStats(c *fiber.Ctx) error ArticleMonthlyStats(c *fiber.Ctx) error PublishScheduling(c *fiber.Ctx) error // Dynamic approval system methods SubmitForApproval(c *fiber.Ctx) error GetApprovalStatus(c *fiber.Ctx) error GetPendingApprovals(c *fiber.Ctx) error GetArticlesWaitingForApproval(c *fiber.Ctx) error } func NewArticlesController(articlesService service.ArticlesService, log zerolog.Logger) ArticlesController { return &articlesController{ articlesService: articlesService, Log: log, } } // All Articles // @Summary Get all Articles // @Description API for getting all Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param req query request.ArticlesQueryRequest false "query parameters" // @Param req query paginator.Pagination false "pagination parameters" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles [get] func (_i *articlesController) All(c *fiber.Ctx) error { paginate, err := paginator.Paginate(c) if err != nil { return err } reqContext := request.ArticlesQueryRequestContext{ Title: c.Query("title"), Description: c.Query("description"), Tags: c.Query("tags"), Category: c.Query("category"), CategoryId: c.Query("categoryId"), TypeId: c.Query("typeId"), StatusId: c.Query("statusId"), IsPublish: c.Query("isPublish"), IsDraft: c.Query("isDraft"), IsBanner: c.Query("isBanner"), ClientSlug: c.Query("clientSlug"), } req := reqContext.ToParamRequest() req.Pagination = paginate // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") articlesData, paging, err := _i.articlesService.All(authToken, req) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles list successfully retrieved"}, Data: articlesData, Meta: paging, }) } // Show Articles // @Summary Get one Articles // @Description API for getting one Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/{id} [get] func (_i *articlesController) Show(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") articlesData, err := _i.articlesService.Show(authToken, uint(id)) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles successfully retrieved"}, Data: articlesData, }) } // ShowByOldId Articles // @Summary Get one Articles // @Description API for getting one Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/old-id/{id} [get] func (_i *articlesController) ShowByOldId(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") articlesData, err := _i.articlesService.ShowByOldId(authToken, uint(id)) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles successfully retrieved"}, Data: articlesData, }) } // Save Articles // @Summary Create Articles // @Description API for create Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param payload body request.ArticlesCreateRequest true "Required payload" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles [post] func (_i *articlesController) Save(c *fiber.Ctx) error { req := new(request.ArticlesCreateRequest) if err := utilVal.ParseAndValidate(c, req); err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") dataResult, err := _i.articlesService.Save(authToken, *req) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles successfully created"}, Data: dataResult, }) } // SaveThumbnail Articles // @Summary Save Thumbnail Articles // @Description API for Save Thumbnail of Articles // @Tags Articles // @Security Bearer // @Produce json // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param id path int true "Articles ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/thumbnail/{id} [post] func (_i *articlesController) SaveThumbnail(c *fiber.Ctx) error { // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") err := _i.articlesService.SaveThumbnail(authToken, c) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Thumbnail of Articles successfully created"}, }) } // Update Articles // @Summary Update Articles // @Description API for update Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param payload body request.ArticlesUpdateRequest true "Required payload" // @Param id path int true "Articles ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/{id} [put] func (_i *articlesController) Update(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } req := new(request.ArticlesUpdateRequest) if err := utilVal.ParseAndValidate(c, req); err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") err = _i.articlesService.Update(authToken, uint(id), *req) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles successfully updated"}, }) } // UpdateBanner Articles // @Summary Update Banner Articles // @Description API for Update Banner Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param id path int true "Articles ID" // @Param isBanner query bool true "Articles Banner Status" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/banner/{id} [put] func (_i *articlesController) UpdateBanner(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } isBanner, err := strconv.ParseBool(c.Query("isBanner")) if err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") err = _i.articlesService.UpdateBanner(authToken, uint(id), isBanner) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles successfully banner updated"}, }) } // Delete Articles // @Summary Delete Articles // @Description API for delete Articles // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param id path int true "Articles ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/{id} [delete] func (_i *articlesController) Delete(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") err = _i.articlesService.Delete(authToken, uint(id)) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles successfully deleted"}, }) } // Viewer Articles // @Summary Viewer Articles Thumbnail // @Description API for View Thumbnail of Article // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param thumbnailName path string true "Articles Thumbnail Name" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/thumbnail/viewer/{thumbnailName} [get] func (_i *articlesController) Viewer(c *fiber.Ctx) error { // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") return _i.articlesService.Viewer(authToken, c) } // SummaryStats Articles // @Summary SummaryStats Articles // @Description API for Summary Stats of Article // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/statistic/summary [get] func (_i *articlesController) SummaryStats(c *fiber.Ctx) error { // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") response, err := _i.articlesService.SummaryStats(authToken) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Summary Stats of Articles successfully retrieved"}, Data: response, }) } // ArticlePerUserLevelStats Articles // @Summary ArticlePerUserLevelStats Articles // @Description API for ArticlePerUserLevelStats of Article // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param startDate query string false "start date" // @Param endDate query string false "start date" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/statistic/user-levels [get] func (_i *articlesController) ArticlePerUserLevelStats(c *fiber.Ctx) error { // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") startDate := c.Query("startDate") endDate := c.Query("endDate") response, err := _i.articlesService.ArticlePerUserLevelStats(authToken, &startDate, &endDate) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"ArticlePerUserLevelStats of Articles successfully retrieved"}, Data: response, }) } // ArticleMonthlyStats Articles // @Summary ArticleMonthlyStats Articles // @Description API for ArticleMonthlyStats of Article // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param year query int false "year" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/statistic/monthly [get] func (_i *articlesController) ArticleMonthlyStats(c *fiber.Ctx) error { // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") year := c.Query("year") yearInt, err := strconv.Atoi(year) if err != nil { return err } response, err := _i.articlesService.ArticleMonthlyStats(authToken, &yearInt) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"ArticleMonthlyStats of Articles successfully retrieved"}, Data: response, }) } // PublishScheduling Articles // @Summary PublishScheduling Articles // @Description API for Publish Schedule of Article // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param id query int false "article id" // @Param date query string false "publish date" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/publish-scheduling [post] func (_i *articlesController) PublishScheduling(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Query("id"), 10, 0) if err != nil { return err } date := c.Query("date") // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") err = _i.articlesService.PublishScheduling(authToken, uint(id), date) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Publish Scheduling of Articles successfully saved"}, }) } // SubmitForApproval Articles // @Summary Submit Article for Approval // @Description API for submitting article for approval workflow // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param id path int true "article id" // @Param req body request.SubmitForApprovalRequest false "approval request data" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/{id}/submit-approval [post] func (_i *articlesController) SubmitForApproval(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } var req request.SubmitForApprovalRequest if err := c.BodyParser(&req); err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") err = _i.articlesService.SubmitForApproval(authToken, uint(id), req.WorkflowId) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Article successfully submitted for approval"}, }) } // GetApprovalStatus Articles // @Summary Get Article Approval Status // @Description API for getting article approval status and workflow progress // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param id path int true "article id" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/{id}/approval-status [get] func (_i *articlesController) GetApprovalStatus(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) if err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") response, err := _i.articlesService.GetApprovalStatus(authToken, uint(id)) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Article approval status successfully retrieved"}, Data: response, }) } // GetPendingApprovals Articles // @Summary Get Pending Approvals // @Description API for getting articles pending approval for current user level // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param page query int false "page number" // @Param limit query int false "items per page" // @Param typeId query int false "article type id" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/pending-approval [get] func (_i *articlesController) GetPendingApprovals(c *fiber.Ctx) error { page, err := strconv.Atoi(c.Query("page", "1")) if err != nil { page = 1 } limit, err := strconv.Atoi(c.Query("limit", "10")) if err != nil { limit = 10 } // Parse typeId filter var typeId *int if typeIdStr := c.Query("typeId"); typeIdStr != "" { if parsedTypeId, err := strconv.Atoi(typeIdStr); err == nil { typeId = &parsedTypeId } } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") response, paging, err := _i.articlesService.GetPendingApprovals(authToken, page, limit, typeId) // Updated with typeId filter if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Pending approvals successfully retrieved"}, Data: response, Meta: paging, }) } // GetArticlesWaitingForApproval // @Summary Get articles waiting for approval by current user level // @Description API for getting articles that are waiting for approval by the current user's level // @Tags Articles // @Security Bearer // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param Authorization header string false "Insert your access token" default(Bearer ) // @Param page query int false "Page number" default(1) // @Param limit query int false "Items per page" default(10) // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError // @Failure 500 {object} response.InternalServerError // @Router /articles/waiting-for-approval [get] func (_i *articlesController) GetArticlesWaitingForApproval(c *fiber.Ctx) error { page, err := strconv.Atoi(c.Query("page", "1")) if err != nil { return err } limit, err := strconv.Atoi(c.Query("limit", "10")) if err != nil { return err } // Get Authorization token from header authToken := c.Get("Authorization") _i.Log.Info().Str("authToken", authToken).Msg("") responses, paging, err := _i.articlesService.GetArticlesWaitingForApproval(authToken, page, limit) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ Success: true, Messages: utilRes.Messages{"Articles waiting for approval retrieved successfully"}, Data: responses, Meta: paging, }) }