From 2606d41c607642b78ff8311d7e12a25eb33f278e Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 1 Mar 2026 16:37:21 -0800 Subject: [PATCH] fix: cascade soft-delete for webhook deletion (closes #24) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When deleting a webhook, also soft-delete all related deliveries and delivery results (not just entrypoints, targets, and events). Query event IDs, then delivery IDs, then cascade delete delivery results, deliveries, events, entrypoints, targets, and finally the webhook itself — all within a single transaction. --- internal/handlers/source_management.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/internal/handlers/source_management.go b/internal/handlers/source_management.go index 0c17039..61bfc2c 100644 --- a/internal/handlers/source_management.go +++ b/internal/handlers/source_management.go @@ -295,10 +295,30 @@ func (h *Handlers) HandleSourceDelete() http.HandlerFunc { return } - // Soft-delete child records + // Soft-delete child records in dependency order (deepest first). + + // Collect event IDs for this webhook + var eventIDs []string + tx.Model(&database.Event{}).Where("webhook_id = ?", webhook.ID).Pluck("id", &eventIDs) + + if len(eventIDs) > 0 { + // Collect delivery IDs for these events + var deliveryIDs []string + tx.Model(&database.Delivery{}).Where("event_id IN ?", eventIDs).Pluck("id", &deliveryIDs) + + if len(deliveryIDs) > 0 { + // Soft-delete delivery results + tx.Where("delivery_id IN ?", deliveryIDs).Delete(&database.DeliveryResult{}) + } + + // Soft-delete deliveries + tx.Where("event_id IN ?", eventIDs).Delete(&database.Delivery{}) + } + + // Soft-delete events, entrypoints, targets, and the webhook itself + tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Event{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Entrypoint{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Target{}) - tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Event{}) tx.Delete(&webhook) if err := tx.Commit().Error; err != nil {