From fe4017f30246e4255fa21c9d9d4b8a0c0f118e86 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 23 Dec 2025 20:38:09 +0100 Subject: [PATCH] docs: clarify tRPC architecture - packages/features vs apps/web/modules (#26155) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> --- agents/knowledge-base.md | 50 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/agents/knowledge-base.md b/agents/knowledge-base.md index ed94725bdd..af6abfc2a2 100644 --- a/agents/knowledge-base.md +++ b/agents/knowledge-base.md @@ -255,7 +255,55 @@ import { TRPCError } from "@trpc/server"; ### packages/features Import Restrictions -Files in `packages/features/**` should NOT import from `trpc`. This keeps the features package decoupled from the tRPC layer, making the code more reusable and testable. Use `ErrorWithCode` for error handling in these files, and let the tRPC middleware handle the conversion. +Files in `packages/features/**` should NOT import from `@calcom/trpc`. This keeps the features package decoupled from the tRPC layer, making the code more reusable and testable. Use `ErrorWithCode` for error handling in these files, and let the tRPC middleware handle the conversion. + +**Architecture: packages/features vs apps/web/modules** + +The `packages/features` package should contain only framework-agnostic code: +- Repositories (data access layer) +- Services (business logic) +- Core utilities and helpers +- Types and interfaces + +Web-specific code, particularly anything that uses tRPC, should live in `apps/web/modules/...`. This includes: +- React hooks that use tRPC queries/mutations +- tRPC-specific utilities +- Web-only UI components that depend on tRPC + +**Example:** + +If you have a feature called `feature-opt-in`: + +``` +packages/features/feature-opt-in/ +├── repository/ +│ └── FeatureOptInRepository.ts # Data access - OK here +├── service/ +│ └── FeatureOptInService.ts # Business logic - OK here +└── types.ts # Types - OK here + +apps/web/modules/feature-opt-in/ +└── hooks/ + └── useFeatureOptIn.ts # tRPC hook - MUST be here, not in packages/features +``` + +```typescript +// ❌ Bad - tRPC hook in packages/features +// packages/features/feature-opt-in/hooks/useFeatureOptIn.ts +import { trpc } from "@calcom/trpc/react"; +export function useFeatureOptIn() { + return trpc.viewer.featureOptIn.useQuery(); +} + +// ✅ Good - tRPC hook in apps/web/modules +// apps/web/modules/feature-opt-in/hooks/useFeatureOptIn.ts +import { trpc } from "@calcom/trpc/react"; +export function useFeatureOptIn() { + return trpc.viewer.featureOptIn.useQuery(); +} +``` + +This separation ensures that `packages/features` remains portable and can be used by other apps (like `apps/api/v2`) without pulling in web-specific dependencies like tRPC React hooks. ## Basic Performance Guidelines