|
1 | 1 | # Cal.com Development Guide for AI Agents |
2 | 2 |
|
3 | | -**📖 Complete documentation is in the [.agents/](.agents/) directory.** |
| 3 | +You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioritize type safety, security, and small, reviewable diffs. |
4 | 4 |
|
5 | | -## Quick Reference |
| 5 | +## Do |
6 | 6 |
|
7 | | -### Essential Commands |
| 7 | +- Use `select` instead of `include` in Prisma queries for performance and security |
| 8 | +- Use `import type { X }` for TypeScript type imports |
| 9 | +- Use early returns to reduce nesting: `if (!booking) return null;` |
| 10 | +- Use TRPCError with proper error codes for API errors |
| 11 | +- Use conventional commits: `feat:`, `fix:`, `refactor:` |
| 12 | +- Create PRs in draft mode by default |
| 13 | +- Run `yarn type-check:ci --force` before concluding CI failures are unrelated to your changes |
| 14 | +- Import directly from source files, not barrel files (e.g., `@calcom/ui/components/button` not `@calcom/ui`) |
| 15 | +- Add translations to `apps/web/public/static/locales/en/common.json` for all UI strings |
| 16 | +- Use `date-fns` or native `Date` instead of Day.js when timezone awareness isn't needed |
| 17 | +- Put permission checks in `page.tsx`, never in `layout.tsx` |
8 | 18 |
|
9 | | -- `yarn dev` - Start development server |
10 | | -- `yarn build` - Build all packages |
11 | | -- `yarn lint:fix` - Lint and fix code |
12 | | -- `yarn type-check` - TypeScript checking |
13 | | -- `yarn test <filename> -- --integrationTestsOnly` - Run integration tests |
14 | | -- `yarn e2e <filename> --grep "<testName>"` - Run specific E2E test |
| 19 | +## Don't |
15 | 20 |
|
16 | | -## Tool Preferences |
| 21 | +- Never use `as any` - use proper type-safe solutions instead |
| 22 | +- Never expose `credential.key` field in API responses or queries |
| 23 | +- Never commit secrets or API keys |
| 24 | +- Never modify `*.generated.ts` files directly - they're created by app-store-cli |
| 25 | +- Never put business logic in repositories - that belongs in Services |
| 26 | +- Never use barrel imports from index.ts files |
| 27 | +- Never skip running type checks before pushing |
| 28 | +- Never create large PRs (>500 lines or >10 files) - split them instead |
17 | 29 |
|
18 | | -### Search Tools Priority |
| 30 | +## Commands |
19 | 31 |
|
20 | | -Use tools in this order of preference: |
| 32 | +### File-scoped (preferred for speed) |
21 | 33 |
|
22 | | -1. **ast-grep** - For AST-based code searches (if available) |
23 | | -2. **rg (ripgrep)** - For fast text searches |
24 | | -3. **grep** - As fallback for text searches |
| 34 | +```bash |
| 35 | +# Type check - always run on changed files |
| 36 | +yarn type-check:ci --force |
25 | 37 |
|
26 | | -## 📚 Detailed Documentation |
| 38 | +# Lint single file |
| 39 | +yarn eslint --fix path/to/file.tsx |
27 | 40 |
|
28 | | -- **[.agents/README.md](.agents/README.md)** - Complete development guide |
29 | | -- **[.agents/commands.md](.agents/commands.md)** - All build, test & dev commands |
30 | | -- **[.agents/knowledge-base.md](.agents/knowledge-base.md)** - Knowledge base & best practices |
| 41 | +# Format single file |
| 42 | +yarn prettier --write path/to/file.tsx |
| 43 | + |
| 44 | +# Unit test specific file |
| 45 | +yarn vitest run path/to/file.test.ts |
| 46 | + |
| 47 | +# Integration test specific file |
| 48 | +yarn test path/to/file.integration-test.ts -- --integrationTestsOnly |
| 49 | + |
| 50 | +# E2E test specific file |
| 51 | +PLAYWRIGHT_HEADLESS=1 yarn e2e path/to/file.e2e.ts |
| 52 | +``` |
| 53 | + |
| 54 | +### Project-wide (use sparingly) |
| 55 | + |
| 56 | +```bash |
| 57 | +# Development |
| 58 | +yarn dev # Start dev server |
| 59 | +yarn dx # Dev with database setup |
| 60 | + |
| 61 | +# Build & check |
| 62 | +yarn build # Build all packages |
| 63 | +yarn lint:fix # Lint and fix all |
| 64 | +yarn type-check # Type check all |
| 65 | + |
| 66 | +# Tests (use TZ=UTC for consistency) |
| 67 | +TZ=UTC yarn test # All unit tests |
| 68 | +yarn e2e # All E2E tests |
| 69 | + |
| 70 | +# Database |
| 71 | +yarn prisma generate # Regenerate types after schema changes |
| 72 | +yarn workspace @calcom/prisma db-migrate # Run migrations |
| 73 | +``` |
| 74 | + |
| 75 | +## Boundaries |
| 76 | + |
| 77 | +### Always do |
| 78 | +- Run type check on changed files before committing |
| 79 | +- Run relevant tests before pushing |
| 80 | +- Use `select` in Prisma queries |
| 81 | +- Follow conventional commits for PR titles |
| 82 | + |
| 83 | +### Ask first |
| 84 | +- Adding new dependencies |
| 85 | +- Schema changes to `packages/prisma/schema.prisma` |
| 86 | +- Changes affecting multiple packages |
| 87 | +- Deleting files |
| 88 | +- Running full build or E2E suites |
| 89 | + |
| 90 | +### Never do |
| 91 | +- Commit secrets, API keys, or `.env` files |
| 92 | +- Expose `credential.key` in any query |
| 93 | +- Use `as any` type casting |
| 94 | +- Force push or rebase shared branches |
| 95 | +- Modify generated files directly |
| 96 | + |
| 97 | +## Project Structure |
| 98 | + |
| 99 | +``` |
| 100 | +apps/web/ # Main Next.js application |
| 101 | +packages/prisma/ # Database schema (schema.prisma) and migrations |
| 102 | +packages/trpc/ # tRPC API layer (routers in server/routers/) |
| 103 | +packages/ui/ # Shared UI components |
| 104 | +packages/features/ # Feature-specific code |
| 105 | +packages/app-store/ # Third-party integrations |
| 106 | +packages/lib/ # Shared utilities |
| 107 | +``` |
| 108 | + |
| 109 | +### Key files |
| 110 | +- Routes: `apps/web/app/` (App Router) |
| 111 | +- Database schema: `packages/prisma/schema.prisma` |
| 112 | +- tRPC routers: `packages/trpc/server/routers/` |
| 113 | +- Translations: `apps/web/public/static/locales/en/common.json` |
| 114 | +- Workflow constants: `packages/features/ee/workflows/lib/constants.ts` |
| 115 | + |
| 116 | +## Tech Stack |
| 117 | + |
| 118 | +- **Framework**: Next.js 13+ (App Router in some areas) |
| 119 | +- **Language**: TypeScript (strict) |
| 120 | +- **Database**: PostgreSQL with Prisma ORM |
| 121 | +- **API**: tRPC for type-safe APIs |
| 122 | +- **Auth**: NextAuth.js |
| 123 | +- **Styling**: Tailwind CSS |
| 124 | +- **Testing**: Vitest (unit), Playwright (E2E) |
| 125 | +- **i18n**: next-i18next |
| 126 | + |
| 127 | +## Code Examples |
| 128 | + |
| 129 | +### Good error handling |
| 130 | + |
| 131 | +```typescript |
| 132 | +// Good - Descriptive error with context |
| 133 | +throw new TRPCError({ |
| 134 | + code: "BAD_REQUEST", |
| 135 | + message: `Unable to create booking: User ${userId} has no available time slots for ${date}`, |
| 136 | +}); |
| 137 | + |
| 138 | +// Bad - Generic error |
| 139 | +throw new Error("Booking failed"); |
| 140 | +``` |
| 141 | + |
| 142 | +### Good Prisma query |
| 143 | + |
| 144 | +```typescript |
| 145 | +// Good - Use select for performance and security |
| 146 | +const booking = await prisma.booking.findFirst({ |
| 147 | + select: { |
| 148 | + id: true, |
| 149 | + title: true, |
| 150 | + user: { |
| 151 | + select: { |
| 152 | + id: true, |
| 153 | + name: true, |
| 154 | + email: true, |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | +}); |
| 159 | + |
| 160 | +// Bad - Include fetches all fields including sensitive ones |
| 161 | +const booking = await prisma.booking.findFirst({ |
| 162 | + include: { user: true } |
| 163 | +}); |
| 164 | +``` |
| 165 | + |
| 166 | +### Good imports |
| 167 | + |
| 168 | +```typescript |
| 169 | +// Good - Type imports and direct paths |
| 170 | +import type { User } from "@prisma/client"; |
| 171 | +import { Button } from "@calcom/ui/components/button"; |
| 172 | + |
| 173 | +// Bad - Regular import for types, barrel imports |
| 174 | +import { User } from "@prisma/client"; |
| 175 | +import { Button } from "@calcom/ui"; |
| 176 | +``` |
| 177 | + |
| 178 | +## PR Checklist |
| 179 | + |
| 180 | +- [ ] Title follows conventional commits: `feat(scope): description` |
| 181 | +- [ ] Type check passes: `yarn type-check:ci --force` |
| 182 | +- [ ] Lint passes: `yarn lint:fix` |
| 183 | +- [ ] Relevant tests pass |
| 184 | +- [ ] Diff is small and focused (<500 lines, <10 files) |
| 185 | +- [ ] No secrets or API keys committed |
| 186 | +- [ ] UI strings added to translation files |
| 187 | +- [ ] Created as draft PR |
| 188 | + |
| 189 | +## When Stuck |
| 190 | + |
| 191 | +- Ask a clarifying question before making large speculative changes |
| 192 | +- Propose a short plan for complex tasks |
| 193 | +- Open a draft PR with notes if unsure about approach |
| 194 | +- Fix type errors before test failures - they're often the root cause |
| 195 | +- Run `yarn prisma generate` if you see missing enum/type errors |
| 196 | + |
| 197 | +## Extended Documentation |
| 198 | + |
| 199 | +For detailed information, see the `agents/` directory: |
| 200 | + |
| 201 | +- **[agents/README.md](agents/README.md)** - Architecture overview and patterns |
| 202 | +- **[agents/commands.md](agents/commands.md)** - Complete command reference |
| 203 | +- **[agents/knowledge-base.md](agents/knowledge-base.md)** - Domain knowledge and best practices |
| 204 | +- **[agents/coding-standards.md](agents/coding-standards.md)** - Coding standards with examples |
0 commit comments