# PeakSkills - Architecture et Organisation du Code ## Structure du Projet ``` peakSkills/ ├── app/ # Pages Next.js et routes API ├── clients/ # Clients HTTP pour les appels externes │ ├── base/ # Client HTTP de base │ └── domains/ # Clients par domaine métier ├── components/ # Composants React │ ├── ui/ # Composants UI réutilisables │ └── [feature]/ # Composants spécifiques aux features ├── services/ # Services métier ├── lib/ # Types et utilitaires partagés ├── hooks/ # Hooks React personnalisés ├── scripts/ # Scripts utilitaires │ └── migrations/ # Scripts de migration ├── data/ # Données statiques └── styles/ # Styles globaux ``` ## Règles de Structure ### 1. Clients HTTP (`clients/`) - Toute la logique d'appels HTTP doit être encapsulée dans des clients dédiés - Chaque domaine métier a son propre client (ex: `auth-client.ts`, `skills-client.ts`) - Les clients utilisent le client de base (`http-client.ts`) pour les appels - Les clients ne contiennent que la logique d'appel, pas de logique métier Exemple : ```typescript // clients/domains/skills-client.ts export class SkillsClient { constructor(private httpClient: HttpClient) {} async getSkills(): Promise { return this.httpClient.get("/api/skills"); } } ``` ### 2. Services Backend (`services/`) - SEULE couche autorisée à faire des requêtes PostgreSQL - Contiennent toute la logique métier et d'accès aux données - Implémentent une interface claire - Organisés par domaine métier - Gèrent les transactions - Valident les données - Utilisent le pool de connexion de database.ts Exemple : ```typescript // services/skills-service.ts export interface ISkillsService { getSkillsByCategory(category: string): Promise; } export class SkillsService implements ISkillsService { constructor(private pool: Pool) {} async getSkillsByCategory(category: string): Promise { const query = ` SELECT s.*, c.name as category_name FROM skills s JOIN skill_categories c ON s.category_id = c.id WHERE c.id = $1 `; const result = await this.pool.query(query, [category]); return result.rows; } } ``` ### 3. Composants (`components/`) - Composants UI réutilisables dans `ui/` - Composants spécifiques dans leur dossier feature - Export via `index.ts` - Utilisation de TypeScript (`.tsx`) ### 4. Pages (`app/`) - Structure selon le routing Next.js - Utilisation des composants - Pas de logique métier directe ### 5. Types (`lib/`) - Types partagés dans `types.ts` - Types spécifiques dans `[domain]-types.ts` - Interfaces commencent par "I" ## Bonnes Pratiques 1. **Séparation des Responsabilités** - Les composants gèrent l'UI - Les services gèrent la logique métier - Les clients gèrent les appels HTTP 2. **Typage** - Tout doit être typé - Utiliser des interfaces pour les contrats - Éviter `any` 3. **Organisation du Code** - Un fichier = une responsabilité - Export via `index.ts` - Documentation en français 4. **Tests** - Tests unitaires à côté du code - Tests d'intégration dans `__tests__` - Mocks dans `__mocks__` ## Patterns à Éviter ❌ Ne pas mettre de logique métier dans les composants ❌ Ne pas faire d'appels HTTP directs ❌ Ne pas dupliquer les types ❌ Ne pas mélanger les responsabilités ## Exemples ### ✅ Bon Pattern ```typescript // components/skills/SkillList.tsx export const SkillList = () => { const { skills } = useSkills(); // Hook personnalisé return
{skills.map(skill => )}
; }; // hooks/useSkills.ts export const useSkills = () => { const skillsService = useSkillsService(); const [skills, setSkills] = useState([]); useEffect(() => { skillsService.getSkills().then(setSkills); }, []); return { skills }; }; ``` ### ❌ Mauvais Pattern ```typescript // components/skills/SkillList.tsx export const SkillList = () => { const [skills, setSkills] = useState([]); useEffect(() => { // ❌ Appel HTTP direct dans le composant fetch('/api/skills').then(res => res.json()).then(setSkills); }, []); return
{skills.map(skill => )}
; }; ```