package audit import "time" const ( DefaultRetentionDays = 90 ForeverRetentionDays = 0 CleanupHour = 3 KeepRecentHours = 24 ) func RetentionOptions() []int { return []int{30, 90, 365, ForeverRetentionDays} } func ValidateRetentionDays(days int) error { for _, option := range RetentionOptions() { if option == days { return nil } } return ErrInvalidRetention } type Settings struct { RetentionDays int `json:"activity_retention_days"` LastCleanupAt *time.Time `json:"activity_last_cleanup_at"` LastCleanupRemoved int `json:"activity_last_cleanup_removed"` } func DefaultSettings() Settings { return Settings{RetentionDays: DefaultRetentionDays} } func (s Settings) CleanupDue(now time.Time) bool { todayRun := time.Date(now.Year(), now.Month(), now.Day(), CleanupHour, 0, 0, 0, now.Location()) if now.Before(todayRun) { return false } return s.LastCleanupAt == nil || s.LastCleanupAt.Before(todayRun) } func ClampCutoff(now time.Time, cutoff time.Time) time.Time { newest := now.Add(-KeepRecentHours * time.Hour) if cutoff.After(newest) { return newest } return cutoff } func RetentionCutoff(now time.Time, retentionDays int) time.Time { return ClampCutoff(now, now.Add(-time.Duration(retentionDays)*24*time.Hour)) } type CleanupResult struct { Removed int }