# Guide d'Authentification - COOP-CA AMIFOND Frontend

## Vue d'ensemble

Cette documentation couvre l'implémentation complète du système d'authentification pour l'application COOP-CA AMIFOND avec Next.js 15, TanStack Query, et Zustand.

## Architecture

### Technologies utilisées

- **Next.js 15** - Framework React avec App Router
- **TanStack Query v5** - Gestion des requêtes et cache côté client
- **Zustand** - Gestion d'état global avec persistance
- **Axios** - Client HTTP avec interceptors automatiques
- **React Hook Form** - Gestion des formulaires
- **Zod** - Validation des schémas

### Structure des fichiers

```
src/
├── types/
│   └── auth.ts                     # Types TypeScript pour l'authentification
├── lib/
│   ├── api-config.ts              # Configuration des endpoints et query keys
│   └── api-client.ts              # Client Axios avec interceptors
├── services/
│   └── auth.service.ts            # Services d'authentification
├── stores/
│   └── auth/
│       └── auth-store.ts          # Store Zustand pour l'état d'authentification
├── hooks/
│   └── auth/
│       └── use-auth-queries.ts    # Hooks TanStack Query personnalisés
├── components/
│   └── auth/
│       ├── protected-route.tsx     # Protection des routes
│       └── redirect-if-authenticated.tsx # Redirection des utilisateurs connectés
├── providers/
│   ├── query-provider.tsx         # Provider TanStack Query
│   └── app-providers.tsx          # Provider principal
└── app/
    ├── (main)/
    │   ├── auth/
    │   │   ├── login/             # Page de connexion
    │   │   ├── register/          # Page d'inscription
    │   │   ├── layout.tsx         # Layout protégé pour l'authentification
    │   │   └── _components/       # Composants de formulaires
    │   ├── dashboard/             # Pages protégées
    │   └── unauthorized/          # Page d'accès refusé
    └── layout.tsx                 # Layout racine avec providers
```

## Fonctionnalités implémentées

### ✅ Authentification de base

- [x] Connexion avec email/mot de passe
- [x] Inscription avec validation
- [x] Déconnexion sécurisée
- [x] Refresh automatique des tokens JWT
- [x] Persistance de l'état d'authentification

### ✅ Gestion des utilisateurs

- [x] Types d'utilisateurs (client, employé, admin, etc.)
- [x] Informations de profil utilisateur
- [x] Système de permissions granulaires

### ✅ Sécurité

- [x] Protection des routes avec redirection
- [x] Gestion automatique des tokens expirés
- [x] Validation côté client avec Zod
- [x] Gestion des erreurs centralisée

### ✅ UX/UI

- [x] Formulaires réactifs avec validation en temps réel
- [x] Messages d'erreur localisés en français
- [x] États de chargement et feedback utilisateur
- [x] Interface responsive
- [x] Affichage d'erreurs spécifiques par champ
- [x] Redirection automatique après authentification

### ✅ Configuration Backend/Frontend

- [x] Intégration Django REST API avec Next.js
- [x] Configuration CORS/CSRF pour développement
- [x] Auto-génération des usernames côté backend
- [x] Gestion des erreurs de validation Django vers React Hook Form
- [x] Middleware d'authentification côté client
- [x] Endpoints API opérationnels (/api/v1/auth/)

### 🚧 À implémenter (phases futures)

- [ ] Authentification à deux facteurs (2FA)
- [ ] Authentification sociale (Google, GitHub, Meta)
- [ ] Vérification par email/SMS
- [ ] Reset de mot de passe
- [ ] Gestion avancée des permissions

## Utilisation

### Connexion d'un utilisateur

```typescript
import { useLogin } from "@/hooks/auth/use-auth-queries";

function LoginComponent() {
  const loginMutation = useLogin();

  const handleLogin = async (credentials: LoginRequest) => {
    try {
      await loginMutation.mutateAsync(credentials);
      // Redirection automatique vers /dashboard
    } catch (error) {
      // Erreur gérée automatiquement avec toast
    }
  };
}
```

### Protection d'une route

```typescript
import { ProtectedRoute } from '@/components/auth/protected-route';

function AdminPage() {
  return (
    <ProtectedRoute requiredUserTypes={['admin', 'manager']}>
      <div>Contenu réservé aux administrateurs</div>
    </ProtectedRoute>
  );
}
```

### Utilisation de l'état d'authentification

```typescript
import { useAuth, usePermissions } from '@/stores/auth/auth-store';

function UserProfile() {
  const { user, isAuthenticated } = useAuth();
  const permissions = usePermissions();

  if (!isAuthenticated) return <div>Non connecté</div>;

  return (
    <div>
      <h1>Bienvenue {user?.first_name}</h1>
      {permissions.canManageUsers && (
        <button>Gérer les utilisateurs</button>
      )}
    </div>
  );
}
```

## Configuration

### Variables d'environnement

Créez un fichier `.env.local` basé sur `.env.example` :

```bash
# URL de l'API backend Django
NEXT_PUBLIC_API_URL=http://localhost:8000

# Mode de développement
NODE_ENV=development
```

### Endpoints API attendus

Le frontend s'attend à ce que le backend Django expose ces endpoints :

