package useCases import ( "RenewCMS/internal/domain/audit" "RenewCMS/internal/domain/purge" "context" "errors" "time" ) type PurgeRunner interface { Execute(fingerprint *string) (purge.RunResult, error) } type PurgeSchedulerUseCase struct { repository purge.Repository runner PurgeRunner recorder audit.Recorder } func NewPurgeSchedulerUseCase(repository purge.Repository, runner PurgeRunner, recorder audit.Recorder) *PurgeSchedulerUseCase { return &PurgeSchedulerUseCase{repository, runner, recorder} } func (u *PurgeSchedulerUseCase) Tick(now time.Time) (purge.RunResult, bool, error) { settings, err := u.repository.Get() if err != nil { return purge.RunResult{}, false, err } next := settings.NextPurgeAt() if next == nil || now.Before(*next) { return purge.RunResult{}, false, nil } result, err := u.runner.Execute(nil) if err != nil { u.recordFailedRun(err) return purge.RunResult{}, false, err } if result.GroupsTotal > 0 { event := systemPurgeEvent() event.Params = purgeParams(result) u.recorder.Record(context.Background(), event) } return result, true, nil } func (u *PurgeSchedulerUseCase) recordFailedRun(err error) { if errors.Is(err, purge.ErrPurgeBusy) { return } failFrom(context.Background(), u.recorder, systemPurgeEvent(), reasonFor(err)) } func systemPurgeEvent() audit.Event { event := audit.NewEvent(audit.ActionMediaPurgeScheduled, audit.CategorySystem) event.Actor = audit.SystemActor() event.Source = audit.SourceSystem return event }