This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- Framework: Next.js 16 with App Router, React 19, TypeScript 5.9
- Styling: TailwindCSS 3.4 with Radix UI components
- State Management: Zustand 5 with Immer for client state
- API Layer: tRPC 11 for end-to-end type-safe APIs
- Database: PostgreSQL with Prisma 6.18 (using @prisma/adapter-pg for connection pooling)
- Authentication: Better Auth 1.3 with Google OAuth (extensible to other providers)
- Caching: Upstash Redis for rate limiting and caching
- Validation: Zod 4.1 for runtime type validation
- AI SDK: Vercel AI SDK 5 (available but optional)
- Package Manager: Bun (recommended) - npm/pnpm/yarn also supported
Package Manager: The project uses Bun (see bun.lock) but npm commands work with any package manager (npm, bun, pnpm, yarn).
Important: The postinstall script automatically runs npm run db:generate after installing dependencies to ensure Prisma client is up to date.
npm run dev # Start dev server on port 4242 with Prisma Studio
npm run build # Production build with Prisma generation
npm run lint # Run ESLint (uses flat config in eslint.config.mjs)
npm run format # Auto-fix with ESLint and Prettier
npm run format:check # Check formatting without fixing
npm run analyze # Analyze bundle size with @next/bundle-analyzer
npm run ts-check # TypeScript type checking without emitting files
npm run repomix # Generate codebase context file for AI toolsClient Generation (always run after schema changes):
npm run db:generate # Generate Prisma clientDevelopment Migrations:
npm run db:migrate:dev # Create and apply new migration
npm run db:push # Push schema changes without migration (dev only)
npm run db:studio # Open Prisma Studio on port 5555Production Deployment:
npm run db:migrate:deploy # Apply migrations in productionMigration Management:
npm run db:status # Check migration status
npm run db:reset # Reset database (dev only - destroys data)
npm run db:pull # Pull schema from databaseMigration Debugging:
npm run db:site:diff # Show diff between schema and datasource
npm run db:site:diff-from-prod # Compare local schema to production DB
npm run db:site:resolve-applied -- MIGRATION_NAME # Mark migration as applied
npm run db:site:resolve-rollback -- MIGRATION_NAME # Mark migration as rolled backnpm run ci:migrate # Apply production migrations
npm run ci:validate # Check migration status and run buildThe repository includes a powerful CLI tool for creating new features with proper structure and automatic registry integration.
npm run create # Interactive mode (recommended)
npm run create -- my-feature # Quick create with positional argument
npm run create -- --name=my-feature # Using --name flag
npm run create -- -n my-feature # Using -n short flagWhen you run npm run create, you'll be prompted to select which modules to generate:
-
API (tRPC routes and services) - Creates:
api/index.ts- Feature router that exports to rootapi/{feature-name}.ts- tRPC proceduresapi/services/{feature-name}.service.ts- Business logic layer- Auto-updates
src/trpc/server/api/site/root.ts
-
Components (React components) - Creates:
components/{feature-name}-component.tsx- Example component
-
Lib (types and validation) - Creates:
lib/types/index.ts- TypeScript type definitionslib/validation/{feature-name}.z.ts- Zod validation schemas
-
Pages (reusable page sections) - Creates:
pages/index.tsx- Page component for composition
-
Header Actions (dynamic header content) - Creates:
header-actions.ts- Header action definitionscomponents/{feature-name}-header-action.tsx- Header component- Auto-updates
src/components/layouts/main/header/header-actions/registry.ts
-
Modals (dialogs/drawers) - Creates:
modals.ts- Modal definitionscomponents/modals/example-{feature-name}-modal.tsx- Example modal- Auto-updates
src/modals/registry.ts
The scaffolding tool automatically:
- Creates the feature directory at
src/features/{feature-name}/ - Generates boilerplate code with proper imports and type safety
- Updates registry files (tRPC root, modals registry, header actions registry)
- Uses proper naming conventions (kebab-case for files, PascalCase for components, camelCase for functions)
- Includes example implementations you can customize
npm run create -- --remove my-feature # Remove feature and update registries
npm run create -- -r my-feature # Short formThe removal process:
- Removes imports and references from all registries
- Prompts for confirmation before deleting the directory
- Cleans up tRPC routes, modal definitions, and header actions
The database schema is located at src/prisma/site/schema/schema.prisma. The generated Prisma client outputs to src/prisma/site/.generated/ with separate subdirectories for client and enums.
Important: Always use the generated types from @/prisma/site/.generated/client and @/prisma/site/.generated/enums.
The tRPC API follows a feature-based structure:
-
Router Definition:
src/trpc/server/api/site/root.ts- Main app router that aggregates feature routers -
Feature Organization: Each feature (e.g., settings) has:
src/features/{feature}/api/index.ts- Feature router that exports to rootsrc/features/{feature}/api/{module}.ts- Individual route modules (e.g., user.ts)src/features/{feature}/api/services/{module}.service.ts- Business logic separated from routessrc/features/{feature}/lib/validation/*.z.ts- Zod validation schemas
-
Server Setup:
src/trpc/server/api/site/trpc.tscontains the tRPC initialization and procedure builders -
Client Setup:
src/trpc/react.tsxprovides the React Query integration
The application uses a custom middleware system:
- Entry point:
src/proxy.ts(Next.js middleware file) callsAppProxyfromsrc/lib/proxy - Core logic:
src/lib/proxy/app.tshandles authentication state and routing - Validates sessions for protected routes via
validateProxySession() - Manages admin route access (dev-only, restricted to ADMIN role)
- Redirects based on user onboarding state
- Matcher excludes:
/api/,/_next/,/_proxy/,/_static,/_vercel, and static files
Better Auth 1.3 configuration in src/lib/auth/auth.ts:
- Prisma adapter with PostgreSQL provider
- Google OAuth social provider (extensible for more providers)
- Custom user fields:
role,alias,onboardingCompleted - Session management: 7-day expiry with 1-day update age, 5-minute cookie cache
- Client setup:
src/lib/auth/auth-client.tsexportsuseSession,signIn,signOut,getSession - API routes:
src/app/api/auth/[...all]/route.tshandles all auth endpoints - Session security:
src/lib/auth/session-security.ts
Located in src/zustand/:
- Uses Immer middleware for immutable updates
- Configuration in
src/lib/infra/storage/zustand/immer-config.ts - Versioning support in
src/lib/infra/storage/zustand/versioning.ts - Example stores:
useLayoutStore,useModalStore,useOnboardingStore
Routes are centrally managed in src/routes/:
src/routes/index.ts- Main routes aggregatorsrc/routes/core.ts- Core navigation routessrc/routes/menubar.ts- Menubar/sidebar routessrc/routes/account.ts- Account-related routessrc/routes/admin.ts- Admin routes (dev-only)
Each route implements the Route interface from src/lib/core/types/routes.ts.
The codebase uses a registry pattern for extensibility:
-
Modal Registry (
src/modals/registry.ts):- Each feature exports modals from
{feature}/modals.ts - Central registry aggregates all modals
- Type-safe with auto-inferred props:
ModalPropsMap - Usage:
const { openModal } = useModals(); openModal('modalKey', { props })
- Each feature exports modals from
-
Header Action Registry (
src/components/layouts/main/header/header-actions/registry.ts):- Each feature exports header actions from
{feature}/header-actions.ts - Automatically rendered based on current route
- Type-safe with auto-inferred props:
HeaderActionPropsMap
- Each feature exports header actions from
- UI Components:
src/components/ui/- Radix UI-based design system - Layout Components:
src/components/layouts/- Main layout, headers, footers - Feature Components:
src/features/{feature}/components/- Feature-specific components - Feature Pages:
src/features/{feature}/pages/- Reusable page sections
Located in src/hooks/:
useModals- Modal state managementuseMediaQuery- Responsive breakpoint detectionuseKeyboardShortcut- Keyboard shortcut handlinguseHandleFormError- Form error handling with toast notifications
Managed via @t3-oss/env-nextjs in src/env.js:
- Server-only variables (database URLs, API keys, OAuth secrets)
- Client-exposed variables (prefixed with
NEXT_PUBLIC_) - Automatic validation with Zod schemas
- Set
SKIP_ENV_VALIDATION=trueto skip validation (useful for Docker builds)
TypeScript path alias configured: @/* maps to src/*
The codebase follows strict naming conventions:
- Files:
kebab-case(e.g.,user-notes-form.tsx,use-modals.ts) - Components:
PascalCase(e.g.,UserNotesForm,DeleteAccountModal) - Functions/Variables:
camelCase(e.g.,getUserState,isAuthenticated) - Constants:
SCREAMING_SNAKE_CASE(e.g.,SESSION_CONFIG,DEFAULT_USER_VALUES) - Types/Interfaces:
PascalCase(e.g.,UserState,ModalKey) - Feature directories:
kebab-case(e.g.,user-notes,settings)
When adding new features:
- Create Feature Directory:
src/features/{feature-name}/ - Add tRPC Router:
- Create
api/index.tswith feature router - Add individual route files as needed (e.g.,
api/user.ts) - Separate business logic into
api/services/*.service.ts - Add to
src/trpc/server/api/site/root.ts
- Create
- Add Validation: Create Zod schemas in
lib/validation/*.z.ts - Add UI Components: Create in
components/ - Add Routes: Define routes in
src/routes/if adding navigation - Add Modals (if needed):
- Export modal definitions from
modals.ts - Registry auto-includes them from
src/modals/registry.ts
- Export modal definitions from
- Add Header Actions (if needed):
- Export from
header-actions.ts - Registry auto-includes them from
src/components/layouts/main/header/header-actions/registry.ts
- Export from
- Modify
src/prisma/site/schema/schema.prisma - Run
npm run db:migrate:devto create and apply migration - Commit both the schema file and the migration files in
src/prisma/site/migrations/ - The Prisma client is automatically regenerated in
src/prisma/site/.generated/
The application uses @prisma/adapter-pg with connection pooling:
- Pool configuration in
src/trpc/server/site.ts - Max connections: 20
- Connection timeout: 10s
- Idle timeout: 30s
- Vercel Functions integration via
attachDatabasePool()
Metadata utilities in src/lib/metadata/:
config.ts- Base metadata configurationstructured-data.ts- JSON-LD schema generationicon-graphics.ts- Dynamic icon generation- OpenGraph/Twitter images handled in
src/app/route files
- Custom error handler:
src/lib/core/errors/error-handler.ts - Error messages:
src/lib/core/errors/error-messages.ts - Form error handling: Use
useHandleFormErrorhook - tRPC error handling: Defined in
src/trpc/server/api/site/errors.ts
- Microsoft Clarity:
NEXT_PUBLIC_CLARITY_PROJECT_ID - Google Analytics:
NEXT_PUBLIC_GTAG_ID - Vercel Analytics: Automatically integrated
- Scripts in
src/scripts/analytics.tsx
The repository includes custom Claude Code slash commands in .claude/commands/:
/create [feature-name] [path/to/instructions.md]- Creates and implements a feature end-to-end using the scaffolding script/scrutinize [path_to_parent_component] [instructions...]- Recursively analyzes a component/directory and its children/use-prd [path_to_prd] [path_to_docs]- Analyzes codebase against PRD and docs for alignment/update-prd [path_to_current_prd] [pull_request_number]- Updates PRD by analyzing PR changes/fix [path_to_logs] [path_to_instructions] [path_to_prd] [path_to_docs]- Performs root cause analysis and implements fixes
- Dev Server: http://localhost:4242
- Prisma Studio: http://localhost:5555
- Admin routes:
/admin/*are only accessible in development mode and restricted to ADMIN role users - Build output: Uses standalone output mode for Docker deployments
- Styling: TailwindCSS uses the
tailwind-mergeutility (cn()helper) for className composition - Images: Use Next.js Image component with remote pattern allowlist configured
- Security: Custom security headers configured in
next.config.js - Session validation: Session tokens are validated on protected routes via the proxy middleware
- ESLint: Uses flat config format (eslint.config.mjs) with prettier integration
- TypeScript: Strict mode enabled with
noUncheckedIndexedAccessfor safer array/object access - Turbopack: Development server uses Turbopack for faster builds (Next.js 16 default)