WebhookEngine v0.3.0
SDK feature expansion, a breaking realignment of three response-model properties, full SDK test coverage (32 new cases), portal client correctness fixes, and a hardened CI/security baseline. Test suite grows from 280 to 312. Breaking change for SDK consumers reading EndpointResponse.CustomHeadersJson, EndpointResponse.MetadataJson, or MessageAttemptResponse.RequestHeadersJson as Dictionary<string,string>? — those properties now return JsonElement / JsonElement? to match the wire format. The v1 route prefix and Standard Webhooks signature surface are preserved.
Features / Fixes / Changes
Added
EndpointClient.TestAsyncin the SDK:EndpointClient.TestAsync(endpointId, request)covers the one live/api/v1/*route that had no SDK binding. Returns the live response and the exact signed request via new modelsTestEndpointRequest,EndpointTestResult, andEndpointTestRequestPreview.- SDK request models now expose all API fields:
CreateEventTypeRequest/UpdateEventTypeRequest.IdempotencyWindowMinutesandCreateEndpointRequest/UpdateEndpointRequest.{AllowedIps, TransformExpression, TransformEnabled}— previously these fields were accepted by the API but unreachable from the SDK. - First
WebhookEngine.Sdk.Testsproject (32 cases): coversWebhookVerifierconstant-time HMAC across tolerance, secret-encoding (whsec_vs base64), multi-signature, tamper, and missing-field cases, plus a stub-HttpMessageHandlercontract suite that deserializes real API envelopes through the client so response-DTO drift now fails CI.
Changed
- SDK response models realigned with the engine DTOs (breaking for three properties):
EndpointResponse.CustomHeadersJson/MetadataJsonandMessageAttemptResponse.RequestHeadersJsonchange fromDictionary<string,string>?toJsonElement/JsonElement?. The old dictionary type silently dropped the entire field for any non-string value; the new types match the wire format exactly.EndpointResponsealso gainsAllowedIps,TransformExpression,TransformEnabled,TransformValidatedAt;EventTypeResponsegainsIdempotencyWindowMinutes— all were sent on the wire but silently dropped before this release. - Concurrency regression tests on real PostgreSQL: new Testcontainers tests cover the idempotency UNIQUE race (
23505on N concurrent inserts of the same key), theFOR UPDATE SKIP LOCKEDdequeue (K workers never double-claim), and theMark*AsyncCAS guard. Worker helper methods are nowinternaland exercised directly so a production regression fails CI rather than silently passing a logic copy.
Fixed
@webhookengine/endpoint-managerportal client realigned: three concrete defects against a real engine —updateEndpoint()sentPUTinstead ofPATCH(every update failed); the client read a non-existentisActiveflag instead of the engine'sstatusstring (badge always showed "Disabled"); it readcustomHeadersinstead ofcustomHeaderNames(silently wiped headers on every save). Types now mirror the engine; a contract test prevents this class of drift from shipping again.- Dependabot lockfile-sync now re-triggers CI:
sync-bun-lock.ymlpreviously pushed withGITHUB_TOKEN, which GitHub's recursion guard blocks from triggering new runs — leaving PRs blocked on required checks until manual close/reopen. The push now uses a short-lived GitHub App installation token so the sync commit re-triggers checks automatically. - Dependabot lockfile auto-sync extended to all workspace members: the
pull_request_targettrigger previously only watchedsrc/dashboard/package.json; bumps inpackages/endpoint-manager/package.jsonsilently left a stalebun.lockand broke CI. - Documentation accuracy pass: README
docker runexample corrected (ConnectionStrings__Default, port5100);docs/PRD.md,docs/ROADMAP.md,docs/ARCHITECTURE.md, andAGENTS.mdsynced to current state.
Security
- Repository security baseline hardened: added
SECURITY.mdwith supported-versions policy and private-vulnerability-reporting flow. Added explicitpermissions: contents: readtoci.ymlandrelease.yml. Extended Dependabot to the/packages/endpoint-managernpm workspace. Addedtimeout-minutesto CI jobs. - Secret-scanning false-positive suppression:
.github/secret_scanning.ymladdspaths-ignorefordocs/**,samples/**,tests/**, and**/*.md— WebhookEngine'swhsec_examples collide with the Stripe webhook-secret pattern; source paths remain scanned.
Quick Start
docker pull voyvodka/webhook-engine:0.3.0
git clone https://github.com/voyvodka/webhook-engine.git
cd webhook-engine
docker compose -f docker/docker-compose.yml up -dDashboard at http://localhost:5100 — login admin@example.com / changeme (reset before exposing publicly).