Guide des Bonnes Pratiques de Développement TypeScript
🎯 Principes Généraux
⚠️ Intégrer les pratiques Angular dans le document.
Code de Qualité
- Ne JAMAIS pousser du code qui ne compile pas
- TOUJOURS tester localement avant commit
- Suivre les patterns existants du projet
- Respecter l'architecture Clean Architecture établie
Responsabilités
- Un commit = une fonctionnalité/fix
- Code review obligatoire pour les PR vers
master - Documentation des changements d'API
- Tests pour les nouvelles fonctionnalités
📝 Standards de Code TypeScript
Conventions de Nommage
TypeScript/JavaScript
// Classes et interfaces : PascalCase
export class UserService { }
export interface IUserConfiguration { }
// Méthodes et variables : camelCase
const getCurrentUser = async (userId: number) => { }
const userConfiguration: IUserConfiguration = { };
// Constantes : SCREAMING_SNAKE_CASE
const API_BASE_URL = 'http://localhost:5000';
Commentaires et Documentation
Commentaires TypeScript
/**
* Service pour gérer les configurations de modèles LLM côté client
* @example
* ```typescript
* const service = new ModelConfigurationService();
* const configs = await service.getUserConfigurations(userId);
* ```
*/
export class ModelConfigurationService {
/**
* Récupère les configurations d'un utilisateur
* @param userId - ID de l'utilisateur
* @returns Promise contenant la liste des configurations
*/
async getUserConfigurations(userId: number): Promise<ModelConfiguration[]> {
// Appel API avec gestion d'erreur
try {
const response = await this.httpClient.get(`/api/model-configurations/user/${userId}`);
return response.data;
} catch (error) {
// Log de l'erreur pour debug
console.error('Failed to fetch user configurations:', error);
throw new Error('Unable to load configurations');
}
}
}
🧪 Tests
Tests TypeScript avec Vitest
// ✅ CORRECT - Test de service TypeScript
import { describe, test, expect, vi, beforeEach } from 'vitest';
import { UserService } from '@/services/UserService';
import { ApiClient } from '@/services/ApiClient';
// Mock du client API
vi.mock('@/services/ApiClient');
describe('UserService', () => {
let userService: UserService;
let mockApiClient: vi.Mocked<ApiClient>;
beforeEach(() => {
mockApiClient = vi.mocked(new ApiClient());
userService = new UserService(mockApiClient);
vi.clearAllMocks();
});
test('getUserConfigurations récupère les configurations utilisateur', async () => {
// Arrange
const userId = 1;
const mockConfigurations = [
{ id: 1, name: 'Config 1', userId },
{ id: 2, name: 'Config 2', userId }
];
mockApiClient.get.mockResolvedValue({ data: mockConfigurations });
// Act
const result = await userService.getUserConfigurations(userId);
// Assert
expect(result).toEqual(mockConfigurations);
expect(mockApiClient.get).toHaveBeenCalledWith(`/api/users/${userId}/configurations`);
});
test('getUserConfigurations gère les erreurs API', async () => {
// Arrange
const userId = 1;
mockApiClient.get.mockRejectedValue(new Error('API Error'));
// Act & Assert
await expect(userService.getUserConfigurations(userId))
.rejects
.toThrow('Unable to load configurations');
});
});
Tests d'Intégration API
// ✅ CORRECT - Test d'intégration avec MSW
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { describe, test, expect, beforeAll, afterEach, afterAll } from 'vitest';
import { ApiClient } from '@/services/ApiClient';
// Mock du serveur API
const server = setupServer(
rest.get('/api/users/:userId/configurations', (req, res, ctx) => {
const { userId } = req.params;
return res(
ctx.status(200),
ctx.json([
{ id: 1, name: 'Test Config', userId: Number(userId) }
])
);
})
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
describe('ApiClient Integration', () => {
test('récupère les configurations utilisateur via API réelle', async () => {
// Arrange
const apiClient = new ApiClient('http://localhost:3000');
// Act
const response = await apiClient.get('/api/users/1/configurations');
// Assert
expect(response.data).toEqual([
{ id: 1, name: 'Test Config', userId: 1 }
]);
});
});
📖 Documentation
Documentation de Services TypeScript
/**
* UserService - Service pour gérer les utilisateurs et leurs configurations
*
* @example
* ```typescript
* const userService = new UserService(apiClient);
* const configs = await userService.getUserConfigurations(userId);
* ```
*/
export class UserService {
constructor(private apiClient: ApiClient) {}
/**
* Récupère les configurations d'un utilisateur
* @param userId - ID de l'utilisateur
* @returns Promise contenant la liste des configurations
* @throws {Error} Si l'utilisateur n'existe pas ou en cas d'erreur API
*/
async getUserConfigurations(userId: number): Promise<ModelConfiguration[]> {
try {
const response = await this.apiClient.get(`/api/users/${userId}/configurations`);
return response.data;
} catch (error) {
throw new Error('Unable to load configurations');
}
}
}
Documentation d'API avec TypeDoc
/**
* Interface pour la configuration d'un modèle LLM
* @interface ModelConfiguration
*/
export interface ModelConfiguration {
/** Identifiant unique de la configuration */
id: number;
/** Nom de la configuration */
name: string;
/** Nom de l'éditeur du modèle (ex: OpenAI, Google) */
editorName: string;
/** Nom du modèle (ex: gpt-4, gemini-pro) */
modelName: string;
/** Clé API pour accéder au modèle */
apiKey: string;
/** Prompt système optionnel */
systemPrompt?: string;
/** Date de création */
createdAt: Date;
/** Configuration active ou non */
isActive: boolean;
}
🆘 Aide et Ressources
Outils et Extensions Recommandés
- VS Code: TypeScript Hero, Auto Import, Better Comments
- Chrome Extensions: JSON Formatter, Postman Interceptor
- Testing: Vitest, Testing Library, MSW
- Linting: ESLint, Prettier, Husky
Ce guide est un document vivant. N'hésitez pas à proposer des améliorations via Pull Request.