```python
# Authentication endpoints (implémentés)
POST /api/v1/auth/login/         # Connexion ✅
POST /api/v1/auth/logout/        # Déconnexion ✅
POST /api/v1/auth/register/      # Inscription ✅
GET  /api/v1/auth/user/          # Profil utilisateur actuel ✅
POST /api/v1/auth/token/refresh/ # Refresh du token ✅
POST /api/v1/auth/token/verify/  # Vérification du token ✅
```

### Configuration Django Backend

#### Settings pour développement

```python
# config/settings/development.py
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = [
    'accept', 'accept-encoding', 'authorization', 'content-type',
    'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with',
]

CSRF_TRUSTED_ORIGINS = [
    "http://localhost:3004",
    "http://127.0.0.1:3004",
]

# REST_AUTH configuration
REST_AUTH = {
    "REGISTER_SERIALIZER": "apps.authentication.api.serializers.CustomRegisterSerializer",
}

# Champs d'inscription requis
ACCOUNT_SIGNUP_FIELDS = [
    "email*", "password1*", "password2*",
    "first_name*", "last_name*", "phone_number*"
]
```

#### CustomRegisterSerializer

```python
class CustomRegisterSerializer(RegisterSerializer):
    # Flag pour indiquer à allauth que nous avons un champ phone_number
    _has_phone_field = True

    # Auto-generate username if not provided
    username = serializers.CharField(required=False, allow_blank=True)
    phone_number = serializers.CharField(required=True, max_length=17)

    def custom_signup(self, request, user):
        # Auto-génération du username depuis l'email
        if not user.username:
            email_prefix = user.email.split("@")[0]
            # Logique d'unicité...
```

### Format des réponses API

#### Connexion réussie

```json
{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGci...",
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGci...",
  "user": {
    "id": 1,
    "email": "user@example.com",
    "username": "user",
    "first_name": "Jean",
    "last_name": "Dupont",
    "phone_number": "+237xxxxxxxx",
    "user_type": "client",
    "user_type_display": "Client",
    "is_active": true,
    "is_verified": false,
    "permissions_level": 10,
    "profile": {
      "id": 1,
      "notification_preferences": {
        "email": true,
        "sms": true,
        "push": false
      }
    }
  }
}
```

#### Erreur de validation

```json
{
  "phone_number": ["Ce numéro de téléphone est déjà utilisé"],
  "email": ["Cette adresse email est déjà utilisée"],
  "password1": ["Ce mot de passe est trop simple."]
}
```

#### Inscription réussie

```json
{
  "detail": "Un email de vérification a été envoyé."
}
```

## Dépannage

### Problèmes courants

1. **Token expiré / 401 Unauthorized**
   - Le refresh automatique devrait gérer ce cas
   - Vérifiez que `NEXT_PUBLIC_API_URL` est correct

2. **CORS errors**
   - Configurez CORS sur le backend Django
   - Ajoutez l'URL du frontend dans `CORS_ALLOWED_ORIGINS`

3. **Store Zustand ne persiste pas**
   - Vérifiez que le localStorage fonctionne
   - Consultez les DevTools pour voir le cache

### Debug

- **TanStack Query DevTools** : Activées en développement
- **Zustand DevTools** : Disponibles dans l'extension navigateur
- **Console logs** : Erreurs d'authentification loggées en développement

## Sécurité

### Bonnes pratiques implémentées

- **Tokens stockés en localStorage** : Automatiquement supprimés à la déconnexion
- **Refresh automatique** : Évite les déconnexions intempestives
- **Validation côté client** : Prévient les erreurs de saisie
- **Protection CSRF** : Gérée par Django avec les tokens JWT

### Considérations pour la production

- Configurez HTTPS obligatoire
- Utilisez des tokens avec durée de vie courte
- Implémentez la rotation des refresh tokens
- Ajoutez des logs de sécurité côté backend

## Tests

Pour tester l'authentification :

1. **Démarrez le backend Django** sur `http://localhost:8000`
2. **Démarrez le frontend Next.js** sur `http://localhost:3000`
3. **Naviguez vers** `/auth/login`
4. **Utilisez un compte existant** ou créez-en un via `/auth/register`

## Support

Pour toute question ou problème :

- Consultez la documentation du backend Django
- Vérifiez les logs dans la console du navigateur
- Consultez les issues GitHub du projet

---

**Dernière mise à jour :** 12 août 2025

## ✅ Statut d'implémentation

### Backend Django

- ✅ CustomRegisterSerializer avec auto-génération username
- ✅ Validation des champs phone_number, email, passwords
- ✅ Endpoints API `/api/v1/auth/` opérationnels
- ✅ Configuration CORS/CSRF pour développement
- ✅ Gestion des erreurs de validation détaillées

### Frontend Next.js

- ✅ Store Zustand avec persistance
- ✅ TanStack Query pour les mutations
- ✅ React Hook Form avec validation Zod
- ✅ Gestion d'erreurs avec affichage par champ
- ✅ Middleware d'authentification
- ✅ Interface responsive avec feedback UX

### Tests réalisés

- ✅ Inscription avec validation des champs
- ✅ Connexion avec redirection automatique
- ✅ Gestion des erreurs spécifiques (email/téléphone déjà utilisé)
- ✅ Affichage des erreurs Django dans les bons champs du formulaire
- ✅ Protection des routes et redirection

**Fonctionnalité prête pour la production en développement** 🚀
