Skip to content

[codex] fix webhook queue scheduling#1872

Open
riderx wants to merge 10 commits intomainfrom
fix_webhooks
Open

[codex] fix webhook queue scheduling#1872
riderx wants to merge 10 commits intomainfrom
fix_webhooks

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented Mar 27, 2026

Summary (AI generated)

  • restore webhook_dispatcher and webhook_delivery in the active high_frequency_queues cron task
  • add a SQL regression test to ensure webhook queues stay registered in public.cron_tasks
  • add a focused integration test that exercises webhook dispatcher and delivery queue processing end to end

Motivation (AI generated)

A scheduler regression left webhook jobs enqueued but never drained. The webhook migration added the queues to the old hard-coded cron runner, but the later table-driven cron_tasks migration rebuilt high_frequency_queues without carrying those queue names forward.

Business Impact (AI generated)

Webhook deliveries back customer integrations and downstream automation. When those jobs stay stuck in the queue, Capgo records the events but never sends them, which breaks customer workflows and undermines reliability.

Test Plan (AI generated)

  • bun lint
  • bun lint:backend
  • bunx eslint tests/webhook-queue-processing.test.ts
  • bunx supabase test db
  • bun run supabase:with-env -- bunx vitest run tests/webhook-queue-processing.test.ts

Local Supabase bootstrap was still pulling first-run Docker images during this session, so the DB and integration runs were not completed here.

Generated with AI

Summary by CodeRabbit

  • Chores

    • Upgraded Supabase client dependencies to newer versions.
  • Bug Fixes

    • Ensured the high-frequency cron task includes both webhook dispatcher and delivery queues.
    • Fixed manifest lookup to select the correct bundle/version for download requests.
    • Improved webhook delivery handler to accept both direct and envelope-formatted inputs.
  • Tests

    • Added automated and end-to-end tests validating cron registration and full webhook delivery processing.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Updates Supabase client versions, adds a migration to include webhook queues in the high_frequency_queues cron task, introduces SQL and Vitest tests for webhook queue registration and end-to-end processing, and tweaks manifest lookup and webhook delivery input parsing in backend functions.

Changes

