diff --git a/AGENTS.md b/AGENTS.md index 22c747352a..1b4065f274 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,30 +1,204 @@ # Cal.com Development Guide for AI Agents -**📖 Complete documentation is in the [.agents/](.agents/) directory.** +You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioritize type safety, security, and small, reviewable diffs. -## Quick Reference +## Do -### Essential Commands +- Use `select` instead of `include` in 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 TRPCError with proper error codes for API errors +- Use conventional commits: `feat:`, `fix:`, `refactor:` +- Create PRs in draft mode by default +- Run `yarn type-check:ci --force` before concluding CI failures are unrelated to your changes +- Import directly from source files, not barrel files (e.g., `@calcom/ui/components/button` not `@calcom/ui`) +- Add translations to `apps/web/public/static/locales/en/common.json` for all UI strings +- Use `date-fns` or native `Date` instead of Day.js when timezone awareness isn't needed +- Put permission checks in `page.tsx`, never in `layout.tsx` -- `yarn dev` - Start development server -- `yarn build` - Build all packages -- `yarn lint:fix` - Lint and fix code -- `yarn type-check` - TypeScript checking -- `yarn test -- --integrationTestsOnly` - Run integration tests -- `yarn e2e --grep ""` - Run specific E2E test +## Don't -## Tool Preferences +- Never use `as any` - use proper type-safe solutions instead +- Never expose `credential.key` field in API responses or queries +- Never commit secrets or API keys +- Never modify `*.generated.ts` files 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 -### Search Tools Priority +## Commands -Use tools in this order of preference: +### File-scoped (preferred for speed) -1. **ast-grep** - For AST-based code searches (if available) -2. **rg (ripgrep)** - For fast text searches -3. **grep** - As fallback for text searches +```bash +# Type check - always run on changed files +yarn type-check:ci --force -## 📚 Detailed Documentation +# Lint single file +yarn eslint --fix path/to/file.tsx -- **[.agents/README.md](.agents/README.md)** - Complete development guide -- **[.agents/commands.md](.agents/commands.md)** - All build, test & dev commands -- **[.agents/knowledge-base.md](.agents/knowledge-base.md)** - Knowledge base & best practices +# Format single file +yarn prettier --write path/to/file.tsx + +# Unit test specific file +yarn vitest run path/to/file.test.ts + +# Integration test specific file +yarn test path/to/file.integration-test.ts -- --integrationTestsOnly + +# E2E test specific file +PLAYWRIGHT_HEADLESS=1 yarn e2e path/to/file.e2e.ts +``` + +### Project-wide (use sparingly) + +```bash +# Development +yarn dev # Start dev server +yarn dx # Dev with database setup + +# Build & check +yarn build # Build all packages +yarn lint:fix # Lint and fix 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 migrations +``` + +## Boundaries + +### Always do +- Run type check on changed files before committing +- Run relevant tests before pushing +- Use `select` in Prisma queries +- Follow conventional commits for PR titles + +### Ask first +- Adding new dependencies +- Schema changes to `packages/prisma/schema.prisma` +- Changes affecting multiple packages +- Deleting files +- Running full build or E2E suites + +### Never do +- Commit secrets, API keys, or `.env` files +- Expose `credential.key` in any query +- Use `as any` type casting +- Force push or rebase shared branches +- Modify generated files directly + +## Project Structure + +``` +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 +``` + +### Key files +- 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` + +## Tech Stack + +- **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 + +## Code Examples + +### Good error handling + +```typescript +// Good - Descriptive error with context +throw new TRPCError({ + code: "BAD_REQUEST", + message: `Unable to create booking: User ${userId} has no available time slots for ${date}`, +}); + +// Bad - Generic error +throw new Error("Booking failed"); +``` + +### Good Prisma query + +```typescript +// 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 imports + +```typescript +// 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"; +``` + +## PR Checklist + +- [ ] 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 + +## When Stuck + +- 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 generate` if you see missing enum/type errors + +## Extended Documentation + +For detailed information, see the `agents/` directory: + +- **[agents/README.md](agents/README.md)** - Architecture overview and patterns +- **[agents/commands.md](agents/commands.md)** - Complete command reference +- **[agents/knowledge-base.md](agents/knowledge-base.md)** - Domain knowledge and best practices +- **[agents/coding-standards.md](agents/coding-standards.md)** - Coding standards with examples diff --git a/.agents/README.md b/agents/README.md similarity index 100% rename from .agents/README.md rename to agents/README.md diff --git a/.agents/coding-standards.md b/agents/coding-standards.md similarity index 100% rename from .agents/coding-standards.md rename to agents/coding-standards.md diff --git a/.agents/commands.md b/agents/commands.md similarity index 100% rename from .agents/commands.md rename to agents/commands.md diff --git a/.agents/knowledge-base.md b/agents/knowledge-base.md similarity index 100% rename from .agents/knowledge-base.md rename to agents/knowledge-base.md