Enforce per-webhook event retention (RetentionDays reaper) #63
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of the road to 1.0 (see #33).
Webhook.RetentionDays(internal/database/model_webhook.go,gorm:"default:30") is stored but never enforced. Nothing deletes oldEvent,Delivery, orDeliveryResultrows, so each per-webhook SQLite file (internal/database/webhook_db_manager.go) grows without bound for the life of the service. For an internet-facing deployment this is unbounded disk growth.Definition of done:
RetentionDays, across all per-webhook databasesRetentionDays <= 0means retain forever (no deletion)Implementation instructions
Implement the retention reaper as a cohesive, self-contained unit.
Files: a new reaper in one place (e.g.
internal/database/retention.go, or a small newinternal/retentionpackage — your choice),internal/config/config.go(add the sweep interval), and the fx wiring where the app assembles its components (inspectcmd/webhooker/main.goandinternal/server/to find where providers and lifecycle hooks are registered). Do NOT editroutes.go,http.go,engine.go,source_management.go, ormiddleware.go— other work is in flight there.Behaviour:
RetentionSweepIntervaltoconfig.gowith an env var and a sane default such as 1h, following the existing config field/env conventions in that fileWebhooktable carriesRetentionDays, default 30). For each webhook with a positiveRetentionDays, open its per-webhook DB via the existingWebhookDBManager.GetDB(webhookID)and delete everyEventrow (and its dependentDeliveryandDeliveryResultrows) whoseCreatedAtis older thanRetentionDaysdays. Read theEvent/Delivery/DeliveryResultmodels first to get the foreign-key relationships, and delete in the correct order (results, then deliveries, then events) so nothing is orphaned.RetentionDaysof 0 or less means retain forever — skip that webhookOnStartlifecycle hook and stop it cleanly onOnStop(context cancellation), matching how other lifecycle components are wiredDefinition of done:
RetentionDays; recent rows are keptGates and process:
make fmt; validate withdocker build .(must exit 0)mainnamedissue-63-retention-reaper; commit subject ends with(closes #63)main) and comment on it with the diff summary and thedocker build .result