#425 Add DELETE /api/webhooks/:id route with confirmation token and cascading delivery cleanup FIXED - #1140
Open
veloura-dev wants to merge 1 commit into
Conversation
…oken and cascading delivery cleanup FIXED
veloura-dev
force-pushed
the
#425-Add-DELETE-/api/webhooks/-id-route-with-confirmation-token-and-cascading-delivery-cleanup-FIX
branch
from
August 1, 2026 16:36
07390d2 to
144bf8c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CLOSE #425
1. Findings in the Codebase
DELETE /api/webhooks/:developerIdacross both routing layers (src/webhooks/webhook.routes.tsandsrc/routes/webhooks.ts) executed an immediate, single-step deletion (WebhookStore.delete(developerId)).failedDeliveryLogand Dead-Letter Queue entries indeadLetterStore) were left behind in memory without cleanup.dispatchWebhook(src/webhooks/webhook.dispatcher.ts) logged delivery attempts tologger, it did not record individual delivery attempt records in a dedicated store (webhook_delivery_attempts) that could be inspected or pruned upon subscription deletion.src/webhooks/webhook.routes.tsandsrc/routes/webhooks.ts). To ensure consistent behavior regardless of which router is mounted or tested, both needed to support two-step delete, token verification, delivery attempt pruning, and database audit row persistence (appendAuditRow/auditStateChange).src/index.tshad duplicate import statements and variable declarations (proxyDrainTracker) resulting from a stale merge conflict onmain.logger.jswithout exportingPINO_REDACT_PATHScaused Pino initialization to crash (pino – redact must contain an array of strings) wheneversrc/middleware/logging.tswas loaded.src/webhooks/webhook.integration.test.ts) tested a non-existent demo endpoint (POST /api/webhooksexpectingx-webhook-signature), which conflicted with the realPOST /api/webhooksregistration endpoint.2. Fix Features Implemented
Two-Step Deletion Protocol (
POST /api/webhooks/:developerId/delete-token&DELETE /api/webhooks/:developerId)POST /api/webhooks/:developerId/delete-token):64characters) with a 5-minute TTL (300,000ms).{ "message": "Webhook deletion confirmation token issued.", "developerId": "dev-123", "token": "d9f8e7a6...", "expires_at": "2026-08-01T12:25:00.000Z", "expiresInMs": 300000 }WEBHOOK_DELETE_TOKEN_ISSUEDaudit logs (logger.audit) and persistent database audit rows (appendAuditRow).DELETE /api/webhooks/:developerId):?token=...), HTTP header (x-confirm-token,x-callora-delete-token,x-confirmation-token), or JSON request body ({ "token": "..." }).DELETEwithout a valid token is blocked with structured HTTP 400 error envelopes:MISSING_TOKEN— No token provided.INVALID_TOKEN— Token does not match the stored token for this developer subscription.EXPIRED_TOKEN— Token has exceeded its 5-minute TTL.WEBHOOK_NOT_FOUND).Single Transaction Subscription + Delivery Cleanup (
WebhookStore.deleteSubscriptionWithCleanup)WebhookStore.deleteSubscriptionWithCleanup(developerId, token)insrc/webhooks/webhook.store.ts.WebhookConfig).developerId.developerId:deliveryAttempts(webhook_delivery_attempts).failedDeliveryLog.deadLetterStore.{ "message": "Webhook removed.", "developerId": "dev-123", "prunedDeliveryAttempts": 5 }Delivery Attempt Tracking (
webhook_delivery_attempts)WebhookDeliveryAttemptrecord tracking inWebhookStore(src/webhooks/webhook.store.ts) with methodsrecordDeliveryAttempt,getDeliveryAttempts(developerId), andclearDeliveryAttempts().WebhookStore.recordDeliveryAttempt(...)intodispatchWebhook(src/webhooks/webhook.dispatcher.ts) so every delivery attempt—whether successful, non-2xx HTTP response, or network/timeout failure—is recorded indeliveryAttempts.Comprehensive Audit Event Logging
POST /delete-tokenandDELETE /:developerIdemit:logger.info.logger.audit(WEBHOOK_DELETE_TOKEN_ISSUEDandWEBHOOK_DELETED).appendAuditRow/auditStateChange, capturing thebeforesubscription state andafter: nullon deletion.OpenAPI Specification & Contract Documentation
src/openapi.yamlto document/api/webhooks/{developerId}/delete-token(POST) and/api/webhooks/{developerId}(DELETE) with complete request parameters, request bodies, and response schemas (WebhookDeleteTokenResponse,WebhookDeleteResponse, andStandardErrorEnvelopeexamples for 400 and 404 errors).High Code Coverage & Dedicated Tests
src/webhooks/webhook.store.test.tsto test all unit methods onWebhookStore, achieving 100% statement, line, and function coverage.describe('DELETE /api/webhooks/:developerId - Two-Step Delete & Authorization')totests/integration/webhooks.test.ts, covering token issuance, valid two-step deletion, token expiry, invalid token rejection, missing token rejection, and delivery attempt pruning.src/routes/webhooks.test.tsto assert that database audit rows (WEBHOOK_DELETE_TOKEN_ISSUEDandWEBHOOK_DELETED) are written during the two-step delete flow.