Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
40cf7e2
Fix processingTime semantics, schema caching, and restarts
ar27111994 Apr 22, 2026
ca69429
fix(ci): stabilize link-check soft-fails
ar27111994 Apr 23, 2026
b8a0753
fix(pr): address review feedback and ci flake
ar27111994 Apr 23, 2026
a8ffa6b
fix(tests): clear follow-up lint and typing issues
ar27111994 Apr 23, 2026
89803dd
fix(testing): harden teardown and document harness isolation
ar27111994 Apr 23, 2026
1cac353
fix(runtime): harden latency metrics and restart-safe state
ar27111994 Apr 23, 2026
0bdf829
fix(runtime): reuse schema validators and harden duckdb resets
ar27111994 Apr 23, 2026
8ae1fc3
Merge branch 'main' into fix/latency-metric-and-schema-cache
ar27111994 Apr 23, 2026
4e33641
fix: drain server before sync and db shutdown
ar27111994 Apr 24, 2026
7d1e8e6
test: harden duckdb reset coverage guards
ar27111994 Apr 24, 2026
dfdc4f5
test: cover duckdb reset helpers deterministically
ar27111994 Apr 24, 2026
dd02e11
fix: prevent duckdb reset queue deadlock
ar27111994 Apr 24, 2026
154ed8c
test: remove unreachable duckdb branch
ar27111994 Apr 24, 2026
f32092f
test: harden integration harness temp-dir setup
ar27111994 Apr 24, 2026
8eaf729
fix: Update src/db/duckdb.js stopWriteQueue() JSDoc
ar27111994 Apr 25, 2026
fc4562e
fix(docs): Update docs/architecture.md DuckDB reset process descripti…
ar27111994 Apr 25, 2026
5a5a8a6
fix: Update stopWriteQueue to drop waiting jobs during reset
ar27111994 Apr 25, 2026
91a8842
fix(db): invalidate late duckdb init after reset
ar27111994 Apr 25, 2026
1671cbd
fix(runtime): harden restart cleanup and worker settling
ar27111994 Apr 25, 2026
e96e108
fix(ci): simplify test command in release workflow
ar27111994 Apr 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .actor/actor.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "webhook-debugger-logger",
"title": "Webhook Debugger, Logger & API Mocking Suite",
"description": "Enterprise-grade tool to test, debug, and mock webhooks. Features real-time SSE streaming, request replay, HTTP forwarding, and JSON schema validation. Perfect for Stripe, GitHub, and Shopify integrations.",
"version": "3.0.4",
"version": "3.0.5",
"output": "./output_schema.json",
"input": "./input_schema.json",
"webServerSchema": "./web_server_schema.json",
Expand Down
6 changes: 3 additions & 3 deletions .actor/dataset_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@
},
"processingTime": {
"type": "integer",
"title": "Latency (ms)",
"description": "Time taken to process the request",
"title": "Processing Time (ms)",
"description": "Time taken to process the request before any simulated response delay is applied",
"example": 5
},
"remoteIp": {
Expand Down Expand Up @@ -224,7 +224,7 @@
"label": "Size (Bytes)"
},
"processingTime": {
"label": "Latency (ms)"
"label": "Processing Time (ms)"
},
"remoteIp": {
"label": "Source IP"
Expand Down
8 changes: 7 additions & 1 deletion .actor/output_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@
"desc": true
},
"display": {
"component": "table"
"component": "table",
"properties": {
"processingTime": {
"label": "Processing Time (ms)",
"format": "number"
}
}
}
},
"details": {
Expand Down
7 changes: 4 additions & 3 deletions .actor/web_server_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "Webhook Debugger & Logger API",
"description": "OpenAPI description for the Webhook Debugger & Logger Actor web server. Authentication is configuration-driven: when authKey is configured, management routes require either a bearer token or the key query parameter; when authKey is unset, those routes remain accessible without credentials.",
"version": "3.0.4"
"version": "3.0.5"
},
"servers": [
{
Expand Down Expand Up @@ -80,7 +80,7 @@
"schema": {
"type": "string"
},
"example": "Webhook Debugger & Logger (v3.0.4)\nActive Webhooks: 1\nSignature Verification: STRIPE"
"example": "Webhook Debugger & Logger (v3.0.5)\nActive Webhooks: 1\nSignature Verification: STRIPE"
}
}
},
Expand Down Expand Up @@ -1137,7 +1137,8 @@
"type": "integer"
},
"processingTime": {
"type": "integer"
"type": "integer",
"description": "Server-side processing time in milliseconds before any configured responseDelayMs simulation is applied"
},
"requestId": {
"type": "string"
Expand Down
10 changes: 8 additions & 2 deletions .claude/rules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
### shared-mocks.js

- `apifyMock`, `axiosMock`, `dnsPromisesMock`, `ssrfMock` - Pre-configured mocks
- `apifyMock` includes both `Actor.on(...)` and `Actor.off(...)` support for lifecycle-oriented harness teardown
- `createDatasetMock(items, { autoRegister })` - Dataset with getData/pushData/getInfo
- `createKeyValueStoreMock(overrides)` - KV store mock
- `createMockWebhookManager(overrides)` - WebhookManager mock
- `setupBasicApifyMock(mockInstance, options)` - Configure apifyMock
- `resetNetworkMocks()` - Reset SSRF, DNS, Axios to defaults
- `fsPromisesMock` - Shared `node:fs/promises` mock surface, including `mkdtemp()` for temp-dir based harness setup
- `loggerMock` - Shared logger mock for assertions

### test-utils.js
Expand All @@ -77,7 +79,7 @@ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
### Other Helpers

- `middleware-test-utils.js`: `createMiddlewareTestContext()`, `runMiddlewareWithTimers()`
- `app-utils.js`: `setupTestApp()` - Initialize app + supertest for integration tests
- `app-utils.js`: `setupTestApp()` - Initialize app + supertest for integration tests; teardown also removes transient Actor listeners and process signal handlers registered during boot
- `db-hooks.js`: `resetDb()` - Clear DuckDB logs table
- `signature-utils.js`: `createStripeSignature()`, `createShopifySignature()`, `createGitHubSignature()`, `createSlackSignature()`

Expand Down Expand Up @@ -231,13 +233,17 @@ let appClient, teardownApp;
beforeAll(async () => {
({ appClient, teardownApp } = await setupTestApp());
});
afterAll(() => teardownApp());
afterAll(async () => {
await teardownApp();
});

test("GET /health", async () => {
expect((await appClient.get("/health")).status).toBe(200);
});
```

Use the harness teardown instead of manually removing process or Actor listeners inside individual integration suites.

### Dataset Mocking

```javascript
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/link-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ jobs:

try {
const { origin, pathname } = new URL(value);
return `${origin}${pathname}`;
const normalizedPathname =
pathname !== '/' && pathname.endsWith('/')
? pathname.slice(0, -1)
: pathname;
return `${origin}${normalizedPathname}`;
} catch {
return null;
}
Expand All @@ -114,6 +118,9 @@ jobs:
'https://www.npmjs.com/package/webhook-debugger-logger',
'https://www.npmjs.com/package/isolated-vm?activeTab=readme',
'https://img.shields.io/coderabbit/prs/github/ar27111994/webhook-debugger-logger?utm_source=oss&utm_medium=github&utm_campaign=ar27111994%2Fwebhook-debugger-logger&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews',
'https://www.patreon.com/cw/ar27111994',
'https://liberapay.com/ar27111994',
'https://thanks.dev/d/gh/ar27111994',
];
const softHandledUrlKeys = new Set(
softHandledUrls.map((value) => normalizeUrlKey(value)).filter(Boolean),
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ coverage/
!.github/coverage/
!.github/coverage/*.json
.tsbuildinfo
*.tmp*
1 change: 1 addition & 0 deletions .lycheeignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
^(?:http://)169\.254\.169\.254/latest(?:/|$)
^(?:http://)(?:empty\.domain|nonexistent\.domain)(?:/|$)
^(?:http://)(?:weird-dns|string-throw)\.com(?:/|$)
^(?:http://)metadata\.cloud(?:/|$)
^(?:https://)xn--unicode-domain\.com(?:/|$)
^(?:https://)google\.com/foo(?:/|$)
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.0.5] - 2026-04-21

### Fixed (3.0.5)

- **Latency Metrics**: Make `processingTime` consistently represent server-side processing time only, excluding any configured `responseDelayMs` simulation from persisted log data.
- **Performance**: Cache compiled JSON Schema validators so repeated requests and stable hot-reload configurations do not trigger unnecessary recompilation on the webhook path.
- **Lifecycle**: Reset webhook-manager singleton state during test teardown and recreate the sync-service limiter after shutdown so repeated initialize/stop/start flows remain stable.
- **Shutdown Ordering**: Drain the HTTP listener before stopping `SyncService` and closing DuckDB so in-flight requests and readiness probes do not race read-model teardown.
- **DuckDB Lifecycle**: Drain both pooled and in-use DuckDB connections before resetting the singleton so repeated DB teardown and rebuild flows do not leave stale handles behind.
- **DuckDB Reset Coordination**: Keep the reset gate for new DuckDB callers while allowing already-queued writes and transactions to drain first, preventing reset deadlocks in the serialized write path.
- **Contracts & Docs**: Align dataset, output, OpenAPI, README, architecture, and API reference documentation with the finalized `processingTime` semantics and response-delay behavior.
- **Tests**: Add regression coverage for latency semantics, validator-cache reuse and memoized schema cache keys, DuckDB reset coordination with active reads plus queued write/transaction drain paths, malformed JSON sanitation persistence, restart-safe integration harness cleanup, shutdown-only sync error suppression, and spawned-process close-path resilience.

## [3.0.4] - 2026-04-18

### Fixed (3.0.4)
Expand Down
Loading
Loading