Cohort / File(s) Summary
Dependencies
package.json
Bumped @supabase/supabase-js from 2.93.32.100.1 and supabase from ^2.78.1^2.84.2.
Database Migration
supabase/migrations/20260327220305_add_webhook_queues_to_cron_tasks.sql
New migration rewrites public.cron_tasks row high_frequency_queues target to include webhook_dispatcher and webhook_delivery as a normalized JSONB array (with fallback).
Database Tests
supabase/tests/49_test_webhook_cron_registration.sql
New SQL test asserting high_frequency_queues exists, is enabled, task_type = 'function_queue', and target contains both webhook_dispatcher and webhook_delivery.
Integration Tests
tests/webhook-queue-processing.test.ts
Adds Vitest e2e test: seeds rows, sends a PGMQ webhook_dispatcher message, triggers consumer sync endpoints (retry/backoff), polls webhook_deliveries and PGMQ queue, and asserts lifecycle fields (status, attempt_count, response_body).
Function logic tweaks
supabase/functions/_backend/private/download_link.ts, supabase/functions/_backend/triggers/webhook_delivery.ts
download_link manifest lookup now filters by .eq('app_version_id', bundle.id) instead of .eq('app_id', body.app_id') & .eq('id', body.id); webhook_delivery input parsing now conditionally treats top-level body as a DeliveryMessage if it contains delivery_id, webhook_id, and url, otherwise falls back to `body.payload

Sequence Diagram(s)

sequenceDiagram
  participant Test as Test Runner
  participant PGMQ as PGMQ
  participant Dispatcher as webhook_dispatcher Consumer
  participant DB as Postgres (webhook_deliveries)
  participant Delivery as webhook_delivery Consumer

  Test->>PGMQ: send message to topic `webhook_dispatcher` (apps.UPDATE payload)
  PGMQ->>Dispatcher: deliver message
  Dispatcher->>DB: insert webhook_deliveries row (status: pending, event_type)
  Test->>Dispatcher: POST /triggers/queue_consumer/sync (retry/backoff) -> 202 OK
  Dispatcher->>DB: ensure delivery row exists
  Test->>Delivery: POST /triggers/queue_consumer/sync (retry/backoff) -> 202 OK
  Delivery->>DB: process delivery -> update status (failed), attempt_count, response_body
  Test->>DB: poll until final status observed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

codex

Poem

🐰 I hopped through migrations with a fluffy, eager twitch,

Queues now hold two names, tucked safely in a niche.
Tests fling tiny carrots down PGMQ lanes,
Consumers nibble, retrying through the rains.
A rabbit cheers: deliveries stitched and versions switched.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title '[codex] fix webhook queue scheduling' clearly summarizes the main change: fixing webhook queue scheduling by restoring the webhook queues to the cron task.
Description check ✅ Passed The PR description covers the summary, motivation, and business impact clearly. However, the test plan section is incomplete: the author notes that DB and integration tests were not completed locally due to Docker image pulls.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix_webhooks

Comment @coderabbitai help to get the list of available commands and usage tips.

@riderx riderx marked this pull request as ready for review March 27, 2026 22:25
@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq bot commented Mar 27, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing fix_webhooks (7acdddd) with main (a843519)

Open in CodSpeed

@socket-security
Copy link
Copy Markdown

socket-security bot commented Mar 27, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​supabase/​supabase-js@​2.93.3 ⏵ 2.100.174 -25100100100100

View full report

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/webhook-queue-processing.test.ts (1)

27-45: Retry transient fetch exceptions in fetchQueueSync.

Right now only non-202 responses retry; thrown network errors fail immediately and make this test flaky.

Suggested change
 async function fetchQueueSync(queueName: string, maxRetries = 4) {
   for (let attempt = 0; attempt < maxRetries; attempt++) {
-    const response = await fetch(`${BASE_URL_TRIGGER}/queue_consumer/sync`, {
-      method: 'POST',
-      headers: headersInternal,
-      body: JSON.stringify({ queue_name: queueName }),
-    })
-
-    if (response.status === 202) {
-      expect(await response.json()).toEqual({ status: 'ok' })
-      return
-    }
+    try {
+      const response = await fetch(`${BASE_URL_TRIGGER}/queue_consumer/sync`, {
+        method: 'POST',
+        headers: headersInternal,
+        body: JSON.stringify({ queue_name: queueName }),
+      })
+
+      if (response.status === 202) {
+        expect(await response.json()).toEqual({ status: 'ok' })
+        return
+      }
+    }
+    catch {
+      if (attempt === maxRetries - 1)
+        throw new Error(`queue_consumer/sync network failure for ${queueName}`)
+    }
 
     if (attempt < maxRetries - 1)
       await new Promise(resolve => setTimeout(resolve, 250 * (attempt + 1)))
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/webhook-queue-processing.test.ts` around lines 27 - 45, The
fetchQueueSync helper currently only retries on non-202 responses and will fail
immediately on thrown network errors; wrap the fetch call in a try/catch inside
the for-loop in fetchQueueSync, treat thrown exceptions like a non-202 attempt
(i.e., if attempt < maxRetries-1 await the same backoff and continue), and on
final failure rethrow a descriptive Error that includes the original exception
and the queueName so test logs show the underlying network error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/webhook-queue-processing.test.ts`:
- Around line 27-45: The fetchQueueSync helper currently only retries on non-202
responses and will fail immediately on thrown network errors; wrap the fetch
call in a try/catch inside the for-loop in fetchQueueSync, treat thrown
exceptions like a non-202 attempt (i.e., if attempt < maxRetries-1 await the
same backoff and continue), and on final failure rethrow a descriptive Error
that includes the original exception and the queueName so test logs show the
underlying network error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e315b39e-b804-49d7-8daf-e3eb4d9501c4

📥 Commits

Reviewing files that changed from the base of the PR and between 7bd5daf and db25e38.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • package.json
  • supabase/migrations/20260327220305_add_webhook_queues_to_cron_tasks.sql
  • supabase/tests/49_test_webhook_cron_registration.sql
  • tests/webhook-queue-processing.test.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a5b2db865

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant