fix: improve skill category syncing and data structure
- Enhanced skill category syncing by ensuring id and name properties are included, boosting data integrity. - Cleaned up admin exports related to skill categories for better maintainability.
This commit is contained in:
166
README.md
Normal file
166
README.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# 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<Skill[]> {
|
||||
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<Skill[]>;
|
||||
}
|
||||
|
||||
export class SkillsService implements ISkillsService {
|
||||
constructor(private pool: Pool) {}
|
||||
|
||||
async getSkillsByCategory(category: string): Promise<Skill[]> {
|
||||
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 <div>{skills.map(skill => <SkillCard skill={skill} />)}</div>;
|
||||
};
|
||||
|
||||
// hooks/useSkills.ts
|
||||
export const useSkills = () => {
|
||||
const skillsService = useSkillsService();
|
||||
const [skills, setSkills] = useState<Skill[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
skillsService.getSkills().then(setSkills);
|
||||
}, []);
|
||||
|
||||
return { skills };
|
||||
};
|
||||
```
|
||||
|
||||
### ❌ Mauvais Pattern
|
||||
|
||||
```typescript
|
||||
// components/skills/SkillList.tsx
|
||||
export const SkillList = () => {
|
||||
const [skills, setSkills] = useState<Skill[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
// ❌ Appel HTTP direct dans le composant
|
||||
fetch('/api/skills').then(res => res.json()).then(setSkills);
|
||||
}, []);
|
||||
|
||||
return <div>{skills.map(skill => <SkillCard skill={skill} />)}</div>;
|
||||
};
|
||||
```
|
||||
Reference in New Issue
Block a user