# CLAUDE.md — Template SaaS

## Role
Tu es un senior full-stack developer spécialisé en applications SaaS avec authentification, paiements et architecture multi-tenant. Tu écris du code sécurisé et maintenable.

## Project Overview
[Nom du projet] — [Description : quel SaaS construis-tu, pour quelle cible ?]

## Tech Stack
- Framework: Next.js 16 (App Router, Server Components)
- ORM: Drizzle (PostgreSQL via Supabase)
- Auth: Better-Auth (email + OAuth)
- Payments: Stripe (Checkout + Webhooks)
- Style: Tailwind CSS v4
- Email: Resend
- Deploy: Vercel

## Commands
```bash
npm run dev        # Dev server (port 3001)
npm run build      # Build production
npm run lint       # ESLint
npm run test       # Vitest
npm run db:push    # Push schema to DB
npm run db:studio  # Open Drizzle Studio
```

## Architecture
- src/app/              — Pages et routes (App Router)
- src/app/api/          — API Routes (webhooks uniquement)
- src/app/dashboard/    — Pages protégées (authentifiées)
- src/components/       — Composants réutilisables
- src/components/ui/    — Composants UI de base (Button, Input, etc.)
- src/lib/              — Configs et utilitaires (auth, stripe, email)
- src/db/               — Schéma Drizzle, client, migrations
- src/types/            — Types TypeScript partagés

## Patterns (fichiers de référence)
- Server Action avec auth : src/app/dashboard/actions.ts
- Formulaire validé : src/components/[FormComponent].tsx
- Schéma DB avec relations : src/db/schema.ts
- Validation Zod : src/lib/validations.ts
- Webhook Stripe : src/app/api/webhooks/stripe/route.ts

## Conventions
- Server Components par défaut
- Server Actions pour TOUTES les mutations (pas d'API Routes)
- API Routes uniquement pour les webhooks externes (Stripe, etc.)
- Validation Zod sur tous les inputs utilisateur
- Vérification de session dans chaque Server Action :
  ```typescript
  const session = await auth.api.getSession({ headers: await headers() })
  if (!session) throw new Error('Unauthorized')
  ```
- Vérification d'ownership pour les ressources :
  ```typescript
  where(and(eq(table.id, id), eq(table.userId, session.user.id)))
  ```
- TypeScript strict : pas de any
- Tailwind uniquement pour le style

## Security Rules
- Jamais de secret côté client (NEXT_PUBLIC_ = données publiques uniquement)
- Valider la signature Stripe dans les webhooks
- Rate limiting sur les endpoints publics
- Sanitize les données avant affichage (XSS)
- Utiliser parameterized queries (Drizzle le fait par défaut)

## Common Mistakes to Avoid
- Oublier revalidatePath() après une Server Action
- Oublier `await headers()` dans les Server Actions
- Ne pas vérifier l'ownership quand on modifie/supprime une ressource
- Exposer des données sensibles dans les réponses API
- Ne pas gérer le cas "utilisateur non authentifié" dans le dashboard
- Oublier de vérifier la signature du webhook Stripe
