diff --git a/app/middleware/register.middleware.go b/app/middleware/register.middleware.go index 814b533..3b8a1ba 100644 --- a/app/middleware/register.middleware.go +++ b/app/middleware/register.middleware.go @@ -58,7 +58,7 @@ func (m *Middleware) Register(db *database.Database) { m.App.Use(cors.New(cors.Config{ Next: utilsSvc.IsEnabled(m.Cfg.Middleware.Cors.Enable), - AllowOrigins: "http://localhost:3000, http://localhost:4000, https://dev.mikulnews.com, https://n8n.qudoco.com, https://narasiahli.com", + AllowOrigins: "http://localhost:3000, http://localhost:4000, https://dev.mikulnews.com, https://n8n.qudoco.com, https://narasiahli.com, https://dev.asuransiaman.com, https://dev.beritabumn.com, https://dev.kabarharapan.com, https://dev.kebaikanindonesia.com, https://dev.isukini.com", AllowMethods: "HEAD, GET, POST, PUT, DELETE, OPTION, PATCH", AllowHeaders: "Origin, Content-Type, Accept, Accept-Language, Authorization, X-Requested-With, Access-Control-Request-Method, Access-Control-Request-Headers, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, X-Csrf-Token, Cookie, Set-Cookie, X-Client-Key", ExposeHeaders: "Content-Length, Content-Type", diff --git a/app/module/article_approval_flows/repository/article_approval_flows.repository.go b/app/module/article_approval_flows/repository/article_approval_flows.repository.go index fa3e24d..9d8013a 100644 --- a/app/module/article_approval_flows/repository/article_approval_flows.repository.go +++ b/app/module/article_approval_flows/repository/article_approval_flows.repository.go @@ -199,6 +199,11 @@ func (_i *articleApprovalFlowsRepository) GetPendingApprovals(clientId *uuid.UUI query = query.Where("articles.category_id = ?", categoryId) } + if typeId, ok := filters["type_id"]; ok { + query = query.Joins("JOIN articles ON article_approval_flows.article_id = articles.id") + query = query.Where("articles.type_id = ?", typeId) + } + if search, ok := filters["search"]; ok { query = query.Joins("JOIN articles ON article_approval_flows.article_id = articles.id") query = query.Where("articles.title ILIKE ? OR articles.description ILIKE ?", fmt.Sprintf("%%%s%%", search), fmt.Sprintf("%%%s%%", search)) diff --git a/app/module/article_files/response/article_files.response.go b/app/module/article_files/response/article_files.response.go index 465d9d2..0993739 100644 --- a/app/module/article_files/response/article_files.response.go +++ b/app/module/article_files/response/article_files.response.go @@ -4,21 +4,21 @@ import "time" type ArticleFilesResponse struct { ID uint `json:"id"` - ArticleId uint `json:"article_id"` - FilePath *string `json:"file_path"` - FileUrl *string `json:"file_url"` - FileName *string `json:"file_name"` - FileThumbnail *string `json:"file_thumbnail"` - FileAlt *string `json:"file_alt"` - WidthPixel *string `json:"width_pixel"` - HeightPixel *string `json:"height_pixel"` + ArticleId uint `json:"articleId"` + FilePath *string `json:"filePath"` + FileUrl *string `json:"fileUrl"` + FileName *string `json:"fileName"` + FileThumbnail *string `json:"fileThumbnail"` + FileAlt *string `json:"fileAlt"` + WidthPixel *string `json:"widthPixel"` + HeightPixel *string `json:"heightPixel"` Size *string `json:"size"` - DownloadCount *int `json:"download_count"` - CreatedById int `json:"created_by_id"` - StatusId int `json:"status_id"` - IsPublish *bool `json:"is_publish"` - PublishedAt *time.Time `json:"published_at"` - IsActive bool `json:"is_active"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + DownloadCount *int `json:"downloadCount"` + CreatedById int `json:"createdById"` + StatusId int `json:"statusId"` + IsPublish *bool `json:"isPublish"` + PublishedAt *time.Time `json:"publishedAt"` + IsActive bool `json:"isActive"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } diff --git a/app/module/articles/controller/articles.controller.go b/app/module/articles/controller/articles.controller.go index 6ca2948..b10766a 100644 --- a/app/module/articles/controller/articles.controller.go +++ b/app/module/articles/controller/articles.controller.go @@ -589,6 +589,7 @@ func (_i *articlesController) GetApprovalStatus(c *fiber.Ctx) error { // @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 @@ -605,13 +606,21 @@ func (_i *articlesController) GetPendingApprovals(c *fiber.Ctx) error { 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 ClientId from context clientId := middleware.GetClientID(c) // Get Authorization token from header authToken := c.Get("Authorization") - response, paging, err := _i.articlesService.GetPendingApprovals(clientId, authToken, page, limit) + response, paging, err := _i.articlesService.GetPendingApprovals(clientId, authToken, page, limit, typeId) // Updated with typeId filter if err != nil { return err } diff --git a/app/module/articles/response/articles.response.go b/app/module/articles/response/articles.response.go index e90af8d..50ee5bc 100644 --- a/app/module/articles/response/articles.response.go +++ b/app/module/articles/response/articles.response.go @@ -62,51 +62,51 @@ type ArticleMonthlyStats struct { // ArticleApprovalStatusResponse represents the approval status of an article type ArticleApprovalStatusResponse struct { - ArticleId uint `json:"article_id"` - WorkflowId *uint `json:"workflow_id"` - WorkflowName *string `json:"workflow_name"` - CurrentStep int `json:"current_step"` - TotalSteps int `json:"total_steps"` - Status string `json:"status"` // "pending", "in_progress", "approved", "rejected", "revision_requested" - CurrentApprover *string `json:"current_approver"` - SubmittedAt *time.Time `json:"submitted_at"` - LastActionAt *time.Time `json:"last_action_at"` - Progress float64 `json:"progress"` // percentage complete - CanApprove bool `json:"can_approve"` // whether current user can approve - NextStep *string `json:"next_step"` + ArticleId uint `json:"articleId"` + WorkflowId *uint `json:"workflowId"` + WorkflowName *string `json:"workflowName"` + CurrentStep int `json:"currentStep"` + TotalSteps int `json:"totalSteps"` + Status string `json:"status"` // "pending", "in_progress", "approved", "rejected", "revision_requested" + CurrentApprover *string `json:"currentApprover"` + SubmittedAt *time.Time `json:"submittedAt"` + LastActionAt *time.Time `json:"lastActionAt"` + Progress float64 `json:"progress"` // percentage complete + CanApprove bool `json:"canApprove"` // whether current user can approve + NextStep *string `json:"nextStep"` } // ArticleApprovalQueueResponse represents an article in the approval queue type ArticleApprovalQueueResponse struct { - ID uint `json:"id"` - Title string `json:"title"` - Slug string `json:"slug"` - Description string `json:"description"` - CategoryName string `json:"category_name"` - AuthorName string `json:"author_name"` - SubmittedAt time.Time `json:"submitted_at"` - CurrentStep int `json:"current_step"` - TotalSteps int `json:"total_steps"` - Priority string `json:"priority"` // "low", "medium", "high", "urgent" - DaysInQueue int `json:"days_in_queue"` - WorkflowName string `json:"workflow_name"` - CanApprove bool `json:"can_approve"` - EstimatedTime string `json:"estimated_time"` // estimated time to complete approval + ID uint `json:"id"` + Title string `json:"title"` + Slug string `json:"slug"` + Description string `json:"description"` + CategoryName string `json:"categoryName"` + AuthorName string `json:"authorName"` + SubmittedAt time.Time `json:"submittedAt"` + CurrentStep int `json:"currentStep"` + TotalSteps int `json:"totalSteps"` + Priority string `json:"priority"` // "low", "medium", "high", "urgent" + DaysInQueue int `json:"daysInQueue"` + WorkflowName string `json:"workflowName"` + CanApprove bool `json:"canApprove"` + EstimatedTime string `json:"estimatedTime"` // estimated time to complete approval } // ClientApprovalSettingsResponse represents client-level approval settings type ClientApprovalSettingsResponse struct { - ClientId string `json:"client_id"` - RequiresApproval bool `json:"requires_approval"` - DefaultWorkflowId *uint `json:"default_workflow_id"` - DefaultWorkflowName *string `json:"default_workflow_name"` - AutoPublishArticles bool `json:"auto_publish_articles"` - ApprovalExemptUsers []uint `json:"approval_exempt_users"` - ApprovalExemptRoles []uint `json:"approval_exempt_roles"` - ApprovalExemptCategories []uint `json:"approval_exempt_categories"` - RequireApprovalFor []string `json:"require_approval_for"` - SkipApprovalFor []string `json:"skip_approval_for"` - IsActive bool `json:"is_active"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ClientId string `json:"clientId"` + RequiresApproval bool `json:"requiresApproval"` + DefaultWorkflowId *uint `json:"defaultWorkflowId"` + DefaultWorkflowName *string `json:"defaultWorkflowName"` + AutoPublishArticles bool `json:"autoPublishArticles"` + ApprovalExemptUsers []uint `json:"approvalExemptUsers"` + ApprovalExemptRoles []uint `json:"approvalExemptRoles"` + ApprovalExemptCategories []uint `json:"approvalExemptCategories"` + RequireApprovalFor []string `json:"requireApprovalFor"` + SkipApprovalFor []string `json:"skipApprovalFor"` + IsActive bool `json:"isActive"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } diff --git a/app/module/articles/service/articles.service.go b/app/module/articles/service/articles.service.go index 0794084..94e574c 100644 --- a/app/module/articles/service/articles.service.go +++ b/app/module/articles/service/articles.service.go @@ -76,7 +76,7 @@ type ArticlesService interface { SubmitForApproval(clientId *uuid.UUID, articleId uint, authToken string, workflowId *uint) error GetApprovalStatus(clientId *uuid.UUID, articleId uint) (*response.ArticleApprovalStatusResponse, error) GetArticlesWaitingForApproval(clientId *uuid.UUID, authToken string, page, limit int) ([]*response.ArticleApprovalQueueResponse, paginator.Pagination, error) - GetPendingApprovals(clientId *uuid.UUID, authToken string, page, limit int) ([]*response.ArticleApprovalQueueResponse, paginator.Pagination, error) + GetPendingApprovals(clientId *uuid.UUID, authToken string, page, limit int, typeId *int) ([]*response.ArticleApprovalQueueResponse, paginator.Pagination, error) // Updated with typeId filter // No-approval system methods CheckApprovalRequired(clientId *uuid.UUID, articleId uint, userId uint, userLevelId uint) (bool, error) @@ -872,15 +872,21 @@ func (_i *articlesService) GetApprovalStatus(clientId *uuid.UUID, articleId uint } // GetPendingApprovals gets articles pending approval for a specific user level -func (_i *articlesService) GetPendingApprovals(clientId *uuid.UUID, authToken string, page, limit int) ([]*response.ArticleApprovalQueueResponse, paginator.Pagination, error) { +func (_i *articlesService) GetPendingApprovals(clientId *uuid.UUID, authToken string, page, limit int, typeId *int) ([]*response.ArticleApprovalQueueResponse, paginator.Pagination, error) { // Extract user info from auth token user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken) if user == nil { return nil, paginator.Pagination{}, errors.New("user not found from auth token") } + // Prepare filters + filters := make(map[string]interface{}) + if typeId != nil { + filters["type_id"] = *typeId + } + // Get pending approvals for the user level - approvalFlows, paging, err := _i.ArticleApprovalFlowsRepo.GetPendingApprovalsByUserLevel(clientId, user.UserLevelId, page, limit) + approvalFlows, paging, err := _i.ArticleApprovalFlowsRepo.GetPendingApprovals(clientId, user.UserLevelId, page, limit, filters) if err != nil { return nil, paging, err }