feat: fixing articles and content submissions
continuous-integration/drone/push Build is passing Details

This commit is contained in:
hanif salafi 2026-04-14 10:27:28 +07:00
parent a22dda8c8b
commit 7b41a9c7af
5 changed files with 31 additions and 18 deletions

View File

@ -116,7 +116,7 @@ func (_i *articlesRepository) GetAll(clientId *uuid.UUID, userLevelId *uint, req
if mode == "approver" { if mode == "approver" {
query = query.Where("articles.is_draft = ?", false) query = query.Where("articles.is_draft = ?", false)
query = query.Joins("JOIN users acu ON acu.id = articles.created_by_id"). query = query.Joins("JOIN users acu ON acu.id = articles.created_by_id").
Where("acu.user_level_id = ?", 2) Where("acu.user_role_id = ?", 3)
} }
} }

View File

@ -30,7 +30,7 @@ type ArticlesQueryRequest struct {
StartDate *time.Time `json:"startDate"` StartDate *time.Time `json:"startDate"`
EndDate *time.Time `json:"endDate"` EndDate *time.Time `json:"endDate"`
Pagination *paginator.Pagination `json:"pagination"` Pagination *paginator.Pagination `json:"pagination"`
// myContentMode: "own" = current user's articles (any level); "approver" = non-draft from contributors (level 2) for approver history // myContentMode: "own" = current user's articles (any level); "approver" = non-draft from contributors (user_role_id 3) for approver history
MyContentMode *string `json:"myContentMode"` MyContentMode *string `json:"myContentMode"`
} }

View File

@ -120,7 +120,15 @@ func NewArticlesService(
} }
} }
const myContentApproverMinLevel = uint(3) const (
userRoleAdmin = uint(1)
userRoleApprover = uint(2)
userRoleContributor = uint(3)
)
func canUseMyContentApproverMode(roleID uint) bool {
return roleID == userRoleApprover || roleID == userRoleAdmin
}
// All implement interface of ArticlesService // All implement interface of ArticlesService
func (_i *articlesService) All(clientId *uuid.UUID, authToken string, req request.ArticlesQueryRequest) (articless []*response.ArticlesResponse, paging paginator.Pagination, err error) { func (_i *articlesService) All(clientId *uuid.UUID, authToken string, req request.ArticlesQueryRequest) (articless []*response.ArticlesResponse, paging paginator.Pagination, err error) {
@ -139,8 +147,8 @@ func (_i *articlesService) All(clientId *uuid.UUID, authToken string, req reques
userLevelId = nil userLevelId = nil
_i.Log.Info().Uint("userId", user.ID).Msg("myContentMode=own: list own articles without level visibility filter") _i.Log.Info().Uint("userId", user.ID).Msg("myContentMode=own: list own articles without level visibility filter")
case "approver": case "approver":
if user.UserLevelId != myContentApproverMinLevel { if !canUseMyContentApproverMode(user.UserRoleId) {
return nil, paging, errors.New("myContentMode approver requires user level 3") return nil, paging, errors.New("myContentMode approver requires approver or admin role")
} }
userLevelId = nil userLevelId = nil
_i.Log.Info().Msg("myContentMode=approver: list contributor non-draft articles") _i.Log.Info().Msg("myContentMode=approver: list contributor non-draft articles")

View File

@ -33,13 +33,18 @@ import (
) )
const ( const (
cmsSubmissionPending = "pending" cmsSubmissionPending = "pending"
cmsSubmissionApproved = "approved" cmsSubmissionApproved = "approved"
cmsSubmissionRejected = "rejected" cmsSubmissionRejected = "rejected"
userLevelContributor = uint(2) userRoleAdmin = uint(1)
userLevelApprover = uint(3) userRoleApprover = uint(2)
userRoleContributor = uint(3)
) )
func canApproveCmsSubmissions(roleID uint) bool {
return roleID == userRoleApprover || roleID == userRoleAdmin
}
type CmsContentSubmissionsService interface { type CmsContentSubmissionsService interface {
Submit(clientID *uuid.UUID, user *users.Users, req *request.SubmitCmsContentSubmissionRequest) (*entity.CmsContentSubmission, error) Submit(clientID *uuid.UUID, user *users.Users, req *request.SubmitCmsContentSubmissionRequest) (*entity.CmsContentSubmission, error)
List(clientID *uuid.UUID, user *users.Users, status string, mineOnly bool, p *paginator.Pagination) ([]response.CmsContentSubmissionListItem, *paginator.Pagination, error) List(clientID *uuid.UUID, user *users.Users, status string, mineOnly bool, p *paginator.Pagination) ([]response.CmsContentSubmissionListItem, *paginator.Pagination, error)
@ -102,8 +107,8 @@ func (_i *cmsContentSubmissionsService) Submit(clientID *uuid.UUID, user *users.
if clientID == nil || user == nil { if clientID == nil || user == nil {
return nil, errors.New("unauthorized") return nil, errors.New("unauthorized")
} }
if user.UserLevelId != userLevelContributor { if user.UserRoleId != userRoleContributor {
return nil, errors.New("only contributor (user level 2) can submit CMS drafts") return nil, errors.New("only contributor role can submit CMS drafts")
} }
domain := strings.TrimSpace(strings.ToLower(req.Domain)) domain := strings.TrimSpace(strings.ToLower(req.Domain))
if domain == "" { if domain == "" {
@ -141,7 +146,7 @@ func (_i *cmsContentSubmissionsService) List(clientID *uuid.UUID, user *users.Us
var submittedBy *uint var submittedBy *uint
if mineOnly { if mineOnly {
submittedBy = &user.ID submittedBy = &user.ID
} else if user.UserLevelId == userLevelContributor { } else if user.UserRoleId == userRoleContributor {
submittedBy = &user.ID submittedBy = &user.ID
} }
statusArg := status statusArg := status
@ -178,8 +183,8 @@ func (_i *cmsContentSubmissionsService) Approve(clientID *uuid.UUID, user *users
if clientID == nil || user == nil { if clientID == nil || user == nil {
return errors.New("unauthorized") return errors.New("unauthorized")
} }
if user.UserLevelId != userLevelApprover { if !canApproveCmsSubmissions(user.UserRoleId) {
return errors.New("only approver (user level 3) can approve CMS submissions") return errors.New("only approver or admin role can approve CMS submissions")
} }
row, err := _i.Repo.FindByID(*clientID, id) row, err := _i.Repo.FindByID(*clientID, id)
if err != nil { if err != nil {
@ -203,8 +208,8 @@ func (_i *cmsContentSubmissionsService) Reject(clientID *uuid.UUID, user *users.
if clientID == nil || user == nil { if clientID == nil || user == nil {
return errors.New("unauthorized") return errors.New("unauthorized")
} }
if user.UserLevelId != userLevelApprover { if !canApproveCmsSubmissions(user.UserRoleId) {
return errors.New("only approver (user level 3) can reject CMS submissions") return errors.New("only approver or admin role can reject CMS submissions")
} }
row, err := _i.Repo.FindByID(*clientID, id) row, err := _i.Repo.FindByID(*clientID, id)
if err != nil { if err != nil {

View File

@ -9,7 +9,7 @@ idle-timeout = 5 # As seconds
print-routes = false print-routes = false
prefork = false prefork = false
# false: CMS preview URLs use http://localhost + port above. true: use domain (e.g. https://qudo.id/api). # false: CMS preview URLs use http://localhost + port above. true: use domain (e.g. https://qudo.id/api).
production = false production = true
body-limit = 1048576000 # "100 * 1024 * 1024" body-limit = 1048576000 # "100 * 1024 * 1024"
[db.postgres] [db.postgres]