Go · 18642 bytes Raw Blame History
1 // Code generated by sqlc. DO NOT EDIT.
2 // versions:
3 // sqlc v1.31.1
4 // source: webhooks.sql
5
6 package webhookdb
7
8 import (
9 "context"
10
11 "github.com/jackc/pgx/v5/pgtype"
12 )
13
14 const autoDisableWebhook = `-- name: AutoDisableWebhook :exec
15 UPDATE webhooks
16 SET disabled_at = now(),
17 disabled_reason = $2,
18 updated_at = now()
19 WHERE id = $1
20 `
21
22 type AutoDisableWebhookParams struct {
23 ID int64
24 DisabledReason pgtype.Text
25 }
26
27 func (q *Queries) AutoDisableWebhook(ctx context.Context, db DBTX, arg AutoDisableWebhookParams) error {
28 _, err := db.Exec(ctx, autoDisableWebhook, arg.ID, arg.DisabledReason)
29 return err
30 }
31
32 const claimDueDeliveries = `-- name: ClaimDueDeliveries :many
33 SELECT id FROM webhook_deliveries
34 WHERE status IN ('pending', 'failed_retry')
35 AND (next_retry_at IS NULL OR next_retry_at <= now())
36 ORDER BY next_retry_at NULLS FIRST, id
37 LIMIT $1
38 FOR UPDATE SKIP LOCKED
39 `
40
41 // Hot-path for the deliver worker: picks up to $1 rows that are
42 // pending or in retry-ready state, FOR UPDATE SKIP LOCKED so concurrent
43 // workers don't double-send. The deliverer marks the row 'pending'
44 // with a far-future next_retry_at while it works on it (defense
45 // against re-claim during a long HTTP timeout).
46 func (q *Queries) ClaimDueDeliveries(ctx context.Context, db DBTX, limit int32) ([]int64, error) {
47 rows, err := db.Query(ctx, claimDueDeliveries, limit)
48 if err != nil {
49 return nil, err
50 }
51 defer rows.Close()
52 items := []int64{}
53 for rows.Next() {
54 var id int64
55 if err := rows.Scan(&id); err != nil {
56 return nil, err
57 }
58 items = append(items, id)
59 }
60 if err := rows.Err(); err != nil {
61 return nil, err
62 }
63 return items, nil
64 }
65
66 const createDelivery = `-- name: CreateDelivery :one
67 INSERT INTO webhook_deliveries (
68 webhook_id, event_kind, event_id, payload, request_headers,
69 request_body, attempt, max_attempts, next_retry_at, status,
70 idempotency_key, redeliver_of
71 ) VALUES (
72 $1, $2, $3::bigint,
73 $4, $5, $6,
74 $7, $8, $9::timestamptz,
75 $10, $11, $12::bigint
76 )
77 RETURNING id, webhook_id, event_kind, event_id, delivery_uuid, payload, request_headers, request_body, response_status, response_headers, response_body, response_truncated, started_at, completed_at, attempt, max_attempts, next_retry_at, status, idempotency_key, error_summary, redeliver_of
78 `
79
80 type CreateDeliveryParams struct {
81 WebhookID int64
82 EventKind string
83 EventID pgtype.Int8
84 Payload []byte
85 RequestHeaders []byte
86 RequestBody []byte
87 Attempt int32
88 MaxAttempts int32
89 NextRetryAt pgtype.Timestamptz
90 Status WebhookDeliveryStatus
91 IdempotencyKey string
92 RedeliverOf pgtype.Int8
93 }
94
95 func (q *Queries) CreateDelivery(ctx context.Context, db DBTX, arg CreateDeliveryParams) (WebhookDelivery, error) {
96 row := db.QueryRow(ctx, createDelivery,
97 arg.WebhookID,
98 arg.EventKind,
99 arg.EventID,
100 arg.Payload,
101 arg.RequestHeaders,
102 arg.RequestBody,
103 arg.Attempt,
104 arg.MaxAttempts,
105 arg.NextRetryAt,
106 arg.Status,
107 arg.IdempotencyKey,
108 arg.RedeliverOf,
109 )
110 var i WebhookDelivery
111 err := row.Scan(
112 &i.ID,
113 &i.WebhookID,
114 &i.EventKind,
115 &i.EventID,
116 &i.DeliveryUuid,
117 &i.Payload,
118 &i.RequestHeaders,
119 &i.RequestBody,
120 &i.ResponseStatus,
121 &i.ResponseHeaders,
122 &i.ResponseBody,
123 &i.ResponseTruncated,
124 &i.StartedAt,
125 &i.CompletedAt,
126 &i.Attempt,
127 &i.MaxAttempts,
128 &i.NextRetryAt,
129 &i.Status,
130 &i.IdempotencyKey,
131 &i.ErrorSummary,
132 &i.RedeliverOf,
133 )
134 return i, err
135 }
136
137 const createWebhook = `-- name: CreateWebhook :one
138
139 INSERT INTO webhooks (
140 owner_kind, owner_id, url, content_type, events,
141 secret_ciphertext, secret_nonce, active, ssl_verification,
142 auto_disable_threshold, created_by_user_id
143 ) VALUES (
144 $1, $2, $3,
145 $4, $5,
146 $6, $7,
147 $8, $9,
148 $10,
149 $11::bigint
150 )
151 RETURNING id, owner_kind, owner_id, url, content_type, events, secret_ciphertext, secret_nonce, active, ssl_verification, consecutive_failures, auto_disable_threshold, disabled_at, disabled_reason, last_success_at, last_failure_at, created_by_user_id, created_at, updated_at
152 `
153
154 type CreateWebhookParams struct {
155 OwnerKind WebhookOwnerKind
156 OwnerID int64
157 Url string
158 ContentType WebhookContentType
159 Events []string
160 SecretCiphertext []byte
161 SecretNonce []byte
162 Active bool
163 SslVerification bool
164 AutoDisableThreshold int32
165 CreatedByUserID pgtype.Int8
166 }
167
168 // SPDX-License-Identifier: AGPL-3.0-or-later
169 //
170 // Query surface for the webhook package. Naming mirrors the verb the
171 // caller uses; visibility / ownership filters are applied by the
172 // handler layer (the queries are deliberately narrow on key columns).
173 func (q *Queries) CreateWebhook(ctx context.Context, db DBTX, arg CreateWebhookParams) (Webhook, error) {
174 row := db.QueryRow(ctx, createWebhook,
175 arg.OwnerKind,
176 arg.OwnerID,
177 arg.Url,
178 arg.ContentType,
179 arg.Events,
180 arg.SecretCiphertext,
181 arg.SecretNonce,
182 arg.Active,
183 arg.SslVerification,
184 arg.AutoDisableThreshold,
185 arg.CreatedByUserID,
186 )
187 var i Webhook
188 err := row.Scan(
189 &i.ID,
190 &i.OwnerKind,
191 &i.OwnerID,
192 &i.Url,
193 &i.ContentType,
194 &i.Events,
195 &i.SecretCiphertext,
196 &i.SecretNonce,
197 &i.Active,
198 &i.SslVerification,
199 &i.ConsecutiveFailures,
200 &i.AutoDisableThreshold,
201 &i.DisabledAt,
202 &i.DisabledReason,
203 &i.LastSuccessAt,
204 &i.LastFailureAt,
205 &i.CreatedByUserID,
206 &i.CreatedAt,
207 &i.UpdatedAt,
208 )
209 return i, err
210 }
211
212 const deleteWebhook = `-- name: DeleteWebhook :exec
213 DELETE FROM webhooks WHERE id = $1
214 `
215
216 func (q *Queries) DeleteWebhook(ctx context.Context, db DBTX, id int64) error {
217 _, err := db.Exec(ctx, deleteWebhook, id)
218 return err
219 }
220
221 const getDeliveryByID = `-- name: GetDeliveryByID :one
222 SELECT id, webhook_id, event_kind, event_id, delivery_uuid, payload, request_headers, request_body, response_status, response_headers, response_body, response_truncated, started_at, completed_at, attempt, max_attempts, next_retry_at, status, idempotency_key, error_summary, redeliver_of FROM webhook_deliveries WHERE id = $1
223 `
224
225 func (q *Queries) GetDeliveryByID(ctx context.Context, db DBTX, id int64) (WebhookDelivery, error) {
226 row := db.QueryRow(ctx, getDeliveryByID, id)
227 var i WebhookDelivery
228 err := row.Scan(
229 &i.ID,
230 &i.WebhookID,
231 &i.EventKind,
232 &i.EventID,
233 &i.DeliveryUuid,
234 &i.Payload,
235 &i.RequestHeaders,
236 &i.RequestBody,
237 &i.ResponseStatus,
238 &i.ResponseHeaders,
239 &i.ResponseBody,
240 &i.ResponseTruncated,
241 &i.StartedAt,
242 &i.CompletedAt,
243 &i.Attempt,
244 &i.MaxAttempts,
245 &i.NextRetryAt,
246 &i.Status,
247 &i.IdempotencyKey,
248 &i.ErrorSummary,
249 &i.RedeliverOf,
250 )
251 return i, err
252 }
253
254 const getWebhookByID = `-- name: GetWebhookByID :one
255 SELECT id, owner_kind, owner_id, url, content_type, events, secret_ciphertext, secret_nonce, active, ssl_verification, consecutive_failures, auto_disable_threshold, disabled_at, disabled_reason, last_success_at, last_failure_at, created_by_user_id, created_at, updated_at FROM webhooks WHERE id = $1
256 `
257
258 func (q *Queries) GetWebhookByID(ctx context.Context, db DBTX, id int64) (Webhook, error) {
259 row := db.QueryRow(ctx, getWebhookByID, id)
260 var i Webhook
261 err := row.Scan(
262 &i.ID,
263 &i.OwnerKind,
264 &i.OwnerID,
265 &i.Url,
266 &i.ContentType,
267 &i.Events,
268 &i.SecretCiphertext,
269 &i.SecretNonce,
270 &i.Active,
271 &i.SslVerification,
272 &i.ConsecutiveFailures,
273 &i.AutoDisableThreshold,
274 &i.DisabledAt,
275 &i.DisabledReason,
276 &i.LastSuccessAt,
277 &i.LastFailureAt,
278 &i.CreatedByUserID,
279 &i.CreatedAt,
280 &i.UpdatedAt,
281 )
282 return i, err
283 }
284
285 const listActiveWebhooksForOwner = `-- name: ListActiveWebhooksForOwner :many
286 SELECT id, owner_kind, owner_id, url, content_type, events, secret_ciphertext, secret_nonce, active, ssl_verification, consecutive_failures, auto_disable_threshold, disabled_at, disabled_reason, last_success_at, last_failure_at, created_by_user_id, created_at, updated_at FROM webhooks
287 WHERE owner_kind = $1 AND owner_id = $2
288 AND active = true AND disabled_at IS NULL
289 `
290
291 type ListActiveWebhooksForOwnerParams struct {
292 OwnerKind WebhookOwnerKind
293 OwnerID int64
294 }
295
296 // Used by fanout to find subscribers for an event.
297 func (q *Queries) ListActiveWebhooksForOwner(ctx context.Context, db DBTX, arg ListActiveWebhooksForOwnerParams) ([]Webhook, error) {
298 rows, err := db.Query(ctx, listActiveWebhooksForOwner, arg.OwnerKind, arg.OwnerID)
299 if err != nil {
300 return nil, err
301 }
302 defer rows.Close()
303 items := []Webhook{}
304 for rows.Next() {
305 var i Webhook
306 if err := rows.Scan(
307 &i.ID,
308 &i.OwnerKind,
309 &i.OwnerID,
310 &i.Url,
311 &i.ContentType,
312 &i.Events,
313 &i.SecretCiphertext,
314 &i.SecretNonce,
315 &i.Active,
316 &i.SslVerification,
317 &i.ConsecutiveFailures,
318 &i.AutoDisableThreshold,
319 &i.DisabledAt,
320 &i.DisabledReason,
321 &i.LastSuccessAt,
322 &i.LastFailureAt,
323 &i.CreatedByUserID,
324 &i.CreatedAt,
325 &i.UpdatedAt,
326 ); err != nil {
327 return nil, err
328 }
329 items = append(items, i)
330 }
331 if err := rows.Err(); err != nil {
332 return nil, err
333 }
334 return items, nil
335 }
336
337 const listDeliveriesForWebhook = `-- name: ListDeliveriesForWebhook :many
338 SELECT id, webhook_id, event_kind, event_id, delivery_uuid, response_status,
339 response_truncated, started_at, completed_at, attempt, max_attempts,
340 next_retry_at, status, error_summary, redeliver_of
341 FROM webhook_deliveries
342 WHERE webhook_id = $1
343 ORDER BY started_at DESC
344 LIMIT $2
345 `
346
347 type ListDeliveriesForWebhookParams struct {
348 WebhookID int64
349 Limit int32
350 }
351
352 type ListDeliveriesForWebhookRow struct {
353 ID int64
354 WebhookID int64
355 EventKind string
356 EventID pgtype.Int8
357 DeliveryUuid pgtype.UUID
358 ResponseStatus pgtype.Int4
359 ResponseTruncated bool
360 StartedAt pgtype.Timestamptz
361 CompletedAt pgtype.Timestamptz
362 Attempt int32
363 MaxAttempts int32
364 NextRetryAt pgtype.Timestamptz
365 Status WebhookDeliveryStatus
366 ErrorSummary pgtype.Text
367 RedeliverOf pgtype.Int8
368 }
369
370 func (q *Queries) ListDeliveriesForWebhook(ctx context.Context, db DBTX, arg ListDeliveriesForWebhookParams) ([]ListDeliveriesForWebhookRow, error) {
371 rows, err := db.Query(ctx, listDeliveriesForWebhook, arg.WebhookID, arg.Limit)
372 if err != nil {
373 return nil, err
374 }
375 defer rows.Close()
376 items := []ListDeliveriesForWebhookRow{}
377 for rows.Next() {
378 var i ListDeliveriesForWebhookRow
379 if err := rows.Scan(
380 &i.ID,
381 &i.WebhookID,
382 &i.EventKind,
383 &i.EventID,
384 &i.DeliveryUuid,
385 &i.ResponseStatus,
386 &i.ResponseTruncated,
387 &i.StartedAt,
388 &i.CompletedAt,
389 &i.Attempt,
390 &i.MaxAttempts,
391 &i.NextRetryAt,
392 &i.Status,
393 &i.ErrorSummary,
394 &i.RedeliverOf,
395 ); err != nil {
396 return nil, err
397 }
398 items = append(items, i)
399 }
400 if err := rows.Err(); err != nil {
401 return nil, err
402 }
403 return items, nil
404 }
405
406 const listWebhooksForOwner = `-- name: ListWebhooksForOwner :many
407 SELECT id, owner_kind, owner_id, url, content_type, events, secret_ciphertext, secret_nonce, active, ssl_verification, consecutive_failures, auto_disable_threshold, disabled_at, disabled_reason, last_success_at, last_failure_at, created_by_user_id, created_at, updated_at FROM webhooks
408 WHERE owner_kind = $1 AND owner_id = $2
409 ORDER BY created_at DESC
410 `
411
412 type ListWebhooksForOwnerParams struct {
413 OwnerKind WebhookOwnerKind
414 OwnerID int64
415 }
416
417 func (q *Queries) ListWebhooksForOwner(ctx context.Context, db DBTX, arg ListWebhooksForOwnerParams) ([]Webhook, error) {
418 rows, err := db.Query(ctx, listWebhooksForOwner, arg.OwnerKind, arg.OwnerID)
419 if err != nil {
420 return nil, err
421 }
422 defer rows.Close()
423 items := []Webhook{}
424 for rows.Next() {
425 var i Webhook
426 if err := rows.Scan(
427 &i.ID,
428 &i.OwnerKind,
429 &i.OwnerID,
430 &i.Url,
431 &i.ContentType,
432 &i.Events,
433 &i.SecretCiphertext,
434 &i.SecretNonce,
435 &i.Active,
436 &i.SslVerification,
437 &i.ConsecutiveFailures,
438 &i.AutoDisableThreshold,
439 &i.DisabledAt,
440 &i.DisabledReason,
441 &i.LastSuccessAt,
442 &i.LastFailureAt,
443 &i.CreatedByUserID,
444 &i.CreatedAt,
445 &i.UpdatedAt,
446 ); err != nil {
447 return nil, err
448 }
449 items = append(items, i)
450 }
451 if err := rows.Err(); err != nil {
452 return nil, err
453 }
454 return items, nil
455 }
456
457 const markDeliveryPermanentFailure = `-- name: MarkDeliveryPermanentFailure :exec
458 UPDATE webhook_deliveries
459 SET status = 'failed_permanent',
460 response_status = $1::int,
461 response_headers = $2::jsonb,
462 response_body = $3::bytea,
463 response_truncated = $4::bool,
464 completed_at = now(),
465 error_summary = $5::text
466 WHERE id = $6::bigint
467 `
468
469 type MarkDeliveryPermanentFailureParams struct {
470 ResponseStatus pgtype.Int4
471 ResponseHeaders []byte
472 ResponseBody []byte
473 ResponseTruncated bool
474 ErrorSummary string
475 ID int64
476 }
477
478 func (q *Queries) MarkDeliveryPermanentFailure(ctx context.Context, db DBTX, arg MarkDeliveryPermanentFailureParams) error {
479 _, err := db.Exec(ctx, markDeliveryPermanentFailure,
480 arg.ResponseStatus,
481 arg.ResponseHeaders,
482 arg.ResponseBody,
483 arg.ResponseTruncated,
484 arg.ErrorSummary,
485 arg.ID,
486 )
487 return err
488 }
489
490 const markDeliveryRetry = `-- name: MarkDeliveryRetry :exec
491 UPDATE webhook_deliveries
492 SET status = 'failed_retry',
493 attempt = attempt + 1,
494 response_status = $1::int,
495 response_headers = $2::jsonb,
496 response_body = $3::bytea,
497 response_truncated = $4::bool,
498 next_retry_at = $5::timestamptz,
499 error_summary = $6::text
500 WHERE id = $7::bigint
501 `
502
503 type MarkDeliveryRetryParams struct {
504 ResponseStatus pgtype.Int4
505 ResponseHeaders []byte
506 ResponseBody []byte
507 ResponseTruncated bool
508 NextRetryAt pgtype.Timestamptz
509 ErrorSummary string
510 ID int64
511 }
512
513 func (q *Queries) MarkDeliveryRetry(ctx context.Context, db DBTX, arg MarkDeliveryRetryParams) error {
514 _, err := db.Exec(ctx, markDeliveryRetry,
515 arg.ResponseStatus,
516 arg.ResponseHeaders,
517 arg.ResponseBody,
518 arg.ResponseTruncated,
519 arg.NextRetryAt,
520 arg.ErrorSummary,
521 arg.ID,
522 )
523 return err
524 }
525
526 const markDeliverySucceeded = `-- name: MarkDeliverySucceeded :exec
527 UPDATE webhook_deliveries
528 SET status = 'succeeded',
529 response_status = $2,
530 response_headers = $3,
531 response_body = $4,
532 response_truncated = $5,
533 completed_at = now(),
534 error_summary = NULL
535 WHERE id = $1
536 `
537
538 type MarkDeliverySucceededParams struct {
539 ID int64
540 ResponseStatus pgtype.Int4
541 ResponseHeaders []byte
542 ResponseBody []byte
543 ResponseTruncated bool
544 }
545
546 func (q *Queries) MarkDeliverySucceeded(ctx context.Context, db DBTX, arg MarkDeliverySucceededParams) error {
547 _, err := db.Exec(ctx, markDeliverySucceeded,
548 arg.ID,
549 arg.ResponseStatus,
550 arg.ResponseHeaders,
551 arg.ResponseBody,
552 arg.ResponseTruncated,
553 )
554 return err
555 }
556
557 const purgeOldDeliveries = `-- name: PurgeOldDeliveries :execrows
558 DELETE FROM webhook_deliveries
559 WHERE status IN ('succeeded', 'failed_permanent')
560 AND completed_at < now() - $1::interval
561 `
562
563 // Cron: drops terminal deliveries older than the retention window.
564 // pending/failed_retry rows are left alone so an in-flight retry isn't
565 // aborted out from under the worker.
566 func (q *Queries) PurgeOldDeliveries(ctx context.Context, db DBTX, retention pgtype.Interval) (int64, error) {
567 result, err := db.Exec(ctx, purgeOldDeliveries, retention)
568 if err != nil {
569 return 0, err
570 }
571 return result.RowsAffected(), nil
572 }
573
574 const recordWebhookFailure = `-- name: RecordWebhookFailure :one
575 UPDATE webhooks
576 SET consecutive_failures = consecutive_failures + 1,
577 last_failure_at = now(),
578 updated_at = now()
579 WHERE id = $1
580 RETURNING consecutive_failures, auto_disable_threshold
581 `
582
583 type RecordWebhookFailureRow struct {
584 ConsecutiveFailures int32
585 AutoDisableThreshold int32
586 }
587
588 // Increments the failure counter and reports the new value so the
589 // caller can decide whether to auto-disable.
590 func (q *Queries) RecordWebhookFailure(ctx context.Context, db DBTX, id int64) (RecordWebhookFailureRow, error) {
591 row := db.QueryRow(ctx, recordWebhookFailure, id)
592 var i RecordWebhookFailureRow
593 err := row.Scan(&i.ConsecutiveFailures, &i.AutoDisableThreshold)
594 return i, err
595 }
596
597 const recordWebhookSuccess = `-- name: RecordWebhookSuccess :exec
598 UPDATE webhooks
599 SET consecutive_failures = 0,
600 last_success_at = now(),
601 updated_at = now()
602 WHERE id = $1
603 `
604
605 func (q *Queries) RecordWebhookSuccess(ctx context.Context, db DBTX, id int64) error {
606 _, err := db.Exec(ctx, recordWebhookSuccess, id)
607 return err
608 }
609
610 const setWebhookActive = `-- name: SetWebhookActive :exec
611 UPDATE webhooks
612 SET active = $2,
613 disabled_at = NULL,
614 disabled_reason = NULL,
615 consecutive_failures = 0,
616 updated_at = now()
617 WHERE id = $1
618 `
619
620 type SetWebhookActiveParams struct {
621 ID int64
622 Active bool
623 }
624
625 // Re-enables a previously auto-disabled webhook (UI affordance).
626 // Resets the failure counter and clears disabled_at/reason.
627 func (q *Queries) SetWebhookActive(ctx context.Context, db DBTX, arg SetWebhookActiveParams) error {
628 _, err := db.Exec(ctx, setWebhookActive, arg.ID, arg.Active)
629 return err
630 }
631
632 const updateWebhook = `-- name: UpdateWebhook :exec
633 UPDATE webhooks
634 SET url = $2,
635 content_type = $3,
636 events = $4,
637 active = $5,
638 ssl_verification = $6,
639 auto_disable_threshold = $7,
640 updated_at = now()
641 WHERE id = $1
642 `
643
644 type UpdateWebhookParams struct {
645 ID int64
646 Url string
647 ContentType WebhookContentType
648 Events []string
649 Active bool
650 SslVerification bool
651 AutoDisableThreshold int32
652 }
653
654 func (q *Queries) UpdateWebhook(ctx context.Context, db DBTX, arg UpdateWebhookParams) error {
655 _, err := db.Exec(ctx, updateWebhook,
656 arg.ID,
657 arg.Url,
658 arg.ContentType,
659 arg.Events,
660 arg.Active,
661 arg.SslVerification,
662 arg.AutoDisableThreshold,
663 )
664 return err
665 }
666
667 const updateWebhookSecret = `-- name: UpdateWebhookSecret :exec
668 UPDATE webhooks
669 SET secret_ciphertext = $2,
670 secret_nonce = $3,
671 updated_at = now()
672 WHERE id = $1
673 `
674
675 type UpdateWebhookSecretParams struct {
676 ID int64
677 SecretCiphertext []byte
678 SecretNonce []byte
679 }
680
681 func (q *Queries) UpdateWebhookSecret(ctx context.Context, db DBTX, arg UpdateWebhookSecretParams) error {
682 _, err := db.Exec(ctx, updateWebhookSecret, arg.ID, arg.SecretCiphertext, arg.SecretNonce)
683 return err
684 }
685