@nestarc/webhook 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +281 -0
  3. package/dist/adapters/fetch-http-client.d.ts +6 -0
  4. package/dist/adapters/fetch-http-client.d.ts.map +1 -0
  5. package/dist/adapters/fetch-http-client.js +56 -0
  6. package/dist/adapters/fetch-http-client.js.map +1 -0
  7. package/dist/adapters/prisma-delivery.repository.d.ts +18 -0
  8. package/dist/adapters/prisma-delivery.repository.d.ts.map +1 -0
  9. package/dist/adapters/prisma-delivery.repository.js +162 -0
  10. package/dist/adapters/prisma-delivery.repository.js.map +1 -0
  11. package/dist/adapters/prisma-endpoint.repository.d.ts +18 -0
  12. package/dist/adapters/prisma-endpoint.repository.d.ts.map +1 -0
  13. package/dist/adapters/prisma-endpoint.repository.js +157 -0
  14. package/dist/adapters/prisma-endpoint.repository.js.map +1 -0
  15. package/dist/adapters/prisma-event.repository.d.ts +8 -0
  16. package/dist/adapters/prisma-event.repository.d.ts.map +1 -0
  17. package/dist/adapters/prisma-event.repository.js +39 -0
  18. package/dist/adapters/prisma-event.repository.js.map +1 -0
  19. package/dist/index.d.ts +26 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +57 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/interfaces/webhook-delivery.interface.d.ts +39 -0
  24. package/dist/interfaces/webhook-delivery.interface.d.ts.map +1 -0
  25. package/dist/interfaces/webhook-delivery.interface.js +3 -0
  26. package/dist/interfaces/webhook-delivery.interface.js.map +1 -0
  27. package/dist/interfaces/webhook-endpoint.interface.d.ts +34 -0
  28. package/dist/interfaces/webhook-endpoint.interface.d.ts.map +1 -0
  29. package/dist/interfaces/webhook-endpoint.interface.js +3 -0
  30. package/dist/interfaces/webhook-endpoint.interface.js.map +1 -0
  31. package/dist/interfaces/webhook-options.interface.d.ts +45 -0
  32. package/dist/interfaces/webhook-options.interface.d.ts.map +1 -0
  33. package/dist/interfaces/webhook-options.interface.js +3 -0
  34. package/dist/interfaces/webhook-options.interface.js.map +1 -0
  35. package/dist/ports/webhook-delivery.repository.d.ts +26 -0
  36. package/dist/ports/webhook-delivery.repository.d.ts.map +1 -0
  37. package/dist/ports/webhook-delivery.repository.js +3 -0
  38. package/dist/ports/webhook-delivery.repository.js.map +1 -0
  39. package/dist/ports/webhook-endpoint.repository.d.ts +15 -0
  40. package/dist/ports/webhook-endpoint.repository.d.ts.map +1 -0
  41. package/dist/ports/webhook-endpoint.repository.js +3 -0
  42. package/dist/ports/webhook-endpoint.repository.js.map +1 -0
  43. package/dist/ports/webhook-event.repository.d.ts +5 -0
  44. package/dist/ports/webhook-event.repository.d.ts.map +1 -0
  45. package/dist/ports/webhook-event.repository.js +3 -0
  46. package/dist/ports/webhook-event.repository.js.map +1 -0
  47. package/dist/ports/webhook-http-client.d.ts +5 -0
  48. package/dist/ports/webhook-http-client.d.ts.map +1 -0
  49. package/dist/ports/webhook-http-client.js +3 -0
  50. package/dist/ports/webhook-http-client.js.map +1 -0
  51. package/dist/webhook.admin.service.d.ts +22 -0
  52. package/dist/webhook.admin.service.d.ts.map +1 -0
  53. package/dist/webhook.admin.service.js +58 -0
  54. package/dist/webhook.admin.service.js.map +1 -0
  55. package/dist/webhook.circuit-breaker.d.ts +12 -0
  56. package/dist/webhook.circuit-breaker.d.ts.map +1 -0
  57. package/dist/webhook.circuit-breaker.js +58 -0
  58. package/dist/webhook.circuit-breaker.js.map +1 -0
  59. package/dist/webhook.constants.d.ts +17 -0
  60. package/dist/webhook.constants.d.ts.map +1 -0
  61. package/dist/webhook.constants.js +26 -0
  62. package/dist/webhook.constants.js.map +1 -0
  63. package/dist/webhook.delivery-admin.service.d.ts +9 -0
  64. package/dist/webhook.delivery-admin.service.d.ts.map +1 -0
  65. package/dist/webhook.delivery-admin.service.js +36 -0
  66. package/dist/webhook.delivery-admin.service.js.map +1 -0
  67. package/dist/webhook.delivery-worker.d.ts +23 -0
  68. package/dist/webhook.delivery-worker.d.ts.map +1 -0
  69. package/dist/webhook.delivery-worker.js +141 -0
  70. package/dist/webhook.delivery-worker.js.map +1 -0
  71. package/dist/webhook.dispatcher.d.ts +14 -0
  72. package/dist/webhook.dispatcher.d.ts.map +1 -0
  73. package/dist/webhook.dispatcher.js +54 -0
  74. package/dist/webhook.dispatcher.js.map +1 -0
  75. package/dist/webhook.endpoint-admin.service.d.ts +23 -0
  76. package/dist/webhook.endpoint-admin.service.d.ts.map +1 -0
  77. package/dist/webhook.endpoint-admin.service.js +97 -0
  78. package/dist/webhook.endpoint-admin.service.js.map +1 -0
  79. package/dist/webhook.event.d.ts +6 -0
  80. package/dist/webhook.event.d.ts.map +1 -0
  81. package/dist/webhook.event.js +22 -0
  82. package/dist/webhook.event.js.map +1 -0
  83. package/dist/webhook.module.d.ts +15 -0
  84. package/dist/webhook.module.d.ts.map +1 -0
  85. package/dist/webhook.module.js +176 -0
  86. package/dist/webhook.module.js.map +1 -0
  87. package/dist/webhook.retry-policy.d.ts +7 -0
  88. package/dist/webhook.retry-policy.d.ts.map +1 -0
  89. package/dist/webhook.retry-policy.js +38 -0
  90. package/dist/webhook.retry-policy.js.map +1 -0
  91. package/dist/webhook.service.d.ts +17 -0
  92. package/dist/webhook.service.d.ts.map +1 -0
  93. package/dist/webhook.service.js +63 -0
  94. package/dist/webhook.service.js.map +1 -0
  95. package/dist/webhook.signer.d.ts +12 -0
  96. package/dist/webhook.signer.d.ts.map +1 -0
  97. package/dist/webhook.signer.js +75 -0
  98. package/dist/webhook.signer.js.map +1 -0
  99. package/dist/webhook.url-validator.d.ts +3 -0
  100. package/dist/webhook.url-validator.d.ts.map +1 -0
  101. package/dist/webhook.url-validator.js +156 -0
  102. package/dist/webhook.url-validator.js.map +1 -0
  103. package/package.json +61 -0
  104. package/src/sql/create-webhook-tables.sql +72 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 nestarc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # @nestarc/webhook
