Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/data-layer/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export interface Storage {
- `setData<T>(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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
7 changes: 3 additions & 4 deletions src/data-layer/storage/netlifyBlobsStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ let store: ReturnType<typeof getStore> | 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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🔥

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({
Expand Down
8 changes: 8 additions & 0 deletions src/data-layer/trigger/old-tasks/index.ts
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
@@ -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/"])
},
})
51 changes: 51 additions & 0 deletions src/data-layer/trigger/old-tasks/revalidate-apps.ts
Original file line number Diff line number Diff line change
@@ -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)
},
})
12 changes: 12 additions & 0 deletions src/data-layer/trigger/old-tasks/revalidate-find-wallet-page.ts
Original file line number Diff line number Diff line change
@@ -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/"])
},
})
12 changes: 12 additions & 0 deletions src/data-layer/trigger/old-tasks/revalidate-home-page.ts
Original file line number Diff line number Diff line change
@@ -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(["/"])
},
})
Original file line number Diff line number Diff line change
@@ -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/"])
},
})
12 changes: 12 additions & 0 deletions src/data-layer/trigger/old-tasks/revalidate-layer-2-page.ts
Original file line number Diff line number Diff line change
@@ -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/"])
},
})
12 changes: 12 additions & 0 deletions src/data-layer/trigger/old-tasks/revalidate-stablecoins-page.ts
Original file line number Diff line number Diff line change
@@ -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/"])
},
})
12 changes: 12 additions & 0 deletions src/data-layer/trigger/old-tasks/revalidate-staking-page.ts
Original file line number Diff line number Diff line change
@@ -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/"])
},
})
39 changes: 39 additions & 0 deletions src/data-layer/trigger/old-tasks/utils.ts
Original file line number Diff line number Diff line change
@@ -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}`)
}
}
7 changes: 5 additions & 2 deletions trigger.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down