feat: recent activity card on Home and Retention card on Settings

This commit is contained in:
fsylvain committed 2026-10-07 16:01:28 +02:00
1 parent 35db442cd3
commit 43469ef08d
33 files changed
+2748 -204

No files matched your search

+14
View File
@@ -26,6 +26,7 @@ type Settings struct {
RetentionDays int `json:"activity_retention_days"`
LastCleanupAt *time.Time `json:"activity_last_cleanup_at"`
LastCleanupRemoved int `json:"activity_last_cleanup_removed"`
NextCleanupAt *time.Time `json:"activity_next_cleanup_at"`
}
func DefaultSettings() Settings {
@@ -40,6 +41,19 @@ func (s Settings) CleanupDue(now time.Time) bool {
return s.LastCleanupAt == nil || s.LastCleanupAt.Before(todayRun)
}
func (s Settings) WithNextCleanup(now time.Time) Settings {
s.NextCleanupAt = nil
if s.RetentionDays == ForeverRetentionDays {
return s
}
next := time.Date(now.Year(), now.Month(), now.Day(), CleanupHour, 0, 0, 0, now.Location())
if !next.After(now) {
next = time.Date(now.Year(), now.Month(), now.Day()+1, CleanupHour, 0, 0, 0, now.Location())
}
s.NextCleanupAt = &next
return s
}
func ClampCutoff(now time.Time, cutoff time.Time) time.Time {
newest := now.Add(-KeepRecentHours * time.Hour)
if cutoff.After(newest) {
@@ -3,27 +3,34 @@ package useCases
import (
"RenewCMS/internal/domain/audit"
"context"
"time"
)
type GetActivityRetentionUseCase struct {
settings audit.SettingsRepository
now func() time.Time
}
func NewGetActivityRetentionUseCase(settings audit.SettingsRepository) *GetActivityRetentionUseCase {
return &GetActivityRetentionUseCase{settings}
func NewGetActivityRetentionUseCase(settings audit.SettingsRepository, now func() time.Time) *GetActivityRetentionUseCase {
return &GetActivityRetentionUseCase{settings, now}
}
func (g *GetActivityRetentionUseCase) GetActivityRetention() (audit.Settings, error) {
return g.settings.Get()
current, err := g.settings.Get()
if err != nil {
return audit.Settings{}, err
}
return current.WithNextCleanup(g.now()), nil
}
type UpdateActivityRetentionUseCase struct {
settings audit.SettingsRepository
recorder audit.Recorder
now func() time.Time
}
func NewUpdateActivityRetentionUseCase(settings audit.SettingsRepository, recorder audit.Recorder) *UpdateActivityRetentionUseCase {
return &UpdateActivityRetentionUseCase{settings, recorder}
func NewUpdateActivityRetentionUseCase(settings audit.SettingsRepository, recorder audit.Recorder, now func() time.Time) *UpdateActivityRetentionUseCase {
return &UpdateActivityRetentionUseCase{settings, recorder, now}
}
func (u *UpdateActivityRetentionUseCase) UpdateActivityRetention(ctx context.Context, days int) (audit.Settings, error) {
@@ -35,7 +42,7 @@ func (u *UpdateActivityRetentionUseCase) UpdateActivityRetention(ctx context.Con
return audit.Settings{}, err
}
if current.RetentionDays == days {
return current, nil
return current.WithNextCleanup(u.now()), nil
}
if err := u.settings.SaveRetention(days); err != nil {
return audit.Settings{}, err
@@ -46,5 +53,5 @@ func (u *UpdateActivityRetentionUseCase) UpdateActivityRetention(ctx context.Con
u.recorder.Record(ctx, event)
current.RetentionDays = days
return current, nil
return current.WithNextCleanup(u.now()), nil
}
@@ -16,7 +16,7 @@ const (
securityOnly = "true"
)
var activityPageSizes = []int{25, 50, 100}
var activityPageSizes = []int{5, 25, 50, 100}
type ActivityQuery struct {
Q string