qudoco-be/app/module/client_approval_settings/service/client_approval_settings.se...

327 lines
11 KiB
Go

package service
import (
"fmt"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/client_approval_settings/mapper"
"web-qudo-be/app/module/client_approval_settings/repository"
"web-qudo-be/app/module/client_approval_settings/request"
"web-qudo-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
}