Julien Froidefond c7a5b25501 feat: my team page
2025-08-27 10:53:11 +02:00
2025-08-27 10:53:11 +02:00
2025-08-27 10:53:11 +02:00
2025-08-26 07:10:26 +02:00
2025-08-27 10:53:11 +02:00
2025-08-27 10:53:11 +02:00
2025-08-20 15:43:24 +02:00
2025-08-27 09:56:55 +02:00
2025-08-27 09:56:44 +02:00
2025-08-20 15:43:24 +02:00
2025-08-26 07:10:39 +02:00
2025-08-20 15:43:24 +02:00
2025-08-20 15:43:24 +02:00

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 :

// 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 :

// 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

// 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

// 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>;
};
Description
No description provided
Readme 638 KiB
Languages
TypeScript 95.3%
JavaScript 2.6%
CSS 1.2%
PLpgSQL 0.7%
Dockerfile 0.2%