# CLAUDE.md - CodeGuide Starter Kit This file contains essential context about the project structure, technologies, and conventions to help Claude understand and work effectively within this codebase. ## Project Overview **CodeGuide Starter Kit** is a modern Next.js starter template featuring authentication, database integration, AI capabilities, and a comprehensive UI component system. ### Core Technologies - **Framework**: Next.js 15 with App Router (`/src/app` directory structure) - **Language**: TypeScript with strict mode enabled - **Styling**: TailwindCSS v4 with CSS custom properties - **UI Components**: shadcn/ui (New York style) with Lucide icons - **Authentication**: Clerk with middleware protection - **Database**: Supabase with third-party auth integration - **AI Integration**: Vercel AI SDK with support for Anthropic Claude and OpenAI - **Theme System**: next-themes with dark mode support ## Project Structure ``` src/ ├── app/ # Next.js App Router │ ├── api/ # API routes │ │ └── chat/ # AI chat endpoint │ ├── globals.css # Global styles with dark mode │ ├── layout.tsx # Root layout with providers │ └── page.tsx # Home page with status dashboard ├── components/ │ ├── ui/ # shadcn/ui components (40+ components) │ ├── chat.tsx # AI chat interface │ ├── setup-guide.tsx # Configuration guide │ ├── theme-provider.tsx # Theme context provider │ └── theme-toggle.tsx # Dark mode toggle components ├── lib/ │ ├── utils.ts # Utility functions (cn, etc.) │ ├── supabase.ts # Supabase client configurations │ ├── user.ts # User utilities using Clerk │ └── env-check.ts # Environment validation └── middleware.ts # Clerk authentication middleware ``` ## Key Configuration Files - **package.json**: Dependencies and scripts - **components.json**: shadcn/ui configuration (New York style, neutral colors) - **tsconfig.json**: TypeScript configuration with path aliases (`@/`) - **.env.example**: Environment variables template - **SUPABASE_CLERK_SETUP.md**: Integration setup guide ## Authentication & Database ### Clerk Integration - Middleware protects `/dashboard(.*)` and `/profile(.*)` routes - Components: `SignInButton`, `SignedIn`, `SignedOut`, `UserButton` - User utilities in `src/lib/user.ts` use `currentUser()` from Clerk ### Supabase Integration - **Client**: `createSupabaseServerClient()` for server-side with Clerk tokens - **RLS**: Row Level Security uses `auth.jwt() ->> 'sub'` for Clerk user IDs - **Example Migration**: `supabase/migrations/001_example_tables_with_rls.sql` #### Supabase Client Usage Patterns **Server-side (Recommended for data fetching):** ```typescript import { createSupabaseServerClient } from "@/lib/supabase" export async function getServerData() { const supabase = await createSupabaseServerClient() const { data, error } = await supabase .from('posts') .select('*') .order('created_at', { ascending: false }) if (error) { console.error('Database error:', error) return null } return data } ``` **Client-side (For interactive operations):** ```typescript "use client" import { supabase } from "@/lib/supabase" import { useAuth } from "@clerk/nextjs" function ClientComponent() { const { getToken } = useAuth() const fetchData = async () => { const token = await getToken() // Pass token manually for client-side operations const { data, error } = await supabase .from('posts') .select('*') .auth(token) return data } } ``` ## UI & Styling ### TailwindCSS Setup - **Version**: TailwindCSS v4 with PostCSS - **Custom Properties**: CSS variables for theming - **Dark Mode**: Class-based with `next-themes` - **Animations**: `tw-animate-css` package included ### shadcn/ui Components - **Style**: New York variant - **Theme**: Neutral base color with CSS variables - **Icons**: Lucide React - **Components Available**: 40+ UI components (Button, Card, Dialog, etc.) ### Theme System - **Provider**: `ThemeProvider` in layout with system detection - **Toggle Components**: `ThemeToggle` (dropdown) and `SimpleThemeToggle` (button) - **Persistence**: Automatic theme persistence across sessions ## AI Integration ### Vercel AI SDK - **Endpoint**: `/api/chat/route.ts` - **Providers**: Anthropic Claude and OpenAI support - **Chat Component**: Real-time streaming chat interface - **Authentication**: Requires Clerk authentication ## Development Conventions ### File Organization - **Components**: Use PascalCase, place in appropriate directories - **Utilities**: Place reusable functions in `src/lib/` - **Types**: Define alongside components or in dedicated files - **API Routes**: Follow Next.js App Router conventions ### Import Patterns ```typescript // Path aliases (configured in tsconfig.json) import { Button } from "@/components/ui/button" import { getCurrentUser } from "@/lib/user" import { supabase } from "@/lib/supabase" // External libraries import { useTheme } from "next-themes" import { SignedIn, useAuth } from "@clerk/nextjs" ``` ### Component Patterns ```typescript // Client components (when using hooks/state) "use client" // Server components (default, for data fetching) export default async function ServerComponent() { const user = await getCurrentUser() // ... } ``` ## Environment Variables Required for full functionality: ```bash # Clerk Authentication NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... CLERK_SECRET_KEY=sk_test_... # Supabase Database NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... # AI Integration (optional) OPENAI_API_KEY=sk-... ANTHROPIC_API_KEY=sk-ant-... ``` ## Common Patterns ### Row Level Security (RLS) Policies All database tables should use RLS policies that reference Clerk user IDs via `auth.jwt() ->> 'sub'`. **Basic User-Owned Data Pattern:** ```sql -- Enable RLS on table ALTER TABLE posts ENABLE ROW LEVEL SECURITY; -- Users can read all posts (public) CREATE POLICY "Anyone can read posts" ON posts FOR SELECT USING (true); -- Users can only insert posts as themselves CREATE POLICY "Users can insert own posts" ON posts FOR INSERT WITH CHECK (auth.jwt() ->> 'sub' = user_id); -- Users can only update their own posts CREATE POLICY "Users can update own posts" ON posts FOR UPDATE USING (auth.jwt() ->> 'sub' = user_id); -- Users can only delete their own posts CREATE POLICY "Users can delete own posts" ON posts FOR DELETE USING (auth.jwt() ->> 'sub' = user_id); ``` **Private Data Pattern:** ```sql -- Completely private to each user CREATE POLICY "Users can only access own data" ON private_notes FOR ALL USING (auth.jwt() ->> 'sub' = user_id); ``` **Conditional Visibility Pattern:** ```sql -- Public profiles or own profile CREATE POLICY "Users can read public profiles or own profile" ON profiles FOR SELECT USING ( is_public = true OR auth.jwt() ->> 'sub' = user_id ); ``` **Collaboration Pattern:** ```sql -- Owner and collaborators can access CREATE POLICY "Owners and collaborators can read" ON collaborations FOR SELECT USING ( auth.jwt() ->> 'sub' = owner_id OR auth.jwt() ->> 'sub' = ANY(collaborators) ); ``` ### Database Operations with Supabase **Complete CRUD Example:** ```typescript import { createSupabaseServerClient } from "@/lib/supabase" import { getCurrentUser } from "@/lib/user" // CREATE - Insert new record export async function createPost(title: string, content: string) { const user = await getCurrentUser() if (!user) return null const supabase = await createSupabaseServerClient() const { data, error } = await supabase .from('posts') .insert({ title, content, user_id: user.id, // Clerk user ID }) .select() .single() if (error) { console.error('Error creating post:', error) return null } return data } // READ - Fetch user's posts export async function getUserPosts() { const supabase = await createSupabaseServerClient() const { data, error } = await supabase .from('posts') .select(` id, title, content, created_at, user_id `) .order('created_at', { ascending: false }) if (error) { console.error('Error fetching posts:', error) return [] } return data } // UPDATE - Modify existing record export async function updatePost(postId: string, updates: { title?: string; content?: string }) { const supabase = await createSupabaseServerClient() const { data, error } = await supabase .from('posts') .update(updates) .eq('id', postId) .select() .single() if (error) { console.error('Error updating post:', error) return null } return data } // DELETE - Remove record export async function deletePost(postId: string) { const supabase = await createSupabaseServerClient() const { error } = await supabase .from('posts') .delete() .eq('id', postId) if (error) { console.error('Error deleting post:', error) return false } return true } ``` **Real-time Subscriptions:** ```typescript "use client" import { useEffect, useState } from "react" import { supabase } from "@/lib/supabase" import { useAuth } from "@clerk/nextjs" function useRealtimePosts() { const [posts, setPosts] = useState([]) const { getToken } = useAuth() useEffect(() => { const fetchPosts = async () => { const token = await getToken() const { data } = await supabase .from('posts') .select('*') .auth(token) setPosts(data || []) } fetchPosts() // Subscribe to changes const subscription = supabase .channel('posts-channel') .on('postgres_changes', { event: '*', schema: 'public', table: 'posts' }, (payload) => { fetchPosts() // Refetch on any change } ) .subscribe() return () => { subscription.unsubscribe() } }, [getToken]) return posts } ``` ### Protected Routes Routes matching `/dashboard(.*)` and `/profile(.*)` are automatically protected by Clerk middleware. ### Theme-Aware Components ```typescript // Automatic dark mode support via CSS custom properties
``` ## Development Commands ```bash npm run dev # Start development server with Turbopack npm run build # Build for production npm run start # Start production server npm run lint # Run ESLint ``` ## Best Practices 1. **Authentication**: Always check user state with Clerk hooks/utilities 2. **Database**: Use RLS policies with Clerk user IDs for security 3. **UI**: Leverage existing shadcn/ui components before creating custom ones 4. **Styling**: Use TailwindCSS classes and CSS custom properties for theming 5. **Types**: Maintain strong TypeScript typing throughout 6. **Performance**: Use server components by default, client components only when needed ## Integration Notes - **Clerk + Supabase**: Uses modern third-party auth (not deprecated JWT templates) - **AI Chat**: Requires authentication and environment variables - **Dark Mode**: Automatically applied to all shadcn components - **Mobile**: Responsive design with TailwindCSS breakpoints This starter kit provides a solid foundation for building modern web applications with authentication, database integration, AI capabilities, and polished UI components.