Skip to content

feat: add HubSpot certificate webhooks for blockchain and avalanche L1 academies#3815

Open
navillanueva wants to merge 11 commits intomasterfrom
hubspot-academy-certificate-webhooks
Open

feat: add HubSpot certificate webhooks for blockchain and avalanche L1 academies#3815
navillanueva wants to merge 11 commits intomasterfrom
hubspot-academy-certificate-webhooks

Conversation

@navillanueva
Copy link
Contributor

@navillanueva navillanueva commented Feb 10, 2026

Summary

  • Move hardcoded HubSpot webhook URLs to per-course env vars for all three academies (entrepreneur,
    blockchain, avalanche L1)
  • Fix badge assignment race condition — wrap upsert in prisma.$transaction() with P2002 safety net
  • Add fetchWithRetry() for CDN template resilience (3 retries, exponential backoff on 5xx)
  • Make HubSpot webhook fire-and-forget — PDF delivery no longer blocked by slow/failed webhooks
  • Guard duplicate awardBadge() calls in BadgeNotification.tsx via useRef
  • Validate response.ok before parsing badge API response

Env Vars

Per-course webhooks (all new, set in Vercel):

Env Var Course
HUBSPOT_WEBHOOK_AVALANCHE_FUNDAMENTALS avalanche-fundamentals
HUBSPOT_WEBHOOK_PERMISSIONED_L1S permissioned-l1s
HUBSPOT_WEBHOOK_L1_NATIVE_TOKENOMICS l1-native-tokenomics
HUBSPOT_WEBHOOK_PERMISSIONLESS_L1S permissionless-l1s
HUBSPOT_WEBHOOK_INTERCHAIN_MESSAGING interchain-messaging
HUBSPOT_WEBHOOK_ERC20_BRIDGE erc20-bridge
HUBSPOT_WEBHOOK_NATIVE_TOKEN_BRIDGE native-token-bridge
HUBSPOT_WEBHOOK_CUSTOMIZING_EVM customizing-evm
HUBSPOT_WEBHOOK_ACCESS_RESTRICTION_FUNDAMENTALS access-restriction-fundamentals
HUBSPOT_WEBHOOK_ACCESS_RESTRICTION_ADVANCED access-restriction-advanced
HUBSPOT_WEBHOOK_BLOCKCHAIN_FUNDAMENTALS blockchain-fundamentals
HUBSPOT_WEBHOOK_SOLIDITY_FOUNDRY solidity-foundry
HUBSPOT_WEBHOOK_NFT_DEPLOYMENT nft-deployment
HUBSPOT_WEBHOOK_ENCRYPTED_ERC encrypted-erc
HUBSPOT_WEBHOOK_X402_PAYMENT_INFRASTRUCTURE x402-payment-infrastructure

Graduation webhooks (new):

Env Var Academy
HUBSPOT_WEBHOOK_AVALANCHE_L1_GRADUATION avalanche-l1
HUBSPOT_WEBHOOK_BLOCKCHAIN_GRADUATION blockchain

Entrepreneur (unchanged):

Env Var Fallback
ENTREPRENEUR_ACADEMY_HUBSPOT_WEBHOOK CODEBASE_CERTIFICATE_HUBSPOT_WEBHOOK

Missing env vars are handled gracefully — certificate generation is never blocked.

Test Plan

To run the integration tests you need a session cookie and user ID from a logged-in session.

1. Get your User ID

Open DevTools → Console and run:

fetch('/api/auth/session').then(r => r.json()).then(d => console.log(d.user.id))
Copy the id value  this is your USER_ID.

2. Get your session cookie

Go to DevTools  Application  Cookies  select the app's origin.

- Localhost: copy the value of next-auth.session-token
- Vercel preview: copy the value of __Secure-next-auth.session-token

3. Run the tests

Against localhost:
SESSION_COOKIE="next-auth.session-token=<value>" \
USER_ID="<id>" \
bash scripts/test-certificate-flow.sh http://localhost:3001

Against a Vercel preview deployment:

Vercel previews are protected by SSO, so you also need the _vercel_jwt cookie (from DevTools 
Application  Cookies) and the __Secure- prefixed session token:
SESSION_COOKIE="_vercel_jwt=<jwt-value>; __Secure-next-auth.session-token=<value>" \
USER_ID="<id>" \
bash scripts/test-certificate-flow.sh https://<preview-url>.vercel.app

Expected output

1. Badge assignment (single call)         PASS (200)
2. Badge idempotency (duplicate call)     PASS (200)
3. Concurrent badge assignments           PASS (200, 200)
4. Certificate PDF generation             PASS (200)
5. Invalid course ID                      PASS (404)
6. Unauthenticated access                 PASS (401)

Server logs confirm webhook fires in background after PDF response:
POST /api/generate-certificate 200 in 3.8s
HubSpot webhook triggered [course: Avalanche Fundamentals]

TEST RESULTS

image image

@vercel
Copy link

vercel bot commented Feb 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
builder-hub Ready Ready Preview, Comment Feb 25, 2026 3:13pm

Request Review

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