Repository navigation
Establish webhooks journal example - #1
Conversation
Express + TypeScript + Prisma backend with React frontend for demonstrating HubSpot Webhooks Journal API integration patterns. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
76f5a50 to
3dafec8
Compare
|
Hi @zprobs, @zman81988 asked me to take a look at this. Overall it looks good but there are a few things I wanted to flag. I can't see anywhere that AppError from |
Addresses PR review feedback and adds dynamic per-portal provisioning driven by APP_LIFECYCLE events. Review feedback: - Wire the previously-unused AppError through a centralized errorHandler plus an asyncHandler wrapper; routes throw AppError for validation and let service/axios errors propagate (removes per-route try/catch). - Subscription cleanup: delete a single subscription or all of a portal's subscriptions (routes + service fns + UI trash/Delete-All actions), plus an Add Subscription button and empty state so the banner is recoverable. - Exponential backoff honoring Retry-After for journal fetches (src/utils/retry.ts) instead of waiting for the next poll on 429. App-lifecycle events: - Create app-global APP_LIFECYCLE_EVENT subscriptions (install + uninstall) on startup and poll from boot so they are consumed. - Process appLifecycleEvent entries: on install, register the portal and dynamically create its default contact subscription; on uninstall, drop the portal (subscriptions are cleaned up server-side). - Portal registry table backs the dropdown; the UI polls /api/portals and diffs to toast new installs and drop uninstalled portals. Lifecycle subs are hidden from the UI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks @zaradford, I pushed fixes for those suggestions and also added some listening for app installs and uninstalls since that is a useful pattern to document. One thing to note before we can merge, is that we will need to wait for the 2027.03-beta API release to be able to use the bulk export endpoint and some other API improvements. Once that goes live, we can update this example and merge it in. |
The bulk snapshot endpoint (crm-bulk) only exists in the 2027-03-beta
date-based version, so the example now targets that version for every
journal, subscription and snapshot call, with the version in a single
constant so moving to 2027-03 GA is a one-line change.
Behavior changes the new version requires or exposed while testing:
- crm-bulk takes installPortalId and returns the status id as `id`.
- batch/{offset}/next returns 404 for an expired offset instead of an
empty 200, so the poller now resets its cursor rather than stalling.
- First-run cursor init starts from the earliest entry; starting from
latest skipped everything already in the journal.
- numErrors/errors are omitted when a batch has no errors, which made
every idle poll log "Fetched 0 journal entries".
Summary