From 890c835ce404b1d9f84389638fcef6eb71e904bf Mon Sep 17 00:00:00 2001 From: Pablo Pettinari Date: Thu, 8 Jan 2026 11:11:15 +0100 Subject: [PATCH 1/2] Use Netlify's auto-provided SITE_ID instead of custom env var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace NETLIFY_BLOBS_SITE_ID with SITE_ID which is automatically provided by Netlify during builds, reducing required configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/data-layer/docs.md | 6 +++--- src/data-layer/storage/netlifyBlobsStorage.ts | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/data-layer/docs.md b/src/data-layer/docs.md index 907b4a8b5c8..66334f35322 100644 --- a/src/data-layer/docs.md +++ b/src/data-layer/docs.md @@ -129,7 +129,7 @@ export interface Storage { - `setData(taskId, data)` - Store data with automatic metadata **Storage Configuration:** -- Requires `NETLIFY_BLOBS_SITE_ID` and `NETLIFY_BLOBS_TOKEN` environment variables +- Requires `SITE_ID` (auto-provided by Netlify) and `NETLIFY_BLOBS_TOKEN` environment variables - Throws error if credentials are missing (no silent fallback) - Use `USE_MOCK_DATA=true` for local development @@ -276,7 +276,7 @@ See `tests/unit/data-layer/getters.spec.ts` for test examples. ## Environment Variables **Required for production:** -- `NETLIFY_BLOBS_SITE_ID` - Netlify Blobs site ID (required, throws error if missing) +- `SITE_ID` - Netlify site ID (auto-provided by Netlify during builds) - `NETLIFY_BLOBS_TOKEN` - Netlify Blobs access token (required, throws error if missing) - `TRIGGER_PROJECT_ID` - Trigger.dev project ID @@ -319,7 +319,7 @@ This pulls data from Netlify Blobs storage and saves it as JSON files for local - Regenerate mocks if needed: `npm run generate-mocks` (if script exists) ### Netlify Blobs errors -- Verify `NETLIFY_BLOBS_SITE_ID` and `NETLIFY_BLOBS_TOKEN` are set +- Verify `SITE_ID` (auto-provided by Netlify) and `NETLIFY_BLOBS_TOKEN` are set - Check error message for specific configuration issues - Storage will throw clear error if credentials are missing diff --git a/src/data-layer/storage/netlifyBlobsStorage.ts b/src/data-layer/storage/netlifyBlobsStorage.ts index 6a391ca5bb7..dc4642abf20 100644 --- a/src/data-layer/storage/netlifyBlobsStorage.ts +++ b/src/data-layer/storage/netlifyBlobsStorage.ts @@ -7,13 +7,12 @@ let store: ReturnType | null = null function getBlobStore() { if (store) return store - const siteID = process.env.NETLIFY_BLOBS_SITE_ID + // SITE_ID is automatically provided by Netlify during builds + const siteID = process.env.SITE_ID const token = process.env.NETLIFY_BLOBS_TOKEN if (!siteID || !token) { - throw new Error( - "Missing NETLIFY_BLOBS_SITE_ID or NETLIFY_BLOBS_TOKEN env vars" - ) + throw new Error("Missing SITE_ID or NETLIFY_BLOBS_TOKEN env vars") } store = getStore({ From b0d63f3c499821c95dd14de0845ad9b8fcf0f80b Mon Sep 17 00:00:00 2001 From: Pablo Pettinari Date: Thu, 8 Jan 2026 11:23:44 +0100 Subject: [PATCH 2/2] Import old trigger.dev revalidation tasks for backward compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copies legacy revalidation tasks from trigger-revalidation-tasks branch to src/data-layer/trigger/old-tasks/ to maintain backward compatibility while the new task structure is in place. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/data-layer/trigger/old-tasks/index.ts | 8 +++ .../revalidate-10-year-anniversary.ts | 12 +++++ .../trigger/old-tasks/revalidate-apps.ts | 51 +++++++++++++++++++ .../old-tasks/revalidate-find-wallet-page.ts | 12 +++++ .../trigger/old-tasks/revalidate-home-page.ts | 12 +++++ .../revalidate-layer-2-networks-page.ts | 12 +++++ .../old-tasks/revalidate-layer-2-page.ts | 12 +++++ .../old-tasks/revalidate-stablecoins-page.ts | 12 +++++ .../old-tasks/revalidate-staking-page.ts | 12 +++++ src/data-layer/trigger/old-tasks/utils.ts | 39 ++++++++++++++ trigger.config.ts | 7 ++- 11 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 src/data-layer/trigger/old-tasks/index.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-10-year-anniversary.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-apps.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-find-wallet-page.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-home-page.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-layer-2-networks-page.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-layer-2-page.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-stablecoins-page.ts create mode 100644 src/data-layer/trigger/old-tasks/revalidate-staking-page.ts create mode 100644 src/data-layer/trigger/old-tasks/utils.ts diff --git a/src/data-layer/trigger/old-tasks/index.ts b/src/data-layer/trigger/old-tasks/index.ts new file mode 100644 index 00000000000..c078bbc0905 --- /dev/null +++ b/src/data-layer/trigger/old-tasks/index.ts @@ -0,0 +1,8 @@ +export { revalidate10YearAnniversary } from "./revalidate-10-year-anniversary" +export { revalidateAppsPages } from "./revalidate-apps" +export { revalidateFindWalletPage } from "./revalidate-find-wallet-page" +export { revalidateHomePage } from "./revalidate-home-page" +export { revalidateLayer2NetworksPage } from "./revalidate-layer-2-networks-page" +export { revalidateLayer2Page } from "./revalidate-layer-2-page" +export { revalidateStablecoinsPage } from "./revalidate-stablecoins-page" +export { revalidateStakingPage } from "./revalidate-staking-page" diff --git a/src/data-layer/trigger/old-tasks/revalidate-10-year-anniversary.ts b/src/data-layer/trigger/old-tasks/revalidate-10-year-anniversary.ts new file mode 100644 index 00000000000..e0de5de23ea --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-10-year-anniversary.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidate10YearAnniversary = schedules.task({ + id: "revalidate-10-year-anniversary", + // every day + cron: "0 0 * * *", + run: async () => { + await revalidatePaths(["/10-year-anniversary/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-apps.ts b/src/data-layer/trigger/old-tasks/revalidate-apps.ts new file mode 100644 index 00000000000..399e9e02d79 --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-apps.ts @@ -0,0 +1,51 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { slugify } from "@/lib/utils/url" + +import { revalidatePaths } from "./utils" + +import { fetchApps } from "@/lib/api/fetchApps" + +const categoriesSlugs = [ + "defi", + "collectibles", + "social", + "gaming", + "bridge", + "productivity", + "privacy", + "dao", +] + +export const revalidateAppsPages = schedules.task({ + id: "revalidate-apps-pages", + // every day + cron: "0 0 * * *", + run: async () => { + // Generate dynamic paths + const paths = ["/apps", "/apps/"] + + // Add category paths + categoriesSlugs.forEach((category) => { + paths.push(`/apps/categories/${category}`) + }) + + // Fetch apps data and add individual app paths + try { + const appsData = await fetchApps() + + Object.values(appsData) + .flat() + .forEach((app) => { + const appSlug = slugify(app.name) + paths.push(`/apps/${appSlug}`) + }) + } catch (error) { + console.error("Failed to fetch apps data for revalidation:", error) + // Continue with category paths even if app fetching fails + } + + console.log(`Revalidating ${paths.length} paths:`, paths) + await revalidatePaths(paths) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-find-wallet-page.ts b/src/data-layer/trigger/old-tasks/revalidate-find-wallet-page.ts new file mode 100644 index 00000000000..12607d4ae7e --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-find-wallet-page.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidateFindWalletPage = schedules.task({ + id: "revalidate-find-wallet-page", + // every day + cron: "0 0 * * *", + run: async () => { + await revalidatePaths(["/wallets/find-wallet/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-home-page.ts b/src/data-layer/trigger/old-tasks/revalidate-home-page.ts new file mode 100644 index 00000000000..6a0555469c8 --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-home-page.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidateHomePage = schedules.task({ + id: "revalidate-home-page", + // every day + cron: "0 0 * * *", + run: async () => { + await revalidatePaths(["/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-layer-2-networks-page.ts b/src/data-layer/trigger/old-tasks/revalidate-layer-2-networks-page.ts new file mode 100644 index 00000000000..5e169e1df05 --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-layer-2-networks-page.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidateLayer2NetworksPage = schedules.task({ + id: "revalidate-layer-2-networks-page", + // every day + cron: "0 0 * * *", + run: async () => { + await revalidatePaths(["/layer-2/networks/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-layer-2-page.ts b/src/data-layer/trigger/old-tasks/revalidate-layer-2-page.ts new file mode 100644 index 00000000000..11edc5f578b --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-layer-2-page.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidateLayer2Page = schedules.task({ + id: "revalidate-layer-2-page", + // every day + cron: "0 0 * * *", + run: async () => { + await revalidatePaths(["/layer-2/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-stablecoins-page.ts b/src/data-layer/trigger/old-tasks/revalidate-stablecoins-page.ts new file mode 100644 index 00000000000..4af5d9b0e70 --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-stablecoins-page.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidateStablecoinsPage = schedules.task({ + id: "revalidate-stablecoins-page", + // once a week + cron: "0 0 * * 1", + run: async () => { + await revalidatePaths(["/stablecoins/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/revalidate-staking-page.ts b/src/data-layer/trigger/old-tasks/revalidate-staking-page.ts new file mode 100644 index 00000000000..baa185dfd6f --- /dev/null +++ b/src/data-layer/trigger/old-tasks/revalidate-staking-page.ts @@ -0,0 +1,12 @@ +import { schedules } from "@trigger.dev/sdk/v3" + +import { revalidatePaths } from "./utils" + +export const revalidateStakingPage = schedules.task({ + id: "revalidate-staking-page", + // every day + cron: "0 0 * * *", + run: async () => { + await revalidatePaths(["/staking/"]) + }, +}) diff --git a/src/data-layer/trigger/old-tasks/utils.ts b/src/data-layer/trigger/old-tasks/utils.ts new file mode 100644 index 00000000000..7cd694bf87b --- /dev/null +++ b/src/data-layer/trigger/old-tasks/utils.ts @@ -0,0 +1,39 @@ +import { logger } from "@trigger.dev/sdk/v3" + +export const revalidatePaths = async (paths: string[]) => { + for (const path of paths) { + logger.log(`Revalidating ${path}`) + + const url = new URL("https://ethereum.org/api/revalidate/") + url.searchParams.set("path", path) + url.searchParams.set("secret", process.env.REVALIDATE_SECRET ?? "") + + const res = await fetch(url) + + if (!res.ok) { + // 502 "Bad Gateway" error is returned when the on-demand builder (lambda function) + // hits the timeout limit (30s) + // https://docs.netlify.com/configure-builds/on-demand-builders/#limits + if (res.status === 502) { + logger.warn("On-demand builder timeout", { + statusText: res.statusText, + status: res.status, + }) + + continue + } + + const message = await res.text() + + logger.error("Failed to revalidate", { + statusText: res.statusText, + status: res.status, + message, + }) + + throw new Error("Failed to revalidate") + } + + logger.log(`Finished revalidating ${path}`) + } +} diff --git a/trigger.config.ts b/trigger.config.ts index d3f50fff72a..06550145d50 100644 --- a/trigger.config.ts +++ b/trigger.config.ts @@ -22,8 +22,11 @@ export default defineConfig({ randomize: true, }, }, - // Directory containing Trigger.dev task definitions - dirs: ["./src/data-layer/trigger/tasks"], + // Directories containing Trigger.dev task definitions + dirs: [ + "./src/data-layer/trigger/tasks", + "./src/data-layer/trigger/old-tasks", + ], // Initialize Sentry for error tracking in Trigger.dev tasks // Uses the same Sentry configuration as the Next.js app // Note: Trigger.dev already initializes OpenTelemetry, so we skip Sentry's OpenTelemetry setup