From 1796c1696f9fd757da7ddefc1014c1b61108ca82 Mon Sep 17 00:00:00 2001 From: Jamie Banks Date: Fri, 17 Jul 2026 09:25:10 +0100 Subject: [PATCH] feat: implement automated scan history cleanup with configurable retention period --- README.md | 3 +++ internal/scheduler/scheduler.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/README.md b/README.md index 9064a89..6be7a16 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,9 @@ Environment="SMTP_TO=admin@example.com" # Environment="WEB_USER=admin" # Environment="WEB_PASS=supersecret" +# Optional: Number of days to retain scan history in the database (Default: 30) +# Environment="RETENTION_DAYS=30" + Restart=always RestartSec=5 diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index 977fbbe..80564cf 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -1,7 +1,10 @@ package scheduler import ( + "fmt" "log" + "os" + "strconv" "github.com/robfig/cron/v3" @@ -15,6 +18,34 @@ var c *cron.Cron func InitScheduler() { c = cron.New() + // Automated Data Cleanup Job (Runs every day at midnight) + c.AddFunc("@daily", func() { + days := os.Getenv("RETENTION_DAYS") + if days == "" { + days = "30" + } + + retentionDays, err := strconv.Atoi(days) + if err != nil { + log.Printf("Invalid RETENTION_DAYS environment variable: %s", days) + retentionDays = 30 + } + + log.Printf("Running automated cleanup (Retention: %d days)", retentionDays) + + modifier := fmt.Sprintf("-%d days", retentionDays) + res, err := db.DB.Exec("DELETE FROM scans WHERE started_at < date('now', ?)", modifier) + if err != nil { + log.Printf("Cleanup failed: %v", err) + return + } + + rowsAffected, _ := res.RowsAffected() + if rowsAffected > 0 { + log.Printf("Cleanup complete: removed %d old scans.", rowsAffected) + } + }) + // Load all targets rows, err := db.DB.Query("SELECT id, name, address, schedule FROM targets") if err != nil {