|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Commands |
| 6 | + |
| 7 | +```bash |
| 8 | +# Development |
| 9 | +pnpm dev # Start dev server with Turbopack |
| 10 | +pnpm build # Build all packages |
| 11 | +pnpm type-check # Run TypeScript checks |
| 12 | + |
| 13 | +# Run commands for specific app |
| 14 | +pnpm --filter @onruntime/web dev |
| 15 | +pnpm --filter @onruntime/web build |
| 16 | +``` |
| 17 | + |
| 18 | +## Architecture |
| 19 | + |
| 20 | +### Monorepo Structure (Turborepo + pnpm workspaces) |
| 21 | + |
| 22 | +``` |
| 23 | +/ |
| 24 | +βββ apps/ |
| 25 | +β βββ web/ # Next.js 16 website (@onruntime/web) |
| 26 | +βββ packages/ # Shared packages (future) |
| 27 | +βββ turbo.json # Turborepo configuration |
| 28 | +βββ pnpm-workspace.yaml # pnpm workspace config |
| 29 | +``` |
| 30 | + |
| 31 | +### Web App Structure (`apps/web/src/`) |
| 32 | + |
| 33 | +- **app/**: Next.js App Router pages and API routes |
| 34 | +- **components/**: React components (ui/, layout/, marketing/) |
| 35 | +- **services/**: External API clients with lazy initialization |
| 36 | +- **constants/**: Static data (projects, agencies, services, team members) |
| 37 | +- **content/**: MDX content (glossary, legal pages) |
| 38 | +- **lib/**: Utilities and helpers |
| 39 | +- **types/**: TypeScript type definitions |
| 40 | + |
| 41 | +### Key Patterns |
| 42 | + |
| 43 | +**Services**: Use lazy initialization for external API clients to avoid build failures when env vars are missing in CI: |
| 44 | +```typescript |
| 45 | +// services/email.ts - Proxy pattern for lazy init |
| 46 | +export const resend = new Proxy({} as Resend, { |
| 47 | + get(_, prop) { |
| 48 | + if (!instance) { |
| 49 | + instance = new Resend(env.RESEND_API_KEY); |
| 50 | + } |
| 51 | + return instance[prop as keyof Resend]; |
| 52 | + }, |
| 53 | +}); |
| 54 | + |
| 55 | +// services/join.ts - Client pattern |
| 56 | +export const joinClient = { |
| 57 | + async jobs() { ... }, |
| 58 | + async job(id) { ... }, |
| 59 | +}; |
| 60 | +``` |
| 61 | + |
| 62 | +**Environment Variables**: Managed via `@t3-oss/env-nextjs` in `env.ts`. Validation is skipped in CI (`skipValidation: !!process.env.CI`). |
| 63 | + |
| 64 | +**API Routes**: Use `unstable_cache` from Next.js for caching external API responses. |
| 65 | + |
| 66 | +## Environment Variables |
| 67 | + |
| 68 | +Required for runtime (optional for build): |
| 69 | +- `RESEND_API_KEY`: Email sending via Resend |
| 70 | +- `JOIN_API_KEY`: Job listings from join.com API |
0 commit comments