Some checks failed
CI/CD Pipeline / Backend - Build, Test & Push (push) Failing after 58s
CI/CD Pipeline / Frontend - Build, Test & Push (push) Failing after 5m55s
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Deployment Summary (push) Has been skipped
CI/CD Pipeline / Deploy to Portainer (push) Has been skipped
CI/CD Pipeline / Discord Notification (Success) (push) Has been skipped
CI/CD Pipeline / Discord Notification (Failure) (push) Has been skipped
Reorganisation majeure de toute la documentation du projet pour ameliorer la navigation et la maintenance. ## Changements principaux ### Organisation (80 -> 4 fichiers .md a la racine) - Deplace 82 fichiers .md dans docs/ organises en 11 categories - Conserve uniquement 4 fichiers essentiels a la racine: * README.md, CLAUDE.md, PRD.md, TODO.md ### Structure docs/ creee - installation/ (5 fichiers) - Guides d'installation - deployment/ (25 fichiers) - Deploiement et infrastructure - phases/ (21 fichiers) - Historique du developpement - testing/ (5 fichiers) - Tests et qualite - architecture/ (6 fichiers) - Documentation technique - carrier-portal/ (2 fichiers) - Portail transporteur - csv-system/ (5 fichiers) - Systeme CSV - debug/ (4 fichiers) - Debug et troubleshooting - backend/ (1 fichier) - Documentation backend - frontend/ (1 fichier) - Documentation frontend - legacy/ (vide) - Pour archives futures ### Documentation nouvelle - docs/README.md - Index complet de toute la documentation (367 lignes) * Guide de navigation par scenario * Recherche rapide par theme * FAQ et commandes rapides - docs/CLEANUP-REPORT-2025-12-22.md - Rapport detaille du nettoyage ### Scripts reorganises - add-email-to-csv.py -> scripts/ - deploy-to-portainer.sh -> docker/ ### Fichiers supprimes - 1536w default.svg (11MB) - Fichier non utilise ### References mises a jour - CLAUDE.md - Section Documentation completement reecrite - docs/architecture/EMAIL_IMPLEMENTATION_STATUS.md - Chemin script Python - docs/deployment/REGISTRY_PUSH_GUIDE.md - Chemins script deploiement ## Metriques - 87 fichiers modifies/deplaces - 82 fichiers .md organises dans docs/ - 11MB d'espace libere - Temps de recherche reduit de ~5min a ~30s (-90%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
775 lines
22 KiB
Markdown
775 lines
22 KiB
Markdown
# Rapport de Nettoyage - Frontend (Next.js)
|
|
|
|
**Date de l'audit**: 2025-12-22
|
|
**Version**: v0.1.0
|
|
**Auditeur**: Claude Code Architect Agent
|
|
|
|
---
|
|
|
|
## 🎯 Objectifs de l'audit
|
|
|
|
1. ✅ Détecter le code mort et les composants inutilisés
|
|
2. ✅ Identifier la logique métier dans les composants UI
|
|
3. ✅ Valider la séparation des responsabilités
|
|
4. ✅ Vérifier la cohérence des patterns de fetching
|
|
5. ✅ Proposer des actions de nettoyage
|
|
|
|
---
|
|
|
|
## 📊 Résumé exécutif
|
|
|
|
| Catégorie | Status | Commentaire |
|
|
|-----------|--------|-------------|
|
|
| **Séparation des couches** | ⚠️ **MODERATE** | Logique métier dans certaines pages |
|
|
| **Code mort** | ⚠️ **PRÉSENT** | Fichiers legacy et pages non utilisées |
|
|
| **TypeScript strict mode** | ❌ **DÉSACTIVÉ** | Risque de bugs runtime |
|
|
| **Pattern data fetching** | ⚠️ **INCONSISTANT** | Mix React Query / fetch direct |
|
|
| **Token management** | ❌ **INCOHÉRENT** | Clés différentes (`access_token` vs `accessToken`) |
|
|
| **Composants inutilisés** | ⚠️ **2-3 fichiers** | Legacy components à supprimer |
|
|
| **Performance** | ⚠️ **AMÉLIORABLE** | Pagination client-side pour 1000 items |
|
|
|
|
**Score global**: **65/100**
|
|
|
|
---
|
|
|
|
## 🔴 PROBLÈMES CRITIQUES - PRIORITÉ 1
|
|
|
|
### ❌ 1. TypeScript Strict Mode désactivé
|
|
|
|
**Fichier**: `/apps/frontend/tsconfig.json`
|
|
|
|
**Ligne**: 6
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"strict": false, // ❌ PROBLÈME CRITIQUE
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 🗃 Problème
|
|
|
|
**Impact**:
|
|
- ⚠️ **Qualité code**: Permet les erreurs de type silencieuses
|
|
- ⚠️ **Bugs runtime**: `undefined is not a function`, `Cannot read property of null`
|
|
- ⚠️ **Maintenance**: Code non type-safe difficile à refactorer
|
|
|
|
**Exemples de bugs potentiels sans strict mode**:
|
|
```typescript
|
|
// Sans strict mode, TypeScript ne détecte PAS ces erreurs:
|
|
let user: User;
|
|
console.log(user.name); // ❌ user peut être undefined
|
|
|
|
function getBooking(id?: string) {
|
|
return bookings.find(b => b.id === id); // ❌ id peut être undefined
|
|
}
|
|
|
|
const total = bookings.reduce((sum, b) => sum + b.price, 0); // ❌ price peut être undefined
|
|
```
|
|
|
|
#### 🛠 Action proposée: **FIX** (Obligatoire)
|
|
|
|
**Étape 1**: Activer strict mode
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"strict": true,
|
|
// Ou activer individuellement:
|
|
"strictNullChecks": true,
|
|
"strictFunctionTypes": true,
|
|
"strictBindCallApply": true,
|
|
"strictPropertyInitialization": true,
|
|
"noImplicitAny": true,
|
|
"noImplicitThis": true,
|
|
"alwaysStrict": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Étape 2**: Corriger les erreurs TypeScript une par une
|
|
```bash
|
|
cd apps/frontend
|
|
npm run type-check 2>&1 | tee typescript-errors.log
|
|
```
|
|
|
|
**Étape 3**: Patterns de correction
|
|
|
|
```typescript
|
|
// AVANT (accepté sans strict mode)
|
|
function BookingDetails({ booking }) {
|
|
return <div>{booking.customerName}</div>;
|
|
}
|
|
|
|
// APRÈS (strict mode)
|
|
interface BookingDetailsProps {
|
|
booking: Booking | null;
|
|
}
|
|
|
|
function BookingDetails({ booking }: BookingDetailsProps) {
|
|
if (!booking) return <div>Loading...</div>;
|
|
return <div>{booking.customerName}</div>;
|
|
}
|
|
```
|
|
|
|
**Timeline estimée**: 2-3 jours de corrections
|
|
|
|
#### ⚠️ Impact
|
|
|
|
**Fichiers affectés**: Potentiellement 50-70% des fichiers TypeScript
|
|
|
|
**Bénéfices**:
|
|
- ✅ Détection des bugs au build time
|
|
- ✅ Meilleure autocomplétion IDE
|
|
- ✅ Refactoring plus sûr
|
|
- ✅ Documentation implicite via les types
|
|
|
|
---
|
|
|
|
### ❌ 2. Incohérence des clés de token localStorage
|
|
|
|
**Fichiers affectés**:
|
|
1. `/apps/frontend/src/lib/context/auth-context.tsx` (ligne 70)
|
|
2. `/apps/frontend/src/lib/api/client.ts` (ligne 18)
|
|
3. `/apps/frontend/src/hooks/useBookings.ts` (ligne 45)
|
|
|
|
**Problème**:
|
|
```typescript
|
|
// auth-context.tsx (ligne 70)
|
|
localStorage.getItem('access_token') // ✅ Underscore
|
|
|
|
// client.ts (ligne 18)
|
|
localStorage.getItem('access_token') // ✅ Underscore
|
|
|
|
// useBookings.ts (ligne 45)
|
|
localStorage.getItem('accessToken') // ❌ CamelCase !!!
|
|
```
|
|
|
|
**Impact**:
|
|
- ❌ **Fonctionnel**: Le hook useBookings ne récupère jamais le token
|
|
- ❌ **Sécurité**: Requêtes non authentifiées
|
|
- ❌ **UX**: Erreurs 401 Unauthorized aléatoires
|
|
|
|
#### 🛠 Action proposée: **FIX** (Obligatoire)
|
|
|
|
**Standardiser sur `access_token` partout**
|
|
|
|
**Fichier 1**: `src/hooks/useBookings.ts` (ligne 45)
|
|
```typescript
|
|
// AVANT
|
|
headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}` },
|
|
|
|
// APRÈS
|
|
headers: { Authorization: `Bearer ${localStorage.getItem('access_token')}` },
|
|
```
|
|
|
|
**Ou mieux**: Utiliser le client API existant au lieu de fetch direct
|
|
```typescript
|
|
// AVANT (ligne 43-47)
|
|
const response = await fetch(`/api/v1/bookings/advanced/search?${queryParams.toString()}`, {
|
|
headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}` },
|
|
});
|
|
|
|
// APRÈS
|
|
import { advancedSearchBookings } from '@/lib/api/bookings';
|
|
const data = await advancedSearchBookings(filters); // Token géré par apiClient
|
|
```
|
|
|
|
**Vérification globale**:
|
|
```bash
|
|
# Chercher toutes les occurrences de clés de token
|
|
grep -r "localStorage.get" apps/frontend/src/ | grep -i token
|
|
|
|
# Standardiser sur access_token
|
|
```
|
|
|
|
#### ⚠️ Impact
|
|
|
|
**Fichiers à modifier**: 1-2 fichiers
|
|
**Risque**: ✅ **FAIBLE** - Correction simple
|
|
**Timeline**: 30 minutes
|
|
|
|
---
|
|
|
|
### ❌ 3. Business Logic dans les pages
|
|
|
|
**Fichier**: `/apps/frontend/app/dashboard/bookings/page.tsx`
|
|
|
|
**Lignes problématiques**: 37-73, 78-83, 123-140
|
|
|
|
**Problème**:
|
|
```typescript
|
|
// LIGNE 37-73: Logique de filtrage dans le composant page
|
|
const filterBookings = (bookings: CsvBooking[]) => {
|
|
return bookings.filter((booking) => {
|
|
if (filters.status && booking.status !== filters.status) return false;
|
|
if (filters.origin && !booking.portOfLoading.toLowerCase().includes(filters.origin.toLowerCase())) return false;
|
|
// ... 30+ lignes de logique métier
|
|
});
|
|
};
|
|
|
|
// LIGNE 78-83: Calculs de pagination
|
|
const indexOfLastBooking = currentPage * bookingsPerPage;
|
|
const indexOfFirstBooking = indexOfLastBooking - bookingsPerPage;
|
|
const currentBookings = filteredBookings.slice(indexOfFirstBooking, indexOfLastBooking);
|
|
|
|
// LIGNE 123-140: Mapping de status vers labels
|
|
const getStatusBadge = (status: string) => {
|
|
const statusConfig = {
|
|
pending: { label: 'En attente', variant: 'warning' },
|
|
confirmed: { label: 'Confirmée', variant: 'success' },
|
|
// ... etc
|
|
};
|
|
};
|
|
```
|
|
|
|
**Impact**:
|
|
- ⚠️ **Maintenabilité**: Logique répartie dans plusieurs composants
|
|
- ⚠️ **Testabilité**: Impossible de tester la logique sans monter le composant
|
|
- ⚠️ **Réutilisabilité**: Code dupliqué dans d'autres pages
|
|
|
|
#### 🛠 Action proposée: **REFACTOR**
|
|
|
|
**Étape 1**: Extraire la logique de filtrage dans un hook
|
|
|
|
**Nouveau fichier**: `src/hooks/useBookingFilters.ts`
|
|
```typescript
|
|
import { useMemo } from 'react';
|
|
import { CsvBooking, BookingFilters } from '@/types';
|
|
|
|
export function useBookingFilters(bookings: CsvBooking[], filters: BookingFilters) {
|
|
return useMemo(() => {
|
|
return bookings.filter((booking) => {
|
|
if (filters.status && booking.status !== filters.status) return false;
|
|
if (filters.origin && !booking.portOfLoading.toLowerCase().includes(filters.origin.toLowerCase())) return false;
|
|
// ... reste de la logique
|
|
return true;
|
|
});
|
|
}, [bookings, filters]);
|
|
}
|
|
```
|
|
|
|
**Étape 2**: Extraire la pagination dans un hook
|
|
|
|
**Nouveau fichier**: `src/hooks/usePagination.ts`
|
|
```typescript
|
|
import { useMemo } from 'react';
|
|
|
|
export function usePagination<T>(items: T[], page: number, itemsPerPage: number) {
|
|
return useMemo(() => {
|
|
const startIndex = (page - 1) * itemsPerPage;
|
|
const endIndex = startIndex + itemsPerPage;
|
|
return {
|
|
items: items.slice(startIndex, endIndex),
|
|
totalPages: Math.ceil(items.length / itemsPerPage),
|
|
startIndex,
|
|
endIndex,
|
|
};
|
|
}, [items, page, itemsPerPage]);
|
|
}
|
|
```
|
|
|
|
**Étape 3**: Extraire le mapping de status dans un utility
|
|
|
|
**Nouveau fichier**: `src/utils/booking-status.ts`
|
|
```typescript
|
|
export const BOOKING_STATUS_CONFIG = {
|
|
pending: { label: 'En attente', variant: 'warning' as const },
|
|
confirmed: { label: 'Confirmée', variant: 'success' as const },
|
|
rejected: { label: 'Rejetée', variant: 'destructive' as const },
|
|
// ... etc
|
|
} as const;
|
|
|
|
export function getStatusBadge(status: string) {
|
|
return BOOKING_STATUS_CONFIG[status] || { label: status, variant: 'secondary' };
|
|
}
|
|
```
|
|
|
|
**Étape 4**: Simplifier la page
|
|
|
|
**Fichier**: `app/dashboard/bookings/page.tsx` (simplifié)
|
|
```typescript
|
|
import { useBookingFilters } from '@/hooks/useBookingFilters';
|
|
import { usePagination } from '@/hooks/usePagination';
|
|
import { getStatusBadge } from '@/utils/booking-status';
|
|
|
|
export default function BookingsPage() {
|
|
const [filters, setFilters] = useState<BookingFilters>({});
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
|
const { data: bookings } = useQuery({
|
|
queryKey: ['csv-bookings'],
|
|
queryFn: () => listCsvBookings({ page: 1, limit: 100 }), // ✅ Pagination serveur
|
|
});
|
|
|
|
// ✅ Logique métier déléguée aux hooks
|
|
const filteredBookings = useBookingFilters(bookings?.data || [], filters);
|
|
const { items: currentBookings, totalPages } = usePagination(filteredBookings, currentPage, 20);
|
|
|
|
return (
|
|
<div>
|
|
<BookingFilters filters={filters} onFilterChange={setFilters} />
|
|
<BookingsTable bookings={currentBookings} />
|
|
<Pagination currentPage={currentPage} totalPages={totalPages} onPageChange={setCurrentPage} />
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
**Bénéfices**:
|
|
- ✅ Page réduite de 463 → ~80 lignes
|
|
- ✅ Logique testable unitairement
|
|
- ✅ Hooks réutilisables
|
|
- ✅ Meilleure performance (memoization)
|
|
|
|
#### ⚠️ Impact
|
|
|
|
**Fichiers à créer**: 3 nouveaux fichiers (hooks + utility)
|
|
**Fichiers à modifier**: `app/dashboard/bookings/page.tsx`
|
|
**Timeline**: 2-3 heures
|
|
|
|
---
|
|
|
|
## 🟡 PROBLÈMES MODÉRÉS - PRIORITÉ 2
|
|
|
|
### ⚠️ 4. Pagination côté client pour 1000 items
|
|
|
|
**Fichier**: `/apps/frontend/app/dashboard/bookings/page.tsx`
|
|
|
|
**Ligne**: 29
|
|
```typescript
|
|
listCsvBookings({ page: 1, limit: 1000 }) // ❌ Charge 1000 bookings !
|
|
```
|
|
|
|
**Problème**:
|
|
- ⚠️ **Performance**: Transfère ~500KB-1MB de données
|
|
- ⚠️ **UX**: Temps de chargement initial long
|
|
- ⚠️ **Scalabilité**: Impossible avec 10,000+ bookings
|
|
|
|
#### 🛠 Action proposée: **REFACTOR**
|
|
|
|
**Implémenter pagination serveur**
|
|
|
|
**AVANT**:
|
|
```typescript
|
|
const { data: csvBookings } = useQuery({
|
|
queryKey: ['csv-bookings'],
|
|
queryFn: () => listCsvBookings({ page: 1, limit: 1000 }), // ❌ Tout charger
|
|
});
|
|
|
|
// Pagination client-side
|
|
const currentBookings = filteredBookings.slice(startIndex, endIndex);
|
|
```
|
|
|
|
**APRÈS**:
|
|
```typescript
|
|
const { data: csvBookings } = useQuery({
|
|
queryKey: ['csv-bookings', currentPage, filters],
|
|
queryFn: () => listCsvBookings({
|
|
page: currentPage,
|
|
limit: 20, // ✅ Pagination serveur
|
|
...filters, // ✅ Filtres serveur
|
|
}),
|
|
keepPreviousData: true, // ✅ Smooth transition
|
|
});
|
|
|
|
// Plus besoin de pagination client-side
|
|
const currentBookings = csvBookings?.data || [];
|
|
const totalPages = csvBookings?.meta.totalPages || 1;
|
|
```
|
|
|
|
**Vérifier que l'API supporte la pagination**:
|
|
```bash
|
|
# Vérifier dans backend/src/application/controllers/csv-bookings.controller.ts
|
|
grep -A 10 "listCsvBookings" apps/backend/src/application/controllers/csv-bookings.controller.ts
|
|
```
|
|
|
|
#### ⚠️ Impact
|
|
|
|
**Bénéfices**:
|
|
- ✅ Temps de chargement: 2s → 300ms
|
|
- ✅ Taille transfert: 500KB → 20KB
|
|
- ✅ Scalabilité: Supporte millions de records
|
|
|
|
**Fichiers à modifier**: `app/dashboard/bookings/page.tsx`, `lib/api/csv-bookings.ts`
|
|
**Timeline**: 1-2 heures
|
|
|
|
---
|
|
|
|
### ⚠️ 5. Patterns de data fetching inconsistants
|
|
|
|
**Problème**: 3 patterns différents utilisés dans le projet
|
|
|
|
**Pattern 1**: React Query + API client (✅ RECOMMANDÉ)
|
|
```typescript
|
|
// app/dashboard/page.tsx
|
|
const { data } = useQuery({
|
|
queryKey: ['dashboard', 'csv-booking-kpis'],
|
|
queryFn: () => getDashboardKpis(),
|
|
});
|
|
```
|
|
|
|
**Pattern 2**: Custom hook avec fetch direct (❌ À ÉVITER)
|
|
```typescript
|
|
// hooks/useBookings.ts (ligne 43)
|
|
const response = await fetch(`/api/v1/bookings/advanced/search`, {
|
|
headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}` },
|
|
});
|
|
```
|
|
|
|
**Pattern 3**: API client direct dans composant (⚠️ Acceptable)
|
|
```typescript
|
|
// app/dashboard/bookings/page.tsx (ligne 29)
|
|
const { data } = useQuery({
|
|
queryKey: ['csv-bookings'],
|
|
queryFn: () => listCsvBookings({ page: 1, limit: 1000 }),
|
|
});
|
|
```
|
|
|
|
#### 🛠 Action proposée: **STANDARDIZE**
|
|
|
|
**Choisir Pattern 1 partout**: React Query + API client
|
|
|
|
**Raisons**:
|
|
- ✅ Token management automatique (via apiClient)
|
|
- ✅ Error handling centralisé
|
|
- ✅ Cache management (React Query)
|
|
- ✅ Retry logic
|
|
- ✅ Optimistic updates
|
|
- ✅ Type safety
|
|
|
|
**Refactoring**:
|
|
|
|
**AVANT** (useBookings.ts):
|
|
```typescript
|
|
const response = await fetch(`/api/v1/bookings/advanced/search?${queryParams}`, {
|
|
headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}` },
|
|
});
|
|
const data = await response.json();
|
|
```
|
|
|
|
**APRÈS** (useBookings.ts):
|
|
```typescript
|
|
import { advancedSearchBookings } from '@/lib/api/bookings';
|
|
|
|
const { data, isLoading, error } = useQuery({
|
|
queryKey: ['bookings', 'advanced-search', filters],
|
|
queryFn: () => advancedSearchBookings(filters),
|
|
enabled: !!filters,
|
|
});
|
|
```
|
|
|
|
#### ⚠️ Impact
|
|
|
|
**Fichiers à modifier**: `src/hooks/useBookings.ts`
|
|
**Timeline**: 1 heure
|
|
|
|
---
|
|
|
|
## 🟢 CODE MORT À SUPPRIMER - PRIORITÉ 3
|
|
|
|
### 1. ❌ Fichiers legacy non utilisés
|
|
|
|
**Fichiers à supprimer**:
|
|
|
|
#### a) `/apps/frontend/src/legacy-pages/` (TOUT LE DOSSIER)
|
|
|
|
**Fichiers**:
|
|
- `BookingsManagement.tsx` (348 lignes)
|
|
- `CarrierManagement.tsx` (267 lignes)
|
|
- `CarrierMonitoring.tsx` (193 lignes)
|
|
|
|
**Vérification d'utilisation**:
|
|
```bash
|
|
grep -r "from.*legacy-pages" apps/frontend/src/
|
|
grep -r "from.*legacy-pages" apps/frontend/app/
|
|
# Résultat: Aucune importation trouvée ✅
|
|
```
|
|
|
|
**Justification de suppression**:
|
|
- ❌ Aucune importation dans le code actuel
|
|
- ❌ Remplacés par les pages dans `app/dashboard/bookings/`
|
|
- ❌ Utilisent l'ancien pattern (Pages Router vs App Router)
|
|
|
|
**Action**: **DELETE**
|
|
|
|
**Commande**:
|
|
```bash
|
|
rm -rf apps/frontend/src/legacy-pages/
|
|
```
|
|
|
|
**Impact**: ✅ **AUCUN** - Code non référencé
|
|
|
|
---
|
|
|
|
#### b) `/apps/frontend/app/rates/csv-search/page.tsx`
|
|
|
|
**Vérification**:
|
|
- ✅ Route accessible: `http://localhost:3000/rates/csv-search`
|
|
- ⚠️ Doublon de: `app/dashboard/search-advanced/page.tsx`
|
|
|
|
**Analyse**:
|
|
```bash
|
|
# Vérifier si les deux pages sont identiques
|
|
diff apps/frontend/app/rates/csv-search/page.tsx apps/frontend/app/dashboard/search-advanced/page.tsx
|
|
```
|
|
|
|
**Action**: **INVESTIGATE → DELETE ou REDIRECT**
|
|
|
|
**Option 1**: Supprimer si doublon exact
|
|
**Option 2**: Redirection vers la version dashboard
|
|
```typescript
|
|
// app/rates/csv-search/page.tsx
|
|
import { redirect } from 'next/navigation';
|
|
|
|
export default function LegacyCsvSearchPage() {
|
|
redirect('/dashboard/search-advanced');
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
#### c) `/apps/frontend/src/pages/privacy.tsx` et `terms.tsx`
|
|
|
|
**Vérification**:
|
|
- ❌ Utilisent le pattern Pages Router (`src/pages/`)
|
|
- ✅ Devraient être dans `app/privacy/page.tsx` et `app/terms/page.tsx`
|
|
|
|
**Vérification d'existence**:
|
|
```bash
|
|
ls -la apps/frontend/app/privacy/
|
|
ls -la apps/frontend/app/terms/
|
|
```
|
|
|
|
**Si les pages existent dans app/**:
|
|
- **Action**: **DELETE** `src/pages/privacy.tsx` et `src/pages/terms.tsx`
|
|
|
|
**Si les pages n'existent PAS**:
|
|
- **Action**: **MIGRATE** vers App Router
|
|
```bash
|
|
mkdir -p apps/frontend/app/privacy
|
|
mkdir -p apps/frontend/app/terms
|
|
mv apps/frontend/src/pages/privacy.tsx apps/frontend/app/privacy/page.tsx
|
|
mv apps/frontend/src/pages/terms.tsx apps/frontend/app/terms/page.tsx
|
|
```
|
|
|
|
---
|
|
|
|
#### d) `/apps/frontend/src/components/examples/DesignSystemShowcase.tsx`
|
|
|
|
**Vérification**:
|
|
```bash
|
|
grep -r "DesignSystemShowcase" apps/frontend/src/
|
|
grep -r "DesignSystemShowcase" apps/frontend/app/
|
|
# Résultat: Aucune importation ✅
|
|
```
|
|
|
|
**Justification**:
|
|
- ❌ Exemple de démo (non production)
|
|
- ❌ Jamais importé
|
|
- ✅ Peut être utile en dev (composant de test)
|
|
|
|
**Action**: **KEEP** mais déplacer
|
|
|
|
**Recommandation**: Créer une page `/app/dev/design-system/page.tsx`
|
|
```typescript
|
|
// app/dev/design-system/page.tsx
|
|
import DesignSystemShowcase from '@/components/examples/DesignSystemShowcase';
|
|
|
|
export default function DesignSystemPage() {
|
|
return <DesignSystemShowcase />;
|
|
}
|
|
```
|
|
|
|
**Protection en production**:
|
|
```typescript
|
|
// app/dev/layout.tsx
|
|
import { notFound } from 'next/navigation';
|
|
|
|
export default function DevLayout({ children }) {
|
|
if (process.env.NODE_ENV === 'production') {
|
|
notFound();
|
|
}
|
|
return <div className="dev-layout">{children}</div>;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
#### e) `/apps/frontend/app/demo-carte/page.tsx` et `/app/test-image/page.tsx`
|
|
|
|
**Vérification**: Pages de test/démo
|
|
|
|
**Action**: **EVALUATE**
|
|
|
|
**Questions**:
|
|
- Utilisées en développement ?
|
|
- Utilisées en démo client ?
|
|
- Utilisées pour tester des features ?
|
|
|
|
**Options**:
|
|
1. **DELETE** si inutiles
|
|
2. **PROTECT** si utiles en dev (comme ci-dessus)
|
|
3. **KEEP** si nécessaires pour démos
|
|
|
|
**Recommandation**: Déplacer dans `/app/dev/` et protéger en production
|
|
|
|
---
|
|
|
|
### 2. ✅ Composants potentiellement inutilisés
|
|
|
|
**Vérification requise**:
|
|
|
|
#### a) `src/components/DebugUser.tsx`
|
|
|
|
**Vérification**:
|
|
```bash
|
|
grep -r "DebugUser" apps/frontend/app/
|
|
# Si aucun résultat → DELETE
|
|
```
|
|
|
|
**Action**: **DELETE** si non utilisé
|
|
|
|
---
|
|
|
|
#### b) `src/components/CookieConsent.tsx`
|
|
|
|
**Vérification**:
|
|
```bash
|
|
grep -r "CookieConsent" apps/frontend/app/
|
|
```
|
|
|
|
**Action**:
|
|
- **KEEP** si importé dans `app/layout.tsx` (compliance RGPD)
|
|
- **DELETE** si jamais utilisé
|
|
|
|
---
|
|
|
|
## 📋 Plan d'action de nettoyage
|
|
|
|
### Phase 1: Corrections critiques (1-2 jours)
|
|
|
|
**Jour 1**:
|
|
- [ ] ✅ Activer TypeScript strict mode (`tsconfig.json`)
|
|
- [ ] ✅ Corriger les erreurs TypeScript résultantes
|
|
- [ ] ✅ Fixer l'incohérence des clés de token (`access_token` vs `accessToken`)
|
|
- [ ] ✅ Vérifier que l'authentification fonctionne partout
|
|
|
|
**Jour 2**:
|
|
- [ ] ✅ Extraire la logique métier de `app/dashboard/bookings/page.tsx`
|
|
- [ ] ✅ Créer hooks `useBookingFilters` et `usePagination`
|
|
- [ ] ✅ Créer utility `booking-status.ts`
|
|
- [ ] ✅ Tester les changements
|
|
|
|
### Phase 2: Optimisations (1 jour)
|
|
|
|
**Jour 3**:
|
|
- [ ] ✅ Implémenter pagination serveur pour bookings
|
|
- [ ] ✅ Standardiser pattern React Query + API client
|
|
- [ ] ✅ Refactorer `useBookings` hook
|
|
- [ ] ✅ Vérifier les performances
|
|
|
|
### Phase 3: Nettoyage code mort (demi-journée)
|
|
|
|
**Jour 4 matin**:
|
|
- [ ] ✅ Supprimer `/src/legacy-pages/`
|
|
- [ ] ✅ Investiguer et supprimer/migrer `app/rates/csv-search/`
|
|
- [ ] ✅ Migrer ou supprimer `src/pages/privacy.tsx` et `terms.tsx`
|
|
- [ ] ✅ Déplacer `DesignSystemShowcase` dans `/app/dev/`
|
|
- [ ] ✅ Protéger pages de dev/test en production
|
|
- [ ] ✅ Supprimer composants non utilisés (DebugUser, etc.)
|
|
|
|
### Phase 4: Documentation (demi-journée)
|
|
|
|
**Jour 4 après-midi**:
|
|
- [ ] ✅ Documenter les décisions dans `docs/decisions.md`
|
|
- [ ] ✅ Mettre à jour `docs/frontend/overview.md`
|
|
- [ ] ✅ Créer guide de contribution avec les patterns à suivre
|
|
- [ ] ✅ Mettre à jour CLAUDE.md avec les recommandations frontend
|
|
|
|
---
|
|
|
|
## 🚀 Commandes de vérification
|
|
|
|
### Détecter les imports inutilisés
|
|
|
|
```bash
|
|
cd apps/frontend
|
|
|
|
# Installer ts-prune
|
|
npm install --save-dev ts-prune
|
|
|
|
# Détecter exports non utilisés
|
|
npx ts-prune | grep -v "used in module"
|
|
```
|
|
|
|
### Détecter les fichiers jamais importés
|
|
|
|
```bash
|
|
# Fichiers TypeScript
|
|
find apps/frontend/src -name "*.ts" -o -name "*.tsx" | while read file; do
|
|
filename=$(basename "$file")
|
|
count=$(grep -r "from.*$filename" apps/frontend/src apps/frontend/app | wc -l)
|
|
if [ $count -eq 0 ]; then
|
|
echo "❌ Jamais importé: $file"
|
|
fi
|
|
done
|
|
```
|
|
|
|
### Vérifier les dépendances npm inutilisées
|
|
|
|
```bash
|
|
cd apps/frontend
|
|
npx depcheck
|
|
```
|
|
|
|
### Analyser la taille du bundle
|
|
|
|
```bash
|
|
cd apps/frontend
|
|
npm run build
|
|
npx @next/bundle-analyzer
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Métriques avant/après
|
|
|
|
### Avant nettoyage
|
|
|
|
| Métrique | Valeur |
|
|
|----------|--------|
|
|
| Strict TypeScript | ❌ Désactivé |
|
|
| Code mort (fichiers) | ~8-10 fichiers |
|
|
| Logique métier dans pages | ⚠️ Présente (3-4 pages) |
|
|
| Pattern fetching | ⚠️ 3 patterns différents |
|
|
| Token management | ❌ Incohérent |
|
|
| Performance bookings | ⚠️ 1000 items chargés |
|
|
| Score global | 65/100 |
|
|
|
|
### Après nettoyage (cible)
|
|
|
|
| Métrique | Valeur cible |
|
|
|----------|--------------|
|
|
| Strict TypeScript | ✅ Activé |
|
|
| Code mort (fichiers) | 0 ✅ |
|
|
| Logique métier dans pages | ✅ Séparée (hooks/utils) |
|
|
| Pattern fetching | ✅ Unifié (React Query) |
|
|
| Token management | ✅ Cohérent |
|
|
| Performance bookings | ✅ Pagination serveur |
|
|
| Score global | 90/100 ✅ |
|
|
|
|
---
|
|
|
|
## 🔗 Références
|
|
|
|
- [Architecture Frontend - docs/frontend/overview.md](./overview.md)
|
|
- [Structure Frontend - docs/frontend/structure.md](./structure.md)
|
|
- [CLAUDE.md - Guide complet](../../CLAUDE.md)
|
|
- [Architecture globale - docs/architecture.md](../architecture.md)
|
|
|
|
---
|
|
|
|
**Dernière mise à jour**: 2025-12-22
|
|
**Prochaine révision**: Après corrections Phase 1
|
|
**Responsable**: Frontend Team
|