|
| 1 | +# Project Context for Claude AI |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is a Next.js monorepo project built with TypeScript, using modern web development practices and tools. |
| 6 | + |
| 7 | +## Package Manager |
| 8 | + |
| 9 | +- **pnpm** is the package manager for this project |
| 10 | +- Always use `pnpm` commands instead of `npm` or `yarn` |
| 11 | +- Workspaces are managed through pnpm workspace configuration |
| 12 | + |
| 13 | +## Tech Stack |
| 14 | + |
| 15 | +### Core Framework |
| 16 | + |
| 17 | +- **Next.js** - React framework with App Router |
| 18 | +- **TypeScript** - Primary language for type safety |
| 19 | +- **React** - UI library |
| 20 | + |
| 21 | +### Backend & Database |
| 22 | + |
| 23 | +- **Supabase** - Backend as a Service (BaaS) |
| 24 | + - Authentication |
| 25 | + - PostgreSQL database |
| 26 | + - Real-time subscriptions |
| 27 | + - Storage |
| 28 | + - Edge Functions |
| 29 | + |
| 30 | +### Forms & Validation |
| 31 | + |
| 32 | +- **React Hook Form** - Form state management |
| 33 | +- **Zod** - Schema validation and type inference |
| 34 | +- Always use Zod schemas for form validation |
| 35 | +- Leverage type inference from Zod schemas |
| 36 | + |
| 37 | +### UI Components |
| 38 | + |
| 39 | +- **shadcn/ui** - Component registry (not a component library) |
| 40 | +- Components are copied into the project and can be customized |
| 41 | +- Typically located in `@/components/ui` |
| 42 | +- Built on top of Radix UI primitives |
| 43 | +- Styled with Tailwind CSS |
| 44 | + |
| 45 | +### Styling |
| 46 | + |
| 47 | +- **Tailwind CSS** - Utility-first CSS framework |
| 48 | +- Follow Tailwind conventions and use utility classes |
| 49 | + |
| 50 | +## Code Style & Conventions |
| 51 | + |
| 52 | +### TypeScript Guidelines |
| 53 | + |
| 54 | +- **Prefer `type` over `interface`** for type definitions |
| 55 | +- Use proper TypeScript types throughout the codebase |
| 56 | +- **Avoid `any` type** - only use in inevitable situations where proper typing is genuinely impossible |
| 57 | +- Use type inference where possible |
| 58 | +- Leverage utility types (`Partial`, `Pick`, `Omit`, `Record`, etc.) |
| 59 | + |
| 60 | +Example: |
| 61 | + |
| 62 | +```typescript |
| 63 | +// Preferred ✅ |
| 64 | +type User = { |
| 65 | + id: string; |
| 66 | + name: string; |
| 67 | + email: string; |
| 68 | +}; |
| 69 | + |
| 70 | +type UserFormData = Pick<User, 'name' | 'email'>; |
| 71 | + |
| 72 | +// Avoid ❌ |
| 73 | +interface User { |
| 74 | + id: string; |
| 75 | + name: string; |
| 76 | + email: string; |
| 77 | +} |
| 78 | + |
| 79 | +const data: any = fetchData(); // Avoid this |
| 80 | +``` |
| 81 | + |
| 82 | +### Function Declarations |
| 83 | + |
| 84 | +- **Prefer `function` declarations over `const` arrow functions** where appropriate |
| 85 | +- Use function declarations for top-level functions, utilities, and standalone functions |
| 86 | +- Arrow functions are acceptable for callbacks, inline functions, and when lexical `this` binding is needed |
| 87 | +- React components can use either pattern, but be consistent within the codebase |
| 88 | + |
| 89 | +```typescript |
| 90 | +// Preferred for top-level/utility functions ✅ |
| 91 | +function calculateTotal(items: Item[]): number { |
| 92 | + return items.reduce((sum, item) => sum + item.price, 0); |
| 93 | +} |
| 94 | + |
| 95 | +function formatUser(user: User): string { |
| 96 | + return `${user.name} (${user.email})`; |
| 97 | +} |
| 98 | + |
| 99 | +// Acceptable for callbacks and inline functions ✅ |
| 100 | +const numbers = [1, 2, 3].map((n) => n * 2); |
| 101 | + |
| 102 | +button.addEventListener('click', (e) => { |
| 103 | + handleClick(e); |
| 104 | +}); |
| 105 | + |
| 106 | +// Avoid for standalone functions ❌ |
| 107 | +const calculateTotal = (items: Item[]): number => { |
| 108 | + return items.reduce((sum, item) => sum + item.price, 0); |
| 109 | +}; |
| 110 | +``` |
| 111 | + |
| 112 | +**Benefits of function declarations:** |
| 113 | + |
| 114 | +- Hoisted (can be called before declaration) |
| 115 | +- More readable for complex functions |
| 116 | +- Better stack traces in debugging |
| 117 | +- Clear intent for reusable functions |
| 118 | + |
| 119 | +**When to use arrow functions:** |
| 120 | + |
| 121 | +- Array methods (map, filter, reduce, etc.) |
| 122 | +- Event handlers and callbacks |
| 123 | +- When you need lexical `this` binding |
| 124 | +- Short, inline operations |
| 125 | +- Inside React components for event handlers |
| 126 | + |
| 127 | +### Form Patterns |
| 128 | + |
| 129 | +Use React Hook Form with Zod for all forms: |
| 130 | + |
| 131 | +```typescript |
| 132 | +import { useForm } from 'react-hook-form'; |
| 133 | +import { zodResolver } from '@hookform/resolvers/zod'; |
| 134 | +import { z } from 'zod'; |
| 135 | + |
| 136 | +const formSchema = z.object({ |
| 137 | + email: z.string().email(), |
| 138 | + password: z.string().min(8), |
| 139 | +}); |
| 140 | + |
| 141 | +type FormData = z.infer<typeof formSchema>; |
| 142 | + |
| 143 | +function MyForm() { |
| 144 | + const form = useForm<FormData>({ |
| 145 | + resolver: zodResolver(formSchema), |
| 146 | + defaultValues: { |
| 147 | + email: '', |
| 148 | + password: '', |
| 149 | + }, |
| 150 | + }); |
| 151 | + |
| 152 | + // Handler functions can use arrow syntax for lexical this |
| 153 | + const onSubmit = (data: FormData) => { |
| 154 | + // Handle form submission |
| 155 | + }; |
| 156 | + |
| 157 | + return ( |
| 158 | + <form onSubmit={form.handleSubmit(onSubmit)}> |
| 159 | + {/* Form fields */} |
| 160 | + </form> |
| 161 | + ); |
| 162 | +} |
| 163 | +``` |
| 164 | + |
| 165 | +### Component Patterns |
| 166 | + |
| 167 | +- Use functional components with hooks |
| 168 | +- Follow React Server Components patterns for Next.js App Router |
| 169 | +- Distinguish between Server Components and Client Components |
| 170 | +- Use `"use client"` directive only when necessary |
| 171 | +- Component functions can use either `function` or arrow function syntax (be consistent) |
| 172 | + |
| 173 | +```typescript |
| 174 | +// Both styles are acceptable for React components |
| 175 | + |
| 176 | +// Function declaration style |
| 177 | +export function UserProfile({ userId }: { userId: string }) { |
| 178 | + const [user, setUser] = useState<User | null>(null); |
| 179 | + |
| 180 | + return <div>{user?.name}</div>; |
| 181 | +} |
| 182 | + |
| 183 | +// Or arrow function style (pick one and be consistent) |
| 184 | +export const UserProfile = ({ userId }: { userId: string }) => { |
| 185 | + const [user, setUser] = useState<User | null>(null); |
| 186 | + |
| 187 | + return <div>{user?.name}</div>; |
| 188 | +}; |
| 189 | +``` |
| 190 | + |
| 191 | +### Supabase Integration |
| 192 | + |
| 193 | +- Use Supabase client for database operations |
| 194 | +- Implement Row Level Security (RLS) policies |
| 195 | +- Use TypeScript types generated from Supabase schema when possible |
| 196 | +- Follow Supabase best practices for authentication and data fetching |
| 197 | + |
| 198 | +Example: |
| 199 | + |
| 200 | +```typescript |
| 201 | +import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; |
| 202 | +import type { Database } from '@/types/supabase'; |
| 203 | + |
| 204 | +const supabase = createClientComponentClient<Database>(); |
| 205 | + |
| 206 | +type Profile = Database['public']['Tables']['profiles']['Row']; |
| 207 | + |
| 208 | +// Use function declarations for data fetching utilities |
| 209 | +async function fetchUserProfile(userId: string): Promise<Profile | null> { |
| 210 | + const { data, error } = await supabase.from('profiles').select('*').eq('id', userId).single(); |
| 211 | + |
| 212 | + if (error) { |
| 213 | + console.error('Error fetching profile:', error); |
| 214 | + return null; |
| 215 | + } |
| 216 | + |
| 217 | + return data; |
| 218 | +} |
| 219 | +``` |
| 220 | + |
| 221 | +## File Structure |
| 222 | + |
| 223 | +``` |
| 224 | +. |
| 225 | +├── apps/ |
| 226 | +│ └── web/ # Next.js application |
| 227 | +│ ├── app/ # App Router pages and layouts |
| 228 | +│ ├── components/ # React components |
| 229 | +│ │ └── ui/ # shadcn/ui components |
| 230 | +│ ├── lib/ # Utility functions and shared code |
| 231 | +│ ├── types/ # TypeScript type definitions |
| 232 | +│ └── public/ # Static assets |
| 233 | +├── packages/ # Shared packages (if applicable) |
| 234 | +├── package.json |
| 235 | +├── pnpm-workspace.yaml |
| 236 | +└── turbo.json # Turborepo config (if using) |
| 237 | +``` |
| 238 | + |
| 239 | +## Key Commands |
| 240 | + |
| 241 | +```bash |
| 242 | +# Install dependencies |
| 243 | +pnpm install |
| 244 | + |
| 245 | +# Development |
| 246 | +pnpm dev |
| 247 | + |
| 248 | +# Build |
| 249 | +pnpm build |
| 250 | + |
| 251 | +# Type checking |
| 252 | +pnpm type-check |
| 253 | + |
| 254 | +# Linting |
| 255 | +pnpm lint |
| 256 | +``` |
| 257 | + |
| 258 | +## Best Practices |
| 259 | + |
| 260 | +1. **Type Safety** |
| 261 | + - Always define proper types for function parameters and return values |
| 262 | + - Use Zod for runtime validation and type inference |
| 263 | + - Avoid type assertions unless absolutely necessary |
| 264 | + |
| 265 | +2. **Functions** |
| 266 | + - Use `function` declarations for standalone, reusable functions |
| 267 | + - Use arrow functions for callbacks, array methods, and when lexical `this` is needed |
| 268 | + - Be consistent with React component declaration style across the codebase |
| 269 | + |
| 270 | +3. **Forms** |
| 271 | + - Use React Hook Form for all form state management |
| 272 | + - Define Zod schemas for validation |
| 273 | + - Infer TypeScript types from Zod schemas using `z.infer<>` |
| 274 | + |
| 275 | +4. **Component Design** |
| 276 | + - Keep components small and focused |
| 277 | + - Use composition over configuration |
| 278 | + - Leverage shadcn/ui components as building blocks |
| 279 | + |
| 280 | +5. **Error Handling** |
| 281 | + - Implement proper error boundaries |
| 282 | + - Handle async errors appropriately |
| 283 | + - Provide meaningful error messages to users |
| 284 | + |
| 285 | +## When Suggesting Code |
| 286 | + |
| 287 | +- Always use TypeScript with proper typing |
| 288 | +- Use `type` declarations instead of `interface` |
| 289 | +- Use `function` declarations for standalone functions and utilities |
| 290 | +- Use arrow functions appropriately (callbacks, array methods, lexical this) |
| 291 | +- Ensure pnpm compatibility in any package.json suggestions |
| 292 | +- Follow React Hook Form + Zod patterns for forms |
| 293 | +- Use shadcn/ui components where applicable |
| 294 | +- Consider Next.js App Router patterns (Server vs Client Components) |
| 295 | +- Include Supabase integration patterns when dealing with data |
| 296 | +- Avoid using `any` type - provide specific types or use generics |
| 297 | + |
| 298 | +## Notes for Claude |
| 299 | + |
| 300 | +- When creating new components, check if shadcn/ui has a suitable component first |
| 301 | +- When working with forms, always scaffold with React Hook Form + Zod |
| 302 | +- When suggesting database operations, consider Supabase RLS and best practices |
| 303 | +- Respect the monorepo structure and shared package conventions |
| 304 | +- Always prefer type inference over explicit typing where TypeScript can infer correctly |
| 305 | +- Use function declarations for utility functions, helpers, and business logic |
| 306 | +- Use arrow functions for event handlers, callbacks, and array operations |
0 commit comments