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

539 lines
17 KiB
Go

package service
import (
"fmt"
"netidhub-saas-be/app/database/entity"
"netidhub-saas-be/app/module/client_approval_settings/mapper"
"netidhub-saas-be/app/module/client_approval_settings/repository"
"netidhub-saas-be/app/module/client_approval_settings/request"
"netidhub-saas-be/app/module/client_approval_settings/response"
usersRepository "netidhub-saas-be/app/module/users/repository"
utilSvc "netidhub-saas-be/utils/service"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
type clientApprovalSettingsService struct {
clientApprovalSettingsRepo repository.ClientApprovalSettingsRepository
UsersRepo usersRepository.UsersRepository
Log zerolog.Logger
}
type ClientApprovalSettingsService interface {
GetByClientId(authToken string) (*response.ClientApprovalSettingsResponse, error)
Create(authToken string, req request.CreateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error)
Update(authToken string, req request.UpdateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error)
Delete(authToken string) error
ToggleApprovalRequirement(authToken string, requiresApproval bool) error
SetDefaultWorkflow(authToken string, workflowId *uint) error
AddExemptUser(authToken string, userId uint) error
RemoveExemptUser(authToken string, userId uint) error
AddExemptRole(authToken string, roleId uint) error
RemoveExemptRole(authToken string, roleId uint) error
AddExemptCategory(authToken string, categoryId uint) error
RemoveExemptCategory(authToken string, categoryId uint) error
CheckIfApprovalRequired(authToken string, userId uint, userLevelId uint, categoryId uint, contentType string) (bool, error)
// Enhanced methods for dynamic approval management
EnableApprovalWithTransition(authToken string, defaultWorkflowId *uint) error
DisableApprovalWithAutoPublish(authToken string, reason string) error
HandlePendingApprovalsOnDisable(authToken string, action string) error // "auto_approve", "keep_pending", "reset_to_draft"
}
func NewClientApprovalSettingsService(
clientApprovalSettingsRepo repository.ClientApprovalSettingsRepository,
usersRepo usersRepository.UsersRepository,
log zerolog.Logger,
) ClientApprovalSettingsService {
return &clientApprovalSettingsService{
clientApprovalSettingsRepo: clientApprovalSettingsRepo,
UsersRepo: usersRepo,
Log: log,
}
}
func (_i *clientApprovalSettingsService) GetByClientId(authToken string) (*response.ClientApprovalSettingsResponse, error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return nil, fmt.Errorf("clientId not found in auth token")
}
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(authToken string, req request.CreateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return nil, fmt.Errorf("clientId not found in auth token")
}
// 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(authToken string, req request.UpdateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return nil, fmt.Errorf("clientId not found in auth token")
}
// 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(authToken string) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.Delete(clientId)
}
func (_i *clientApprovalSettingsService) ToggleApprovalRequirement(authToken string, requiresApproval bool) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
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(authToken string, workflowId *uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
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(authToken string, userId uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.AddExemptUser(clientId, userId)
}
func (_i *clientApprovalSettingsService) RemoveExemptUser(authToken string, userId uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.RemoveExemptUser(clientId, userId)
}
func (_i *clientApprovalSettingsService) AddExemptRole(authToken string, roleId uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.AddExemptRole(clientId, roleId)
}
func (_i *clientApprovalSettingsService) RemoveExemptRole(authToken string, roleId uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.RemoveExemptRole(clientId, roleId)
}
func (_i *clientApprovalSettingsService) AddExemptCategory(authToken string, categoryId uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.AddExemptCategory(clientId, categoryId)
}
func (_i *clientApprovalSettingsService) RemoveExemptCategory(authToken string, categoryId uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
return _i.clientApprovalSettingsRepo.RemoveExemptCategory(clientId, categoryId)
}
func (_i *clientApprovalSettingsService) CheckIfApprovalRequired(authToken string, userId uint, userLevelId uint, categoryId uint, contentType string) (bool, error) {
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return true, fmt.Errorf("clientId not found in auth token")
}
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(authToken string, defaultWorkflowId *uint) error {
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
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(authToken string, reason string) error {
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
if clientId == nil {
return fmt.Errorf("clientId not found in auth token")
}
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(authToken string, action string) error {
// This would typically interact with article approval flows
// For now, just log the action
_i.Log.Info().
Str("client_id", authToken).
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
}