2
+
3
+ Outbound webhook delivery for NestJS — HMAC signing, exponential retry, circuit breaker, delivery logs, fan-out, [Standard Webhooks](https://www.standardwebhooks.com/) compatible.
4
+
5
+ **No separate infrastructure required.** Uses your existing PostgreSQL database.
6
+
7
+ [![CI](https://github.com/nestarc/webhook/actions/workflows/ci.yml/badge.svg)](https://github.com/nestarc/webhook/actions/workflows/ci.yml)
8
+
9
+ ## Features
10
+
11
+ - **Fan-out delivery** — one event to many endpoints
12
+ - **HMAC-SHA256 signing** — Standard Webhooks compatible headers
13
+ - **Exponential backoff** — 30s, 5m, 30m, 2h, 24h (with jitter)
14
+ - **Circuit breaker** — auto-disable failing endpoints, auto-recover after cooldown
15
+ - **Dead letter queue** — failed deliveries tracked for manual retry
16
+ - **Delivery logs** — full audit trail (status code, latency, response body)
17
+ - **Multi-instance safe** — `FOR UPDATE SKIP LOCKED` prevents duplicate delivery
18
+ - **Graceful shutdown** — waits for in-flight deliveries on process exit
19
+ - **SSRF defense** — DNS resolution validation at registration and dispatch time
20
+ - **Ports/adapters architecture** — swap Prisma or fetch with custom implementations
21
+ - **Stale delivery recovery** — lease-based reaper recovers crashed worker deliveries
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install @nestarc/webhook
27
+ ```
28
+
29
+ **Peer dependencies:**
30
+
31
+ ```bash
32
+ npm install @nestjs/common @nestjs/core @nestjs/schedule @prisma/client
33
+ ```
34
+
35
+ ## Database Setup
36
+
37
+ Run the migration SQL against your PostgreSQL database:
38
+
39
+ ```bash
40
+ psql -d your_database -f node_modules/@nestarc/webhook/src/sql/create-webhook-tables.sql
41
+ ```
42
+
43
+ This creates three tables: `webhook_endpoints`, `webhook_events`, `webhook_deliveries`.
44
+
45
+ The migration includes `CREATE EXTENSION IF NOT EXISTS pgcrypto` for PostgreSQL < 13 compatibility.
46
+
47
+ ## Quick Start
48
+
49
+ ### 1. Register the module
50
+
51
+ ```typescript
52
+ import { WebhookModule } from '@nestarc/webhook';
53
+
54
+ @Module({
55
+ imports: [
56
+ WebhookModule.forRoot({
57
+ prisma: prismaService,
58
+ delivery: {
59
+ timeout: 10_000,
60
+ maxRetries: 5,
61
+ backoff: 'exponential',
62
+ jitter: true,
63
+ },
64
+ circuitBreaker: {
65
+ failureThreshold: 5,
66
+ cooldownMinutes: 60,
67
+ },
68
+ polling: {
69
+ interval: 5000,
70
+ batchSize: 50,
71
+ },
72
+ }),
73
+ ],
74
+ })
75
+ export class AppModule {}
76
+ ```
77
+
78
+ ### 2. Define events
79
+
80
+ ```typescript
81
+ import { WebhookEvent } from '@nestarc/webhook';
82
+
83
+ export class OrderCreatedEvent extends WebhookEvent {
84
+ static readonly eventType = 'order.created';
85
+
86
+ constructor(
87
+ public readonly orderId: string,
88
+ public readonly total: number,
89
+ ) {
90
+ super();
91
+ }
92
+ }
93
+ ```
94
+
95
+ > **Note:** Subclasses **must** define `static readonly eventType`. The module throws at runtime if this is missing.
96
+
97
+ ### 3. Send events
98
+
99
+ ```typescript
100
+ import { WebhookService } from '@nestarc/webhook';
101
+
102
+ @Injectable()
103
+ export class OrderService {
104
+ constructor(private readonly webhooks: WebhookService) {}
105
+
106
+ async createOrder(dto: CreateOrderDto) {
107
+ const order = await this.saveOrder(dto);
108
+ await this.webhooks.send(new OrderCreatedEvent(order.id, order.total));
109
+ return order;
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### 4. Manage endpoints
115
+
116
+ ```typescript
117
+ import { WebhookEndpointAdminService } from '@nestarc/webhook';
118
+
119
+ @Injectable()
120
+ export class WebhookController {
121
+ constructor(private readonly endpointAdmin: WebhookEndpointAdminService) {}
122
+
123
+ async register() {
124
+ // Secret is returned only on creation
125
+ return this.endpointAdmin.createEndpoint({
126
+ url: 'https://customer.com/webhooks',
127
+ events: ['order.created', 'order.paid'],
128
+ secret: 'auto',
129
+ });
130
+ }
131
+ }
132
+ ```
133
+
134
+ ## API Reference
135
+
136
+ ### WebhookService
137
+
138
+ | Method | Description |
139
+ |--------|-------------|
140
+ | `send(event)` | Publish event to all matching endpoints |
141
+ | `sendToTenant(tenantId, event)` | Publish to tenant-specific endpoints only |
142
+
143
+ ### WebhookEndpointAdminService
144
+
145
+ | Method | Description |
146
+ |--------|-------------|
147
+ | `createEndpoint(dto)` | Register a new webhook endpoint (returns secret) |
148
+ | `listEndpoints(tenantId?)` | List all endpoints (secret excluded) |
149
+ | `getEndpoint(id)` | Get endpoint details (secret excluded) |
150
+ | `updateEndpoint(id, dto)` | Update endpoint URL, events, etc. |
151
+ | `deleteEndpoint(id)` | Delete an endpoint |
152
+ | `sendTestEvent(endpointId)` | Send a `webhook.test` ping event |
153
+
154
+ ### WebhookDeliveryAdminService
155
+
156
+ | Method | Description |
157
+ |--------|-------------|
158
+ | `getDeliveryLogs(endpointId, filters?)` | Query delivery history |
159
+ | `retryDelivery(deliveryId)` | Manually retry a failed delivery |
160
+
161
+ ### WebhookSigner
162
+
163
+ | Method | Description |
164
+ |--------|-------------|
165
+ | `sign(eventId, timestamp, body, secret)` | Generate Standard Webhooks signature headers |
166
+ | `verify(eventId, timestamp, body, secret, signature)` | Verify a webhook signature |
167
+ | `generateSecret()` | Generate a random base64 signing secret |
168
+
169
+ > **Deprecated:** `WebhookAdminService` is a facade that delegates to `WebhookEndpointAdminService` and `WebhookDeliveryAdminService`. It will be removed in v0.3.0.
170
+
171
+ ## Configuration
172
+
173
+ | Option | Default | Description |
174
+ |--------|---------|-------------|
175
+ | `prisma` | — | PrismaClient instance (required unless all custom repos provided) |
176
+ | `delivery.timeout` | `10000` | HTTP request timeout (ms) |
177
+ | `delivery.maxRetries` | `5` | Maximum delivery attempts |
178
+ | `delivery.jitter` | `true` | Add random jitter to retry delays |
179
+ | `circuitBreaker.failureThreshold` | `5` | Consecutive failures before disabling endpoint |
180
+ | `circuitBreaker.cooldownMinutes` | `60` | Minutes before attempting recovery |
181
+ | `polling.interval` | `5000` | Delivery worker poll interval (ms) |
182
+ | `polling.batchSize` | `50` | Max deliveries per poll cycle |
183
+ | `polling.staleSendingMinutes` | `5` | Minutes before a stuck SENDING delivery is recovered |
184
+ | `allowPrivateUrls` | `false` | Allow private/internal URLs (dev/test only) |
185
+
186
+ ### Custom adapters
187
+
188
+ Replace default Prisma or fetch implementations by providing custom ports:
189
+
190
+ ```typescript
191
+ WebhookModule.forRoot({
192
+ prisma: prismaService,
193
+ httpClient: myCustomHttpClient, // implements WebhookHttpClient
194
+ eventRepository: myCustomEventRepo, // implements WebhookEventRepository
195
+ endpointRepository: myCustomEndpointRepo,// implements WebhookEndpointRepository
196
+ deliveryRepository: myCustomDeliveryRepo,// implements WebhookDeliveryRepository
197
+ });
198
+ ```
199
+
200
+ ### Async configuration
201
+
202
+ ```typescript
203
+ WebhookModule.forRootAsync({
204
+ imports: [ConfigModule],
205
+ useFactory: (config: ConfigService, prisma: PrismaService) => ({
206
+ prisma,
207
+ delivery: {
208
+ maxRetries: config.get('WEBHOOK_MAX_RETRIES', 5),
209
+ },
210
+ }),
211
+ inject: [ConfigService, PrismaService],
212
+ });
213
+ ```
214
+
215
+ ## Security
216
+
217
+ ### Signing
218
+
219
+ All webhooks are signed with **HMAC-SHA256** using [Standard Webhooks](https://www.standardwebhooks.com/) headers:
220
+
221
+ ```
222
+ webhook-id: <event-uuid>
223
+ webhook-timestamp: <unix-seconds>
224
+ webhook-signature: v1,<base64-hmac-sha256>
225
+ ```
226
+
227
+ **Secret format:** Secrets must be valid base64 strings decoding to at least 16 bytes. Use `"auto"` for automatic generation.
228
+
229
+ ### SSRF defense
230
+
231
+ - Endpoint URLs are validated at **registration** and at **every dispatch**
232
+ - Blocks: private IPs, loopback, link-local, cloud metadata (169.254.x), IPv4-mapped IPv6
233
+ - DNS resolution is checked to prevent rebinding attacks
234
+ - HTTP redirects are disabled (`redirect: 'manual'`)
235
+ - Use `allowPrivateUrls: true` for local development only
236
+
237
+ ### Secret handling
238
+
239
+ - Signing secrets are excluded from read queries (`listEndpoints`, `getEndpoint`)
240
+ - Secrets are only returned on `createEndpoint` (initial provisioning)
241
+ - Delivery enrichment uses an internal path that does not expose secrets through admin APIs
242
+
243
+ ## Webhook Payload Format
244
+
245
+ ```json
246
+ {
247
+ "type": "order.created",
248
+ "data": {
249
+ "orderId": "ord_123",
250
+ "total": 99.99
251
+ }
252
+ }
253
+ ```
254
+
255
+ ## Architecture
256
+
257
+ ```
258
+ ┌─────────────┐ ┌──────────────────┐ ┌───────────────────┐
259
+ │ Your Service │────>│ WebhookService │────>│ PostgreSQL (tx) │
260
+ └─────────────┘ └──────────────────┘ └───────────────────┘
261
+
262
+ ┌───────┴────────┐
263
+ │ DeliveryWorker │ (polls every N seconds)
264
+ └───────┬────────┘
265
+
266
+ ┌─────────────┼─────────────┐
267
+ v v v
268
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
269
+ │Dispatcher│ │RetryPolicy│ │CircuitBkr│
270
+ └────┬─────┘ └──────────┘ └──────────┘
271
+
272
+ ┌────┴─────┐
273
+ │HttpClient│──> customer endpoints
274
+ └──────────┘
275
+ ```
276
+
277
+ All components depend on **port interfaces**, not concrete implementations. Default adapters use Prisma and Node.js fetch.
278
+
279
+ ## License
280
+
281
+ MIT
@@ -0,0 +1,6 @@
1
+ import { WebhookHttpClient } from '../ports/webhook-http-client';
2
+ import { DeliveryResult } from '../interfaces/webhook-delivery.interface';
3
+ export declare class FetchHttpClient implements WebhookHttpClient {
4
+ post(url: string, headers: Record<string, string>, body: string, timeout: number): Promise<DeliveryResult>;
5
+ }
6
+ //# sourceMappingURL=fetch-http-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-http-client.d.ts","sourceRoot":"","sources":["../../src/adapters/fetch-http-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAG1E,qBACa,eAAgB,YAAW,iBAAiB;IACjD,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC;CAuC3B"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.FetchHttpClient = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const webhook_constants_1 = require("../webhook.constants");
12
+ let FetchHttpClient = class FetchHttpClient {
13
+ async post(url, headers, body, timeout) {
14
+ const controller = new AbortController();
15
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
16
+ const start = Date.now();
17
+ try {
18
+ const response = await fetch(url, {
19
+ method: 'POST',
20
+ headers: {
21
+ 'Content-Type': 'application/json',
22
+ 'User-Agent': '@nestarc/webhook',
23
+ ...headers,
24
+ },
25
+ body,
26
+ signal: controller.signal,
27
+ redirect: 'manual',
28
+ });
29
+ const latencyMs = Date.now() - start;
30
+ const responseBody = await response.text();
31
+ return {
32
+ success: response.status >= 200 && response.status < 300,
33
+ statusCode: response.status,
34
+ body: responseBody.slice(0, webhook_constants_1.RESPONSE_BODY_MAX_LENGTH),
35
+ latencyMs,
36
+ };
37
+ }
38
+ catch (error) {
39
+ const latencyMs = Date.now() - start;
40
+ const message = error instanceof Error ? error.message : String(error);
41
+ return {
42
+ success: false,
43
+ latencyMs,
44
+ error: message,
45
+ };
46
+ }
47
+ finally {
48
+ clearTimeout(timeoutId);
49
+ }
50
+ }
51
+ };
52
+ exports.FetchHttpClient = FetchHttpClient;
53
+ exports.FetchHttpClient = FetchHttpClient = __decorate([
54
+ (0, common_1.Injectable)()
55
+ ], FetchHttpClient);
56
+ //# sourceMappingURL=fetch-http-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-http-client.js","sourceRoot":"","sources":["../../src/adapters/fetch-http-client.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAG5C,4DAAgE;AAGzD,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,KAAK,CAAC,IAAI,CACR,GAAW,EACX,OAA+B,EAC/B,IAAY,EACZ,OAAe;QAEf,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,YAAY,EAAE,kBAAkB;oBAChC,GAAG,OAAO;iBACX;gBACD,IAAI;gBACJ,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAE3C,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG;gBACxD,UAAU,EAAE,QAAQ,CAAC,MAAM;gBAC3B,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,4CAAwB,CAAC;gBACrD,SAAS;aACV,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,SAAS;gBACT,KAAK,EAAE,OAAO;aACf,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;CACF,CAAA;AA7CY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;GACA,eAAe,CA6C3B"}
@@ -0,0 +1,18 @@
1
+ import { PendingDelivery, WebhookDeliveryRepository } from '../ports/webhook-delivery.repository';
2
+ import { DeliveryLogFilters, DeliveryRecord, DeliveryResult } from '../interfaces/webhook-delivery.interface';
3
+ export declare class PrismaDeliveryRepository implements WebhookDeliveryRepository {
4
+ private readonly prisma;
5
+ constructor(prisma: any);
6
+ createDeliveriesInTransaction(tx: any, eventId: string, endpointIds: string[], maxAttempts: number): Promise<void>;
7
+ runInTransaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T>;
8
+ claimPendingDeliveries(batchSize: number): Promise<PendingDelivery[]>;
9
+ enrichDeliveries(deliveryIds: string[]): Promise<PendingDelivery[]>;
10
+ markSent(deliveryId: string, attempts: number, result: DeliveryResult): Promise<void>;
11
+ markFailed(deliveryId: string, attempts: number, result: DeliveryResult): Promise<void>;
12
+ markRetry(deliveryId: string, attempts: number, nextAt: Date, result: DeliveryResult): Promise<void>;
13
+ recoverStaleSending(stalenessMinutes: number): Promise<number>;
14
+ getDeliveryLogs(endpointId: string, filters?: DeliveryLogFilters): Promise<DeliveryRecord[]>;
15
+ retryDelivery(deliveryId: string): Promise<boolean>;
16
+ createTestDelivery(eventId: string, endpointId: string): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=prisma-delivery.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,yBAAyB,EAC1B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACf,MAAM,0CAA0C,CAAC;AAElD,qBACa,wBAAyB,YAAW,yBAAyB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,GAAG;IAElC,6BAA6B,CACjC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAUV,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhE,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAqBrE,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAYnE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAY9D,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC;IAgDtB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQnD,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK7E"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PrismaDeliveryRepository = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ let PrismaDeliveryRepository = class PrismaDeliveryRepository {
15
+ prisma;
16
+ constructor(prisma) {
17
+ this.prisma = prisma;
18
+ }
19
+ async createDeliveriesInTransaction(tx, eventId, endpointIds, maxAttempts) {
20
+ await tx.$executeRawUnsafe(`INSERT INTO webhook_deliveries (event_id, endpoint_id, status, attempts, max_attempts, next_attempt_at)
21
+ SELECT $1::uuid, unnest($2::uuid[]), 'PENDING', 0, $3, NOW()`, eventId, endpointIds, maxAttempts);
22
+ }
23
+ async runInTransaction(fn) {
24
+ return this.prisma.$transaction(fn);
25
+ }
26
+ async claimPendingDeliveries(batchSize) {
27
+ return this.prisma.$queryRaw `
28
+ UPDATE webhook_deliveries
29
+ SET status = 'SENDING', claimed_at = NOW()
30
+ WHERE id IN (
31
+ SELECT d.id
32
+ FROM webhook_deliveries d
33
+ WHERE d.status = 'PENDING'
34
+ AND d.next_attempt_at <= NOW()
35
+ ORDER BY d.next_attempt_at ASC
36
+ LIMIT ${batchSize}
37
+ FOR UPDATE SKIP LOCKED
38
+ )
39
+ RETURNING
40
+ webhook_deliveries.id,
41
+ webhook_deliveries.event_id,
42
+ webhook_deliveries.endpoint_id,
43
+ webhook_deliveries.attempts,
44
+ webhook_deliveries.max_attempts`;
45
+ }
46
+ async enrichDeliveries(deliveryIds) {
47
+ return this.prisma.$queryRaw `
48
+ SELECT
49
+ d.id, d.event_id, d.endpoint_id, d.attempts, d.max_attempts,
50
+ e.url, e.secret,
51
+ ev.event_type, ev.payload
52
+ FROM webhook_deliveries d
53
+ JOIN webhook_endpoints e ON e.id = d.endpoint_id
54
+ JOIN webhook_events ev ON ev.id = d.event_id
55
+ WHERE d.id = ANY(${deliveryIds}::uuid[])`;
56
+ }
57
+ async markSent(deliveryId, attempts, result) {
58
+ await this.prisma.$executeRaw `
59
+ UPDATE webhook_deliveries
60
+ SET status = 'SENT', attempts = ${attempts},
61
+ last_attempt_at = NOW(), completed_at = NOW(),
62
+ response_status = ${result.statusCode ?? null},
63
+ response_body = ${result.body ?? null},
64
+ latency_ms = ${result.latencyMs}
65
+ WHERE id = ${deliveryId}::uuid`;
66
+ }
67
+ async markFailed(deliveryId, attempts, result) {
68
+ await this.prisma.$executeRaw `
69
+ UPDATE webhook_deliveries
70
+ SET status = 'FAILED', attempts = ${attempts},
71
+ last_attempt_at = NOW(), completed_at = NOW(),
72
+ response_status = ${result.statusCode ?? null},
73
+ response_body = ${result.body ?? null},
74
+ latency_ms = ${result.latencyMs},
75
+ last_error = ${result.error ?? null}
76
+ WHERE id = ${deliveryId}::uuid`;
77
+ }
78
+ async markRetry(deliveryId, attempts, nextAt, result) {
79
+ await this.prisma.$executeRaw `
80
+ UPDATE webhook_deliveries
81
+ SET status = 'PENDING', attempts = ${attempts},
82
+ last_attempt_at = NOW(), next_attempt_at = ${nextAt},
83
+ response_status = ${result.statusCode ?? null},
84
+ response_body = ${result.body ?? null},
85
+ latency_ms = ${result.latencyMs},
86
+ last_error = ${result.error ?? null}
87
+ WHERE id = ${deliveryId}::uuid`;
88
+ }
89
+ async recoverStaleSending(stalenessMinutes) {
90
+ const interval = `${stalenessMinutes} minutes`;
91
+ const recovered = await this.prisma.$queryRaw `
92
+ UPDATE webhook_deliveries
93
+ SET status = 'PENDING', claimed_at = NULL
94
+ WHERE status = 'SENDING'
95
+ AND claimed_at IS NOT NULL
96
+ AND claimed_at + ${interval}::interval < NOW()
97
+ RETURNING id`;
98
+ return recovered.length;
99
+ }
100
+ async getDeliveryLogs(endpointId, filters) {
101
+ const conditions = ['d.endpoint_id = $1::uuid'];
102
+ const values = [endpointId];
103
+ let paramIndex = 2;
104
+ if (filters?.status) {
105
+ conditions.push(`d.status = $${paramIndex++}`);
106
+ values.push(filters.status);
107
+ }
108
+ if (filters?.eventType) {
109
+ conditions.push(`ev.event_type = $${paramIndex++}`);
110
+ values.push(filters.eventType);
111
+ }
112
+ if (filters?.since) {
113
+ conditions.push(`d.last_attempt_at >= $${paramIndex++}`);
114
+ values.push(filters.since);
115
+ }
116
+ if (filters?.until) {
117
+ conditions.push(`d.last_attempt_at <= $${paramIndex++}`);
118
+ values.push(filters.until);
119
+ }
120
+ const limit = filters?.limit ?? 50;
121
+ const offset = filters?.offset ?? 0;
122
+ const query = `
123
+ SELECT d.id, d.status, d.attempts,
124
+ d.event_id AS "eventId",
125
+ d.endpoint_id AS "endpointId",
126
+ d.max_attempts AS "maxAttempts",
127
+ d.next_attempt_at AS "nextAttemptAt",
128
+ d.last_attempt_at AS "lastAttemptAt",
129
+ d.completed_at AS "completedAt",
130
+ d.response_status AS "responseStatus",
131
+ d.response_body AS "responseBody",
132
+ d.latency_ms AS "latencyMs",
133
+ d.last_error AS "lastError"
134
+ FROM webhook_deliveries d
135
+ JOIN webhook_events ev ON ev.id = d.event_id
136
+ WHERE ${conditions.join(' AND ')}
137
+ ORDER BY d.last_attempt_at DESC NULLS LAST
138
+ LIMIT $${paramIndex++}
139
+ OFFSET $${paramIndex}`;
140
+ values.push(limit, offset);
141
+ const results = await this.prisma.$queryRawUnsafe(query, ...values);
142
+ return results;
143
+ }
144
+ async retryDelivery(deliveryId) {
145
+ const result = await this.prisma.$executeRaw `
146
+ UPDATE webhook_deliveries
147
+ SET status = 'PENDING', next_attempt_at = NOW()
148
+ WHERE id = ${deliveryId}::uuid AND status = 'FAILED'`;
149
+ return result > 0;
150
+ }
151
+ async createTestDelivery(eventId, endpointId) {
152
+ await this.prisma.$executeRaw `
153
+ INSERT INTO webhook_deliveries (event_id, endpoint_id, status, max_attempts, next_attempt_at)
154
+ VALUES (${eventId}::uuid, ${endpointId}::uuid, 'PENDING', 1, NOW())`;
155
+ }
156
+ };
157
+ exports.PrismaDeliveryRepository = PrismaDeliveryRepository;
158
+ exports.PrismaDeliveryRepository = PrismaDeliveryRepository = __decorate([
159
+ (0, common_1.Injectable)(),
160
+ __metadata("design:paramtypes", [Object])
161
+ ], PrismaDeliveryRepository);
162
+ //# sourceMappingURL=prisma-delivery.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-delivery.repository.js","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { WebhookEndpointRepository } from '../ports/webhook-endpoint.repository';
2
+ import { EndpointRecord, EndpointRecordWithSecret, UpdateEndpointDto } from '../interfaces/webhook-endpoint.interface';
3
+ export declare class PrismaEndpointRepository implements WebhookEndpointRepository {
4
+ private readonly prisma;
5
+ constructor(prisma: any);
6
+ findMatchingEndpoints(eventType: string, tenantId: string | undefined): Promise<EndpointRecord[]>;
7
+ findMatchingEndpointsInTransaction(tx: any, eventType: string, tenantId: string | undefined): Promise<EndpointRecord[]>;
8
+ createEndpoint(url: string, secret: string, events: string[], description: string | null, metadata: Record<string, unknown> | null, tenantId: string | null): Promise<EndpointRecordWithSecret>;
9
+ getEndpoint(id: string): Promise<EndpointRecord | null>;
10
+ listEndpoints(tenantId?: string): Promise<EndpointRecord[]>;
11
+ updateEndpoint(id: string, dto: UpdateEndpointDto): Promise<EndpointRecord | null>;
12
+ deleteEndpoint(id: string): Promise<boolean>;
13
+ resetFailures(endpointId: string): Promise<void>;
14
+ incrementFailures(endpointId: string): Promise<number>;
15
+ disableEndpoint(endpointId: string, reason: string): Promise<void>;
16
+ recoverEligibleEndpoints(cooldownMinutes: number): Promise<number>;
17
+ }
18
+ //# sourceMappingURL=prisma-endpoint.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-endpoint.repository.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma-endpoint.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,iBAAiB,EAClB,MAAM,0CAA0C,CAAC;AAsBlD,qBACa,wBAAyB,YAAW,yBAAyB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,GAAG;IAElC,qBAAqB,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC;IAoBtB,kCAAkC,CACtC,EAAE,EAAE,GAAG,EACP,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC;IAoBtB,cAAc,CAClB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EAAE,EAChB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACxC,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAAC,wBAAwB,CAAC;IAe9B,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAQvD,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAe3D,cAAc,CAClB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAqC3B,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAStD,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAYzE"}