Security & Stability: - Add Next.js 16 proxy.ts for BetterAuth cookie-based auth protection - Add rate limiting for API routes (src/lib/rate-limit.ts) - Add Zod validation for chat API request bodies - Add session auth check to chat and diagnostics endpoints - Add security headers in next.config.ts (CSP, X-Frame-Options, etc.) - Add file upload validation and sanitization in storage.ts Core UX Components: - Add error boundaries (error.tsx, not-found.tsx, chat/error.tsx) - Add loading states (skeleton.tsx, spinner.tsx, loading.tsx files) - Add toast notifications with Sonner - Add form components (input.tsx, textarea.tsx, label.tsx) - Add database indexes for performance (schema.ts) - Enhance chat UX: timestamps, copy-to-clipboard, thinking indicator, error display, localStorage message persistence Polish & Accessibility: - Add Open Graph and Twitter card metadata - Add JSON-LD structured data for SEO - Add sitemap.ts, robots.ts, manifest.ts - Add skip-to-content link and ARIA labels in site-header - Enable profile page quick action buttons with dialogs - Update Next.js 15 references to Next.js 16 Developer Experience: - Add GitHub Actions CI workflow (lint, typecheck, build) - Add Prettier configuration (.prettierrc, .prettierignore) - Add .nvmrc pinning Node 20 - Add ESLint rules: import/order, react-hooks/exhaustive-deps - Add stricter TypeScript settings (exactOptionalPropertyTypes, noImplicitOverride) - Add interactive setup script (scripts/setup.ts) - Add session utility functions (src/lib/session.ts) All changes mirrored to create-agentic-app/template/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.7 KiB
8.7 KiB
Agentic Coding Boilerplate - AI Assistant Guidelines
Project Overview
This is a Next.js 16 boilerplate for building AI-powered applications with authentication, database, and modern UI components.
Tech Stack
- Framework: Next.js 16 with App Router, React 19, TypeScript
- AI Integration: Vercel AI SDK 5 + OpenRouter (access to 100+ AI models)
- Authentication: BetterAuth with Google OAuth
- Database: PostgreSQL with Drizzle ORM
- UI: shadcn/ui components with Tailwind CSS 4
- Styling: Tailwind CSS with dark mode support (next-themes)
AI Integration with OpenRouter
Key Points
- This project uses OpenRouter as the AI provider, NOT direct OpenAI
- OpenRouter provides access to 100+ AI models through a single unified API
- Default model:
openai/gpt-5-mini(configurable viaOPENROUTER_MODELenv var) - Users browse models at: https://openrouter.ai/models
- Users get API keys from: https://openrouter.ai/settings/keys
AI Implementation Files
src/app/api/chat/route.ts- Chat API endpoint using OpenRouter- Package:
@openrouter/ai-sdk-provider(not@ai-sdk/openai) - Import:
import { openrouter } from "@openrouter/ai-sdk-provider"
Project Structure
src/
├── app/ # Next.js App Router
│ ├── api/
│ │ ├── auth/[...all]/ # Better Auth catch-all route
│ │ ├── chat/route.ts # AI chat endpoint (OpenRouter)
│ │ └── diagnostics/ # System diagnostics
│ ├── chat/page.tsx # AI chat interface (protected)
│ ├── dashboard/page.tsx # User dashboard (protected)
│ ├── profile/page.tsx # User profile (protected)
│ ├── page.tsx # Home/landing page
│ └── layout.tsx # Root layout
├── components/
│ ├── auth/ # Authentication components
│ │ ├── sign-in-button.tsx
│ │ ├── sign-out-button.tsx
│ │ └── user-profile.tsx
│ ├── ui/ # shadcn/ui components
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── separator.tsx
│ │ ├── mode-toggle.tsx # Dark/light mode toggle
│ │ └── github-stars.tsx
│ ├── site-header.tsx # Main navigation header
│ ├── site-footer.tsx # Footer component
│ ├── theme-provider.tsx # Dark mode provider
│ ├── setup-checklist.tsx # Setup guide component
│ └── starter-prompt-modal.tsx # Starter prompts modal
└── lib/
├── auth.ts # Better Auth server config
├── auth-client.ts # Better Auth client hooks
├── db.ts # Database connection
├── schema.ts # Drizzle schema (users, sessions, etc.)
├── storage.ts # File storage abstraction (Vercel Blob / local)
└── utils.ts # Utility functions (cn, etc.)
Environment Variables
Required environment variables (see env.example):
# Database
POSTGRES_URL=postgresql://user:password@localhost:5432/db_name
# Better Auth
BETTER_AUTH_SECRET=32-char-random-string
# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# AI via OpenRouter
OPENROUTER_API_KEY=sk-or-v1-your-key
OPENROUTER_MODEL=openai/gpt-5-mini # or any model from openrouter.ai/models
# App
NEXT_PUBLIC_APP_URL=http://localhost:3000
# File Storage (optional)
BLOB_READ_WRITE_TOKEN= # Leave empty for local dev, set for Vercel Blob in production
Available Scripts
npm run dev # Start dev server (DON'T run this yourself - ask user)
npm run build # Build for production (runs db:migrate first)
npm run start # Start production server
npm run lint # Run ESLint (ALWAYS run after changes)
npm run typecheck # TypeScript type checking (ALWAYS run after changes)
npm run db:generate # Generate database migrations
npm run db:migrate # Run database migrations
npm run db:push # Push schema changes to database
npm run db:studio # Open Drizzle Studio (database GUI)
npm run db:dev # Push schema for development
npm run db:reset # Reset database (drop all tables)
Documentation Files
The project includes technical documentation in docs/:
docs/technical/ai/streaming.md- AI streaming implementation guidedocs/technical/ai/structured-data.md- Structured data extractiondocs/technical/react-markdown.md- Markdown rendering guidedocs/technical/betterauth/polar.md- Polar payment integrationdocs/business/starter-prompt.md- Business context for AI prompts
Guidelines for AI Assistants
CRITICAL RULES
-
ALWAYS run lint and typecheck after completing changes:
npm run lint && npm run typecheck -
NEVER start the dev server yourself
- If you need dev server output, ask the user to provide it
- Don't run
npm run devorpnpm dev
-
Use OpenRouter, NOT OpenAI directly
- Import from
@openrouter/ai-sdk-provider - Use
openrouter()function, notopenai() - Model names follow OpenRouter format:
provider/model-name
- Import from
-
Styling Guidelines
- Stick to standard Tailwind CSS utility classes
- Use shadcn/ui color tokens (e.g.,
bg-background,text-foreground) - Avoid custom colors unless explicitly requested
- Support dark mode with appropriate Tailwind classes
-
Authentication
- Server-side: Import from
@/lib/auth(Better Auth instance) - Client-side: Import hooks from
@/lib/auth-client - Protected routes should check session in Server Components
- Use existing auth components from
src/components/auth/
- Server-side: Import from
-
Database Operations
- Use Drizzle ORM (imported from
@/lib/db) - Schema is defined in
@/lib/schema - Always run migrations after schema changes
- PostgreSQL is the database (not SQLite, MySQL, etc.)
- Use Drizzle ORM (imported from
-
File Storage
- Use the storage abstraction from
@/lib/storage - Automatically uses local storage (dev) or Vercel Blob (production)
- Import:
import { upload, deleteFile } from "@/lib/storage" - Example:
const result = await upload(buffer, "avatar.png", "avatars") - Storage switches based on
BLOB_READ_WRITE_TOKENenvironment variable
- Use the storage abstraction from
-
Component Creation
- Use existing shadcn/ui components when possible
- Follow the established patterns in
src/components/ui/ - Support both light and dark modes
- Use TypeScript with proper types
-
API Routes
- Follow Next.js 16 App Router conventions
- Use Route Handlers (route.ts files)
- Return Response objects
- Handle errors appropriately
Best Practices
- Read existing code patterns before creating new features
- Maintain consistency with established file structure
- Use the documentation files when implementing related features
- Test changes with lint and typecheck before considering complete
- When modifying AI functionality, refer to
docs/technical/ai/guides
Common Tasks
Adding a new page:
- Create in
src/app/[route]/page.tsx - Use Server Components by default
- Add to navigation if needed
Adding a new API route:
- Create in
src/app/api/[route]/route.ts - Export HTTP method handlers (GET, POST, etc.)
- Use proper TypeScript types
Adding authentication to a page:
- Import auth instance:
import { auth } from "@/lib/auth" - Get session:
const session = await auth.api.getSession({ headers: await headers() }) - Check session and redirect if needed
Working with the database:
- Update schema in
src/lib/schema.ts - Generate migration:
npm run db:generate - Apply migration:
npm run db:migrate - Import
dbfrom@/lib/dbto query
Modifying AI chat:
- Backend:
src/app/api/chat/route.ts - Frontend:
src/app/chat/page.tsx - Reference streaming docs:
docs/technical/ai/streaming.md - Remember to use OpenRouter, not direct OpenAI
Working with file storage:
- Import storage functions:
import { upload, deleteFile } from "@/lib/storage" - Upload files:
const result = await upload(fileBuffer, "filename.png", "folder") - Delete files:
await deleteFile(result.url) - Storage automatically uses local filesystem in dev, Vercel Blob in production
- Local files are saved to
public/uploads/and served at/uploads/
Package Manager
This project uses pnpm (see pnpm-lock.yaml). When running commands:
- Use
pnpminstead ofnpmwhen possible - Scripts defined in package.json work with
pnpm run [script]