From 0f916af5c6d445a383f0245506256c8ded4d22f8 Mon Sep 17 00:00:00 2001 From: Pablo Pettinari Date: Wed, 29 Apr 2026 13:34:29 +0200 Subject: [PATCH 1/2] docs(data-layer): add fetcher isolation rule --- .claude/skills/data-layer/SKILL.md | 8 ++++++++ src/data-layer/docs.md | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/.claude/skills/data-layer/SKILL.md b/.claude/skills/data-layer/SKILL.md index a9996b2a9ab..c67caa596f7 100644 --- a/.claude/skills/data-layer/SKILL.md +++ b/.claude/skills/data-layer/SKILL.md @@ -160,6 +160,14 @@ return { ...event, logoImage: logoUrl ?? "" } Always handle `null` returns (upload failures) with fallback/empty string. +### 5. Keep fetchers isolated from the app + +Fetchers run on Trigger.dev — a separate runtime, deployment, and bundle from the Next.js app. They cannot assume the app's filesystem, environment, or modules are available. + +Any import or runtime dependency reaching outside `src/data-layer/` is a warning sign. Allowed: types (`@/lib/types`, `@/lib/interfaces`), pure constants (`@/lib/constants`), and pure utility functions with no app-runtime dependencies. Not allowed: anything that reads `process.cwd()`, anything from `app/`, anything from `src/components/`, or `src/lib/data/` (which wraps the data layer and would create a cycle). + +If a fetcher needs data that lives in the app — content files, frontmatter, etc. — fetch it over the network via the GitHub API and treat the repo as an external system. See `fetchGitHubContributors.ts` for the pattern. Don't work around this with `additionalFiles` in `trigger.config.ts`; bundling app files into the data-layer deployment re-creates the coupling. + ## Adding a New Data Source 1. **Create fetcher** in `src/data-layer/fetchers/fetchNewData.ts`: diff --git a/src/data-layer/docs.md b/src/data-layer/docs.md index e3fba6347ce..afbecf85c17 100644 --- a/src/data-layer/docs.md +++ b/src/data-layer/docs.md @@ -51,6 +51,10 @@ export const getEventsData = createCachedGetter( Direct `@/data-layer` imports work but have no caching. +### 4. Keep fetchers isolated from the app + +Fetchers run on Trigger.dev — a separate runtime from the Next.js app — and cannot assume the app's filesystem or modules are available. Any import or runtime dependency reaching outside `src/data-layer/` is a warning sign; if a fetcher needs app data, fetch it via the GitHub API and treat the repo as an external system. See `fetchGitHubContributors.ts` for the pattern, and the data-layer skill (Rule 5) for the full allow/deny list. + ## Adding a New Data Source 1. **Create fetcher** in `src/data-layer/fetchers/fetchNewData.ts` From f7f367b2bdd976a635c61eae4ab94827a6c71f1a Mon Sep 17 00:00:00 2001 From: Pablo Pettinari Date: Thu, 30 Apr 2026 13:25:39 +0200 Subject: [PATCH 2/2] Update .claude/skills/data-layer/SKILL.md Co-authored-by: wackerow <54227730+wackerow@users.noreply.github.com> --- .claude/skills/data-layer/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/data-layer/SKILL.md b/.claude/skills/data-layer/SKILL.md index c67caa596f7..8b889330d0d 100644 --- a/.claude/skills/data-layer/SKILL.md +++ b/.claude/skills/data-layer/SKILL.md @@ -164,7 +164,7 @@ Always handle `null` returns (upload failures) with fallback/empty string. Fetchers run on Trigger.dev — a separate runtime, deployment, and bundle from the Next.js app. They cannot assume the app's filesystem, environment, or modules are available. -Any import or runtime dependency reaching outside `src/data-layer/` is a warning sign. Allowed: types (`@/lib/types`, `@/lib/interfaces`), pure constants (`@/lib/constants`), and pure utility functions with no app-runtime dependencies. Not allowed: anything that reads `process.cwd()`, anything from `app/`, anything from `src/components/`, or `src/lib/data/` (which wraps the data layer and would create a cycle). +Any import or runtime dependency reaching outside `src/data-layer/` is a warning sign. Allowed: types (`@/lib/types`, `@/lib/interfaces`), pure constants (`@/lib/constants`), and pure utility functions with no app-runtime dependencies. Not allowed: anything that reads `process.cwd()`, anything from `app/` or `public/`, anything from `src/components/`, or `src/lib/data/` (which wraps the data layer and would create a cycle). If a fetcher needs data that lives in the app — content files, frontmatter, etc. — fetch it over the network via the GitHub API and treat the repo as an external system. See `fetchGitHubContributors.ts` for the pattern. Don't work around this with `additionalFiles` in `trigger.config.ts`; bundling app files into the data-layer deployment re-creates the coupling.