Skip to content

fix(gateway): resolve download_event_id timing bug#592

Merged
FredericoAndrade merged 1 commit into
mainfrom
fix/cc/download-event-id-timing
Apr 19, 2026
Merged

fix(gateway): resolve download_event_id timing bug#592
FredericoAndrade merged 1 commit into
mainfrom
fix/cc/download-event-id-timing

Conversation

@FredericoAndrade
Copy link
Copy Markdown
Contributor

Problem

download_event_id was always null in intake webhook payloads, causing Make.com's Airtable search formula to evaluate as {WP Event ID} = (empty string) and fail with a 422.

Root cause: The JS submitted intake first, then redirected the browser to the download token URL. The redirect event was logged server-side only after the browser navigation — after intake had already been enqueued. find_redirect_id() always returned null because the redirect row didn't exist yet.

Additionally, WebhookDispatcher had no ORDER BY, so intake could be sent to Make.com before the download webhook even if they were enqueued at the same time.

Fixes

JS sequencing (gateway-modal.js)

  • handleIntakeSubmit() now fetches the download URL via ?format=json first
  • The server logs the redirect event and returns {url, event_id}
  • JS submits intake with download_event_id: event_id, then redirects to file URL
  • External downloads skip the JSON fetch (no token to redeem)

PHP: download event_id in JSON response (class-download-controller.php)

  • Added last_event_id property set as a side effect of get_file_url()
  • handle() includes event_id in the ?format=json response
  • No change to resolve() signature or existing tests

PHP: intake accepts event_id from caller (class-intake-controller.php)

  • submit() now accepts ?int $download_event_id = null (default keeps tests passing)
  • Replaces the always-null DownloadEventRepository::find_redirect_id() DB lookup
  • JS passes the reliable event_id obtained from the download fetch

Webhook ordering (class-webhook-dispatcher.php)

  • Added ORDER BY id ASC to dispatch_pending() query
  • Download webhook (lower ID, enqueued first) always delivered to Make.com before intake

Make.com: no scenario changes needed

The intake webhook now reliably carries download_event_id, so the existing M24 search formula {WP Event ID} = {{1.download_event_id}} will work correctly.

Test plan

  • All 202 PHPUnit tests pass (composer test)
  • PHPCS clean (composer lint)
  • Deploy to production (rsync + dispatch_pending trigger)
  • Full end-to-end: download a gated resource → verify download_event_id is non-null in intake webhook payload → verify Make.com updates Downloads record correctly

🤖 Generated with Claude Code

…fore intake

JS now fetches the download URL via ?format=json before submitting intake,
so the redirect event is logged server-side before intake is enqueued.
The PHP download endpoint returns the event_id in its JSON response, which
the JS passes to the intake POST as download_event_id.

- DownloadController: add last_event_id property; expose event_id in JSON response
- IntakeController: accept download_event_id from request instead of DB lookup;
  removes the always-null find_redirect_id() call
- WebhookDispatcher: add ORDER BY id ASC so download webhook is always
  delivered to Make.com before intake (they share the same next_attempt_at)
- gateway-modal.js: handleIntakeSubmit() now fetches download URL first,
  then posts intake with event_id, then redirects — fixes the ordering
- Bump version to 0.1.13 to bust JS cache

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@FredericoAndrade FredericoAndrade merged commit 7fc9d4c into main Apr 19, 2026
6 checks passed
@FredericoAndrade FredericoAndrade deleted the fix/cc/download-event-id-timing branch April 19, 2026 19:34
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