327 lines
11 KiB
Go
327 lines
11 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"web-medols-be/app/database/entity"
|
||
|
|
"web-medols-be/app/module/client_approval_settings/mapper"
|
||
|
|
"web-medols-be/app/module/client_approval_settings/repository"
|
||
|
|
"web-medols-be/app/module/client_approval_settings/request"
|
||
|
|
"web-medols-be/app/module/client_approval_settings/response"
|
||
|
|
|
||
|
|
"github.com/google/uuid"
|
||
|
|
"github.com/rs/zerolog"
|
||
|
|
)
|
||
|
|
|
||
|
|
type clientApprovalSettingsService struct {
|
||
|
|
clientApprovalSettingsRepo repository.ClientApprovalSettingsRepository
|
||
|
|
Log zerolog.Logger
|
||
|
|
}
|
||
|
|
|
||
|
|
type ClientApprovalSettingsService interface {
|
||
|
|
GetByClientId(clientId *uuid.UUID) (*response.ClientApprovalSettingsResponse, error)
|
||
|
|
Create(clientId *uuid.UUID, req request.CreateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error)
|
||
|
|
Update(clientId *uuid.UUID, req request.UpdateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error)
|
||
|
|
Delete(clientId *uuid.UUID) error
|
||
|
|
ToggleApprovalRequirement(clientId *uuid.UUID, requiresApproval bool) error
|
||
|
|
SetDefaultWorkflow(clientId *uuid.UUID, workflowId *uint) error
|
||
|
|
AddExemptUser(clientId *uuid.UUID, userId uint) error
|
||
|
|
RemoveExemptUser(clientId *uuid.UUID, userId uint) error
|
||
|
|
AddExemptRole(clientId *uuid.UUID, roleId uint) error
|
||
|
|
RemoveExemptRole(clientId *uuid.UUID, roleId uint) error
|
||
|
|
AddExemptCategory(clientId *uuid.UUID, categoryId uint) error
|
||
|
|
RemoveExemptCategory(clientId *uuid.UUID, categoryId uint) error
|
||
|
|
CheckIfApprovalRequired(clientId *uuid.UUID, userId uint, userLevelId uint, categoryId uint, contentType string) (bool, error)
|
||
|
|
|
||
|
|
// Enhanced methods for dynamic approval management
|
||
|
|
EnableApprovalWithTransition(clientId *uuid.UUID, defaultWorkflowId *uint) error
|
||
|
|
DisableApprovalWithAutoPublish(clientId *uuid.UUID, reason string) error
|
||
|
|
HandlePendingApprovalsOnDisable(clientId *uuid.UUID, action string) error // "auto_approve", "keep_pending", "reset_to_draft"
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewClientApprovalSettingsService(
|
||
|
|
clientApprovalSettingsRepo repository.ClientApprovalSettingsRepository,
|
||
|
|
log zerolog.Logger,
|
||
|
|
) ClientApprovalSettingsService {
|
||
|
|
return &clientApprovalSettingsService{
|
||
|
|
clientApprovalSettingsRepo: clientApprovalSettingsRepo,
|
||
|
|
Log: log,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) GetByClientId(clientId *uuid.UUID) (*response.ClientApprovalSettingsResponse, error) {
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
// Return default settings if none found
|
||
|
|
return &response.ClientApprovalSettingsResponse{
|
||
|
|
ClientId: clientId.String(),
|
||
|
|
RequiresApproval: true, // Default to requiring approval
|
||
|
|
AutoPublishArticles: false,
|
||
|
|
ApprovalExemptUsers: []uint{},
|
||
|
|
ApprovalExemptRoles: []uint{},
|
||
|
|
ApprovalExemptCategories: []uint{},
|
||
|
|
RequireApprovalFor: []string{},
|
||
|
|
SkipApprovalFor: []string{},
|
||
|
|
IsActive: true,
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
return mapper.ClientApprovalSettingsResponseMapper(_i.Log, clientId, settings), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) Create(clientId *uuid.UUID, req request.CreateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) {
|
||
|
|
// Check if settings already exist
|
||
|
|
existing, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
if existing != nil {
|
||
|
|
return nil, fmt.Errorf("approval settings already exist for this client")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create new settings
|
||
|
|
settings := &entity.ClientApprovalSettings{
|
||
|
|
RequiresApproval: &req.RequiresApproval,
|
||
|
|
DefaultWorkflowId: req.DefaultWorkflowId,
|
||
|
|
AutoPublishArticles: &req.AutoPublishArticles,
|
||
|
|
ApprovalExemptUsers: req.ApprovalExemptUsers,
|
||
|
|
ApprovalExemptRoles: req.ApprovalExemptRoles,
|
||
|
|
ApprovalExemptCategories: req.ApprovalExemptCategories,
|
||
|
|
RequireApprovalFor: req.RequireApprovalFor,
|
||
|
|
SkipApprovalFor: req.SkipApprovalFor,
|
||
|
|
IsActive: &req.IsActive,
|
||
|
|
}
|
||
|
|
|
||
|
|
createdSettings, err := _i.clientApprovalSettingsRepo.Create(clientId, settings)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
return mapper.ClientApprovalSettingsResponseMapper(_i.Log, clientId, createdSettings), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) Update(clientId *uuid.UUID, req request.UpdateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) {
|
||
|
|
// Get existing settings
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
return nil, fmt.Errorf("approval settings not found for this client")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update fields if provided
|
||
|
|
if req.RequiresApproval != nil {
|
||
|
|
settings.RequiresApproval = req.RequiresApproval
|
||
|
|
}
|
||
|
|
if req.DefaultWorkflowId != nil {
|
||
|
|
settings.DefaultWorkflowId = *req.DefaultWorkflowId
|
||
|
|
}
|
||
|
|
if req.AutoPublishArticles != nil {
|
||
|
|
settings.AutoPublishArticles = req.AutoPublishArticles
|
||
|
|
}
|
||
|
|
if req.ApprovalExemptUsers != nil {
|
||
|
|
settings.ApprovalExemptUsers = req.ApprovalExemptUsers
|
||
|
|
}
|
||
|
|
if req.ApprovalExemptRoles != nil {
|
||
|
|
settings.ApprovalExemptRoles = req.ApprovalExemptRoles
|
||
|
|
}
|
||
|
|
if req.ApprovalExemptCategories != nil {
|
||
|
|
settings.ApprovalExemptCategories = req.ApprovalExemptCategories
|
||
|
|
}
|
||
|
|
if req.RequireApprovalFor != nil {
|
||
|
|
settings.RequireApprovalFor = req.RequireApprovalFor
|
||
|
|
}
|
||
|
|
if req.SkipApprovalFor != nil {
|
||
|
|
settings.SkipApprovalFor = req.SkipApprovalFor
|
||
|
|
}
|
||
|
|
if req.IsActive != nil {
|
||
|
|
settings.IsActive = req.IsActive
|
||
|
|
}
|
||
|
|
|
||
|
|
updatedSettings, err := _i.clientApprovalSettingsRepo.Update(clientId, settings)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
return mapper.ClientApprovalSettingsResponseMapper(_i.Log, clientId, updatedSettings), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) Delete(clientId *uuid.UUID) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.Delete(clientId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) ToggleApprovalRequirement(clientId *uuid.UUID, requiresApproval bool) error {
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
return fmt.Errorf("approval settings not found for this client")
|
||
|
|
}
|
||
|
|
|
||
|
|
settings.RequiresApproval = &requiresApproval
|
||
|
|
_, err = _i.clientApprovalSettingsRepo.Update(clientId, settings)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) SetDefaultWorkflow(clientId *uuid.UUID, workflowId *uint) error {
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
return fmt.Errorf("approval settings not found for this client")
|
||
|
|
}
|
||
|
|
|
||
|
|
settings.DefaultWorkflowId = workflowId
|
||
|
|
_, err = _i.clientApprovalSettingsRepo.Update(clientId, settings)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) AddExemptUser(clientId *uuid.UUID, userId uint) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.AddExemptUser(clientId, userId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) RemoveExemptUser(clientId *uuid.UUID, userId uint) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.RemoveExemptUser(clientId, userId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) AddExemptRole(clientId *uuid.UUID, roleId uint) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.AddExemptRole(clientId, roleId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) RemoveExemptRole(clientId *uuid.UUID, roleId uint) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.RemoveExemptRole(clientId, roleId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) AddExemptCategory(clientId *uuid.UUID, categoryId uint) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.AddExemptCategory(clientId, categoryId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) RemoveExemptCategory(clientId *uuid.UUID, categoryId uint) error {
|
||
|
|
return _i.clientApprovalSettingsRepo.RemoveExemptCategory(clientId, categoryId)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) CheckIfApprovalRequired(clientId *uuid.UUID, userId uint, userLevelId uint, categoryId uint, contentType string) (bool, error) {
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindActiveSettings(clientId)
|
||
|
|
if err != nil {
|
||
|
|
return true, err // Default to requiring approval on error
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
return true, nil // Default to requiring approval if no settings
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if approval is disabled
|
||
|
|
if settings.RequiresApproval != nil && !*settings.RequiresApproval {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check user exemption
|
||
|
|
for _, exemptUserId := range settings.ApprovalExemptUsers {
|
||
|
|
if exemptUserId == userId {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check role exemption
|
||
|
|
for _, exemptRoleId := range settings.ApprovalExemptRoles {
|
||
|
|
if exemptRoleId == userLevelId {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check category exemption
|
||
|
|
for _, exemptCategoryId := range settings.ApprovalExemptCategories {
|
||
|
|
if exemptCategoryId == categoryId {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check content type exemptions
|
||
|
|
for _, skipType := range settings.SkipApprovalFor {
|
||
|
|
if skipType == contentType {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if content type requires approval
|
||
|
|
for _, requireType := range settings.RequireApprovalFor {
|
||
|
|
if requireType == contentType {
|
||
|
|
return true, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Default to requiring approval
|
||
|
|
return true, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) EnableApprovalWithTransition(clientId *uuid.UUID, defaultWorkflowId *uint) error {
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
// Create new settings
|
||
|
|
settings = &entity.ClientApprovalSettings{
|
||
|
|
RequiresApproval: &[]bool{true}[0],
|
||
|
|
DefaultWorkflowId: defaultWorkflowId,
|
||
|
|
AutoPublishArticles: &[]bool{false}[0],
|
||
|
|
IsActive: &[]bool{true}[0],
|
||
|
|
}
|
||
|
|
_, err = _i.clientApprovalSettingsRepo.Create(clientId, settings)
|
||
|
|
} else {
|
||
|
|
// Update existing settings
|
||
|
|
settings.RequiresApproval = &[]bool{true}[0]
|
||
|
|
settings.DefaultWorkflowId = defaultWorkflowId
|
||
|
|
settings.AutoPublishArticles = &[]bool{false}[0]
|
||
|
|
settings.IsActive = &[]bool{true}[0]
|
||
|
|
_, err = _i.clientApprovalSettingsRepo.Update(clientId, settings)
|
||
|
|
}
|
||
|
|
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) DisableApprovalWithAutoPublish(clientId *uuid.UUID, reason string) error {
|
||
|
|
settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if settings == nil {
|
||
|
|
return fmt.Errorf("approval settings not found for this client")
|
||
|
|
}
|
||
|
|
|
||
|
|
settings.RequiresApproval = &[]bool{false}[0]
|
||
|
|
settings.AutoPublishArticles = &[]bool{true}[0]
|
||
|
|
settings.IsActive = &[]bool{true}[0]
|
||
|
|
|
||
|
|
_, err = _i.clientApprovalSettingsRepo.Update(clientId, settings)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
func (_i *clientApprovalSettingsService) HandlePendingApprovalsOnDisable(clientId *uuid.UUID, action string) error {
|
||
|
|
// This would typically interact with article approval flows
|
||
|
|
// For now, just log the action
|
||
|
|
_i.Log.Info().
|
||
|
|
Str("client_id", clientId.String()).
|
||
|
|
Str("action", action).
|
||
|
|
Msg("Handling pending approvals on disable")
|
||
|
|
|
||
|
|
// TODO: Implement actual logic based on action:
|
||
|
|
// - "auto_approve": Auto approve all pending articles
|
||
|
|
// - "keep_pending": Keep articles in pending state
|
||
|
|
// - "reset_to_draft": Reset articles to draft state
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|