You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioritize type safety, security, and small, reviewable diffs.
- Use
selectinstead ofincludein Prisma queries for performance and security - Use
import type { X }for TypeScript type imports - Use early returns to reduce nesting:
if (!booking) return null; - Use
ErrorWithCodefor errors in non-tRPC files (services, repositories, utilities); useTRPCErroronly in tRPC routers - Use conventional commits:
feat:,fix:,refactor: - Create PRs in draft mode by default
- Run
yarn type-check:ci --forcebefore concluding CI failures are unrelated to your changes - Import directly from source files, not barrel files (e.g.,
@calcom/ui/components/buttonnot@calcom/ui) - Add translations to
apps/web/public/static/locales/en/common.jsonfor all UI strings - Use
date-fnsor nativeDateinstead of Day.js when timezone awareness isn't needed - Put permission checks in
page.tsx, never inlayout.tsx - Use
ast-grepfor searching if available; otherwise userg(ripgrep), then fall back togrep - Use Biome for formatting and linting
- Never use
as any- use proper type-safe solutions instead - Never expose
credential.keyfield in API responses or queries - Never commit secrets or API keys
- Never modify
*.generated.tsfiles directly - they're created by app-store-cli - Never put business logic in repositories - that belongs in Services
- Never use barrel imports from index.ts files
- Never skip running type checks before pushing
- Never create large PRs (>500 lines or >10 files) - split them instead
# Type check - always run on changed files
yarn type-check:ci --force
# Lint and format single file
yarn biome check --write path/to/file.tsx
# Unit test specific file
yarn vitest run path/to/file.test.ts
# Unit test specific file + specific test
yarn vitest run path/to/file.test.ts --testNamePattern="specific test name"
# Integration test specific file
yarn test path/to/file.integration-test.ts -- --integrationTestsOnly
# Integration test specific file + specific test
yarn test path/to/file.integration-test.ts --testNamePattern="specific test name" -- --integrationTestsOnly
# E2E test specific file
PLAYWRIGHT_HEADLESS=1 yarn e2e path/to/file.e2e.ts
# E2E test specific file + specific test
PLAYWRIGHT_HEADLESS=1 yarn e2e path/to/file.e2e.ts --grep "specific test name"# Development
yarn dev # Start dev server
yarn dx # Dev with database setup
# Build & check
yarn build # Build all packages
yarn biome check --write . # Lint and format all
yarn type-check # Type check all
# Tests (use TZ=UTC for consistency)
TZ=UTC yarn test # All unit tests
yarn e2e # All E2E tests
# Database
yarn prisma generate # Regenerate types after schema changes
yarn workspace @calcom/prisma db-migrate # Run migrationsyarn biome check --write .
yarn type-check:ci --force- Run type check on changed files before committing
- Run relevant tests before pushing
- Use
selectin Prisma queries - Follow conventional commits for PR titles
- Run Biome before pushing
- Adding new dependencies
- Schema changes to
packages/prisma/schema.prisma - Changes affecting multiple packages
- Deleting files
- Running full build or E2E suites
- Commit secrets, API keys, or
.envfiles - Expose
credential.keyin any query - Use
as anytype casting - Force push or rebase shared branches
- Modify generated files directly
apps/web/ # Main Next.js application
packages/prisma/ # Database schema (schema.prisma) and migrations
packages/trpc/ # tRPC API layer (routers in server/routers/)
packages/ui/ # Shared UI components
packages/features/ # Feature-specific code
packages/app-store/ # Third-party integrations
packages/lib/ # Shared utilities
- Routes:
apps/web/app/(App Router) - Database schema:
packages/prisma/schema.prisma - tRPC routers:
packages/trpc/server/routers/ - Translations:
apps/web/public/static/locales/en/common.json - Workflow constants:
packages/features/ee/workflows/lib/constants.ts
- Framework: Next.js 13+ (App Router in some areas)
- Language: TypeScript (strict)
- Database: PostgreSQL with Prisma ORM
- API: tRPC for type-safe APIs
- Auth: NextAuth.js
- Styling: Tailwind CSS
- Testing: Vitest (unit), Playwright (E2E)
- i18n: next-i18next
// Good - Descriptive error with context
throw new Error(`Unable to create booking: User ${userId} has no available time slots for ${date}`);
// Bad - Generic error
throw new Error("Booking failed");For which error class to use (ErrorWithCode vs TRPCError) and concrete examples, see Error Types in knowledge-base.md.
// Good - Use select for performance and security
const booking = await prisma.booking.findFirst({
select: {
id: true,
title: true,
user: {
select: {
id: true,
name: true,
email: true,
}
}
}
});
// Bad - Include fetches all fields including sensitive ones
const booking = await prisma.booking.findFirst({
include: { user: true }
});// Good - Type imports and direct paths
import type { User } from "@prisma/client";
import { Button } from "@calcom/ui/components/button";
// Bad - Regular import for types, barrel imports
import { User } from "@prisma/client";
import { Button } from "@calcom/ui";- Title follows conventional commits:
feat(scope): description - Type check passes:
yarn type-check:ci --force - Lint passes:
yarn lint:fix - Relevant tests pass
- Diff is small and focused (<500 lines, <10 files)
- No secrets or API keys committed
- UI strings added to translation files
- Created as draft PR
- Ask a clarifying question before making large speculative changes
- Propose a short plan for complex tasks
- Open a draft PR with notes if unsure about approach
- Fix type errors before test failures - they're often the root cause
- Run
yarn prisma generateif you see missing enum/type errors
For detailed information, see the agents/ directory:
- agents/README.md - Architecture overview and patterns
- agents/commands.md - Complete command reference
- agents/knowledge-base.md - Domain knowledge and best practices
- agents/coding-standards.md - Coding standards with examples