1546 lines
No EOL
37 KiB
Markdown
1546 lines
No EOL
37 KiB
Markdown
# 📖 Guide Complet du Système de Fixtures Veza
|
|
|
|
## Table des Matières
|
|
|
|
1. [Introduction](#-introduction)
|
|
2. [Installation et Configuration](#-installation-et-configuration)
|
|
3. [Concepts Fondamentaux](#-concepts-fondamentaux)
|
|
4. [Génération de Données](#-génération-de-données)
|
|
5. [Intégration avec les Services](#-intégration-avec-les-services)
|
|
6. [Scénarios de Test](#-scénarios-de-test)
|
|
7. [CLI et Outils](#-cli-et-outils)
|
|
8. [Cas d'Usage Avancés](#-cas-dusage-avancés)
|
|
9. [Dépannage](#-dépannage)
|
|
10. [Meilleures Pratiques](#-meilleures-pratiques)
|
|
|
|
## 🎯 Introduction
|
|
|
|
Le système de fixtures Veza est conçu pour fournir des données de test cohérentes, réalistes et reproductibles pour l'ensemble de la plateforme Veza. Il s'adresse aux développeurs, testeurs, et équipes DevOps qui ont besoin de données fiables pour leurs environnements de développement, test, et démonstration.
|
|
|
|
### Objectifs Principaux
|
|
|
|
- **Cohérence** : Données liées et cohérentes entre tous les services
|
|
- **Réalisme** : Données qui reflètent des cas d'usage réels
|
|
- **Reproductibilité** : Même seed = mêmes données
|
|
- **Scalabilité** : De 10 à 10,000+ entités
|
|
- **Simplicité** : Interface intuitive et documentation claire
|
|
|
|
### Public Cible
|
|
|
|
- **Développeurs Frontend/Backend** : Données pour développement local
|
|
- **Testeurs QA** : Scénarios de test automatisés
|
|
- **DevOps** : Intégration CI/CD et environnements
|
|
- **Product Managers** : Démos avec données réalistes
|
|
|
|
## 🔧 Installation et Configuration
|
|
|
|
### Prérequis Système
|
|
|
|
```bash
|
|
# Versions minimales requises
|
|
node --version # >= 18.0.0
|
|
npm --version # >= 8.0.0
|
|
psql --version # >= 13.0 (pour chat-server)
|
|
redis-cli --version # >= 6.0 (pour streaming)
|
|
```
|
|
|
|
### Installation Automatique
|
|
|
|
```bash
|
|
# Cloner le projet
|
|
git clone https://github.com/your-org/veza-platform.git
|
|
cd veza-platform/fixtures
|
|
|
|
# Installation complète
|
|
./tools/scripts/install.sh
|
|
|
|
# Vérification
|
|
npm run status
|
|
```
|
|
|
|
### Installation Manuelle
|
|
|
|
```bash
|
|
# Installation des dépendances
|
|
npm install
|
|
|
|
# Build du système
|
|
npm run build
|
|
|
|
# Configuration environnement
|
|
cp ../env.example .env
|
|
nano .env
|
|
```
|
|
|
|
### Configuration Détaillée
|
|
|
|
#### Variables d'Environnement
|
|
|
|
```bash
|
|
# .env - Configuration principale
|
|
# Base de données
|
|
DB_HOST=localhost
|
|
DB_PORT=5432
|
|
DB_USERNAME=veza
|
|
DB_PASSWORD=veza_password
|
|
DB_MAIN=veza_dev
|
|
DB_CHAT=veza_chat
|
|
DB_TEST=veza_test
|
|
|
|
# Redis
|
|
REDIS_HOST=localhost
|
|
REDIS_PORT=6379
|
|
REDIS_PASSWORD=
|
|
|
|
# Fixtures
|
|
FIXTURES_SEED=veza-platform-2025
|
|
FIXTURES_LOCALE=fr
|
|
```
|
|
|
|
#### Configuration Avancée
|
|
|
|
```typescript
|
|
// fixtures/environments/custom.ts
|
|
export const customConfig: Partial<FixtureConfig> = {
|
|
generation: {
|
|
users: {
|
|
count: 150,
|
|
adminCount: 5,
|
|
artistCount: 30,
|
|
producerCount: 15,
|
|
},
|
|
audio: {
|
|
trackCount: 750,
|
|
albumCount: 75,
|
|
playlistCount: 150,
|
|
}
|
|
},
|
|
services: {
|
|
web: { port: 3001 },
|
|
chat: { port: 8081, wsPort: 8082 }
|
|
}
|
|
}
|
|
```
|
|
|
|
### Vérification de l'Installation
|
|
|
|
```bash
|
|
# Test complet du système
|
|
npm run validate
|
|
|
|
# Diagnostic détaillé
|
|
./tools/scripts/install.sh doctor
|
|
|
|
# Génération de test
|
|
npm run generate -- --env development --dry-run
|
|
```
|
|
|
|
## 🧠 Concepts Fondamentaux
|
|
|
|
### Architecture en Couches
|
|
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ Interface Layer │
|
|
│ CLI Tools | Programmatic API │
|
|
├─────────────────────────────────────┤
|
|
│ Scenario Layer │
|
|
│ User Journey | Performance | E2E │
|
|
├─────────────────────────────────────┤
|
|
│ Service Integration │
|
|
│ Web | Chat | Stream | Backend │
|
|
├─────────────────────────────────────┤
|
|
│ Core Layer │
|
|
│ Generators | Relations | Validation │
|
|
├─────────────────────────────────────┤
|
|
│ Configuration Layer │
|
|
│ Environments | Seeds | Settings │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
### Entités Principales
|
|
|
|
#### Utilisateurs
|
|
```typescript
|
|
interface User {
|
|
id: string // UUID unique
|
|
username: string // Nom d'utilisateur unique
|
|
email: string // Email unique
|
|
role: UserRole // admin | artist | producer | user
|
|
status: UserStatus // active | inactive | suspended
|
|
stats: UserStats // Statistiques d'activité
|
|
preferences: UserPreferences // Préférences utilisateur
|
|
}
|
|
```
|
|
|
|
#### Contenu Audio
|
|
```typescript
|
|
interface Audio {
|
|
id: string // UUID unique
|
|
title: string // Titre du morceau
|
|
artist: string // Nom de l'artiste
|
|
genre: AudioGenre // Genre musical
|
|
metadata: AudioMetadata // Métadonnées techniques
|
|
stats: AudioStats // Statistiques d'écoute
|
|
uploadedById: string // ID de l'utilisateur
|
|
}
|
|
```
|
|
|
|
#### Conversations
|
|
```typescript
|
|
interface Conversation {
|
|
id: string // UUID unique
|
|
type: ConversationType // direct | group | channel
|
|
participantIds: string[] // IDs des participants
|
|
lastMessageId?: string // ID du dernier message
|
|
lastActivityAt: Date // Dernière activité
|
|
}
|
|
```
|
|
|
|
### Système de Relations
|
|
|
|
Le `DataRelationManager` maintient automatiquement la cohérence entre les entités :
|
|
|
|
```typescript
|
|
// Exemple de relations automatiques
|
|
const user = UserGenerator.generate()
|
|
const track = AudioGenerator.generate({ uploadedById: user.id })
|
|
const playlist = AudioGenerator.generatePlaylist({
|
|
createdById: user.id,
|
|
trackIds: [track.id]
|
|
})
|
|
|
|
// Le système maintient automatiquement :
|
|
// - user.stats.tracksUploaded++
|
|
// - user.stats.playlistsCreated++
|
|
// - Relations bidirectionnelles
|
|
```
|
|
|
|
## 📊 Génération de Données
|
|
|
|
### Générateurs Disponibles
|
|
|
|
#### UserGenerator
|
|
|
|
```typescript
|
|
import { UserGenerator } from '@veza/fixtures'
|
|
|
|
// Utilisateur basique
|
|
const user = UserGenerator.generate()
|
|
|
|
// Utilisateur avec options
|
|
const artist = UserGenerator.generate({
|
|
role: 'artist',
|
|
isVerified: true,
|
|
withAvatar: true,
|
|
withBio: true
|
|
})
|
|
|
|
// Utilisateurs spécialisés
|
|
const admin = UserGenerator.generateAdmin()
|
|
const producer = UserGenerator.generateProducer()
|
|
const testUser = UserGenerator.generateTestUser('john_doe')
|
|
|
|
// Génération en lot
|
|
const users = UserGenerator.generateBatch(50)
|
|
|
|
// Distribution réaliste
|
|
const distributedUsers = UserGenerator.generateWithDistribution()
|
|
```
|
|
|
|
**Options Avancées :**
|
|
|
|
```typescript
|
|
const customUser = UserGenerator.generate({
|
|
role: 'artist',
|
|
status: 'active',
|
|
isVerified: true,
|
|
emailVerified: true,
|
|
withAvatar: true,
|
|
withBio: true,
|
|
withStats: true,
|
|
createdAt: new Date('2024-01-01'),
|
|
lastSeenAt: new Date()
|
|
})
|
|
```
|
|
|
|
#### AudioGenerator
|
|
|
|
```typescript
|
|
import { AudioGenerator } from '@veza/fixtures'
|
|
|
|
// Track simple
|
|
const track = AudioGenerator.generate()
|
|
|
|
// Track avec genre spécifique
|
|
const electroTrack = AudioGenerator.generate({
|
|
genre: 'electronic',
|
|
isPopular: true,
|
|
uploadedById: artist.id
|
|
})
|
|
|
|
// Album complet
|
|
const album = AudioGenerator.generateAlbum(12, {
|
|
genre: 'rock',
|
|
uploadedById: artist.id
|
|
})
|
|
|
|
// Playlist thématique
|
|
const workoutPlaylist = AudioGenerator.generatePlaylist({
|
|
theme: 'workout',
|
|
trackCount: 25,
|
|
createdById: user.id,
|
|
visibility: 'public'
|
|
})
|
|
|
|
// Collection par genre
|
|
const jazzCollection = AudioGenerator.generateGenreCollection('jazz', 100)
|
|
```
|
|
|
|
**Contenu Utilisateur :**
|
|
|
|
```typescript
|
|
// Contenu basé sur le rôle
|
|
const artistContent = AudioGenerator.generateUserContent(artist.id, 'artist')
|
|
// Retourne : { tracks: Audio[], albums: Album[], playlists: Playlist[] }
|
|
|
|
const userContent = AudioGenerator.generateUserContent(user.id, 'user')
|
|
// Retourne : { tracks: [], albums: [], playlists: Playlist[] }
|
|
```
|
|
|
|
#### ConversationGenerator
|
|
|
|
```typescript
|
|
import { ConversationGenerator } from '@veza/fixtures'
|
|
|
|
// Conversation directe
|
|
const directChat = ConversationGenerator.generateConversation({
|
|
type: 'direct',
|
|
participantIds: [user1.id, user2.id],
|
|
messageCount: 25
|
|
})
|
|
|
|
// Groupe de discussion
|
|
const groupChat = ConversationGenerator.generateConversation({
|
|
type: 'group',
|
|
participantIds: [user1.id, user2.id, user3.id, user4.id],
|
|
messageCount: 100,
|
|
timeSpan: 'month'
|
|
})
|
|
|
|
// Canal public
|
|
const channel = ConversationGenerator.generateConversation({
|
|
type: 'channel',
|
|
participantIds: userIds, // Beaucoup d'utilisateurs
|
|
isPrivate: false,
|
|
messageCount: 500
|
|
})
|
|
|
|
// Messages avec relations
|
|
const messages = ConversationGenerator.generateMessages(
|
|
conversation.id,
|
|
conversation.participantIds,
|
|
50,
|
|
{ timeSpan: 'week' }
|
|
)
|
|
```
|
|
|
|
**Scénarios Pré-définis :**
|
|
|
|
```typescript
|
|
// Scénario de collaboration studio
|
|
const studioScenario = ConversationGenerator.generateScenario(
|
|
ConversationGenerator.SCENARIOS[0], // 'Studio Collaboration'
|
|
[producer.id, artist1.id, artist2.id, engineer.id]
|
|
)
|
|
|
|
// Autres scénarios disponibles :
|
|
// - Music Discovery
|
|
// - Event Planning
|
|
// - Producer Feedback
|
|
```
|
|
|
|
### Dataset Complet avec Relations
|
|
|
|
```typescript
|
|
import { DataRelationManager } from '@veza/fixtures'
|
|
|
|
// Génération complète avec relations cohérentes
|
|
const dataset = DataRelationManager.generateCompleteDataset()
|
|
|
|
console.log(dataset)
|
|
// {
|
|
// users: User[],
|
|
// tracks: Audio[],
|
|
// playlists: Playlist[],
|
|
// conversations: Conversation[],
|
|
// messages: Message[]
|
|
// }
|
|
|
|
// Validation des relations
|
|
const validation = DataRelationManager.validateRelations()
|
|
if (!validation.isValid) {
|
|
console.error('Erreurs de relation:', validation.errors)
|
|
}
|
|
|
|
// Statistiques
|
|
const stats = DataRelationManager.getStatistics()
|
|
console.log('Statistiques:', stats)
|
|
```
|
|
|
|
### Personnalisation des Générateurs
|
|
|
|
#### Configuration Faker
|
|
|
|
```typescript
|
|
import { vezaFaker } from '@veza/fixtures'
|
|
|
|
// Personnaliser les noms d'artistes
|
|
vezaFaker.music.artistName = () => {
|
|
const prefixes = ['DJ', 'MC', 'Lil', 'Big']
|
|
const names = ['Beats', 'Flow', 'Sound', 'Vibe']
|
|
return `${vezaFaker.helpers.arrayElement(prefixes)} ${vezaFaker.helpers.arrayElement(names)}`
|
|
}
|
|
|
|
// Personnaliser les titres de morceaux
|
|
vezaFaker.music.songTitle = () => {
|
|
const adjectives = ['Electric', 'Cosmic', 'Urban', 'Mystic']
|
|
const nouns = ['Dreams', 'Nights', 'Vibes', 'Echoes']
|
|
return `${vezaFaker.helpers.arrayElement(adjectives)} ${vezaFaker.helpers.arrayElement(nouns)}`
|
|
}
|
|
```
|
|
|
|
#### Hooks de Génération
|
|
|
|
```typescript
|
|
// Hook après génération d'utilisateur
|
|
DataRelationManager.onUserGenerated((user) => {
|
|
console.log(`✅ Utilisateur créé: ${user.username} (${user.role})`)
|
|
|
|
// Logique personnalisée
|
|
if (user.role === 'artist') {
|
|
// Créer automatiquement du contenu pour les artistes
|
|
const content = AudioGenerator.generateUserContent(user.id, 'artist')
|
|
console.log(`🎵 ${content.tracks.length} tracks créées pour ${user.username}`)
|
|
}
|
|
})
|
|
```
|
|
|
|
## 🔗 Intégration avec les Services
|
|
|
|
### Web Service (Frontend)
|
|
|
|
#### Configuration MSW
|
|
|
|
```typescript
|
|
import { WebFixtures } from '@veza/fixtures'
|
|
|
|
// Initialisation avec utilisateur spécifique
|
|
await WebFixtures.initialize(userId)
|
|
|
|
// Récupération des handlers MSW
|
|
const handlers = WebFixtures.getMSWHandlers()
|
|
|
|
// Intégration avec MSW
|
|
import { setupServer } from 'msw/node'
|
|
const server = setupServer(...handlers)
|
|
```
|
|
|
|
#### État d'Authentification
|
|
|
|
```typescript
|
|
// L'état d'auth est automatiquement configuré dans localStorage
|
|
const currentUser = WebFixtures.getCurrentUser()
|
|
const authToken = WebFixtures.getAuthToken()
|
|
|
|
// Données disponibles dans localStorage :
|
|
// - 'auth-storage' : État Zustand
|
|
// - 'access_token' : Token JWT
|
|
// - 'user-preferences' : Préférences utilisateur
|
|
// - 'recent-activity' : Activité récente
|
|
```
|
|
|
|
#### Endpoints Mockés
|
|
|
|
```typescript
|
|
// Endpoints automatiquement disponibles :
|
|
POST /api/auth/login
|
|
POST /api/auth/register
|
|
POST /api/auth/refresh
|
|
GET /api/users/me
|
|
PUT /api/users/me
|
|
GET /api/dashboard
|
|
GET /api/tracks
|
|
GET /api/playlists
|
|
GET /api/conversations
|
|
GET /api/search
|
|
```
|
|
|
|
### Chat Server (Backend)
|
|
|
|
#### Configuration Base de Données
|
|
|
|
```typescript
|
|
import { ChatServerFixtures } from '@veza/fixtures'
|
|
|
|
// Initialisation des connexions
|
|
await ChatServerFixtures.initialize()
|
|
|
|
// Seeding de la base de données PostgreSQL
|
|
await ChatServerFixtures.seedDatabase()
|
|
|
|
// Seeding du cache Redis
|
|
await ChatServerFixtures.seedRedis()
|
|
|
|
// Vérification de santé
|
|
const health = await ChatServerFixtures.healthCheck()
|
|
console.log(health) // { database: true, redis: true, dataConsistency: true }
|
|
```
|
|
|
|
#### Données Générées
|
|
|
|
```typescript
|
|
// Base de données PostgreSQL :
|
|
// - Table users (avec profils complets)
|
|
// - Table conversations (avec métadonnées)
|
|
// - Table conversation_members (relations)
|
|
// - Table messages (avec contenu réaliste)
|
|
|
|
// Cache Redis :
|
|
// - Sessions utilisateur actives
|
|
// - Métadonnées de conversations
|
|
// - Indicateurs de frappe
|
|
// - Statuts de livraison des messages
|
|
```
|
|
|
|
#### Événements WebSocket
|
|
|
|
```typescript
|
|
// Génération d'événements temps réel
|
|
const events = ChatServerFixtures.generateWebSocketEvents()
|
|
|
|
events.forEach(event => {
|
|
console.log(`${event.type}: ${event.data}`)
|
|
})
|
|
|
|
// Types d'événements :
|
|
// - user_connected / user_disconnected
|
|
// - message_sent / message_received
|
|
// - typing_start / typing_stop
|
|
// - conversation_joined / conversation_left
|
|
```
|
|
|
|
### Stream Server (Backend)
|
|
|
|
#### Sessions de Streaming
|
|
|
|
```typescript
|
|
import { StreamServerFixtures } from '@veza/fixtures'
|
|
|
|
// Initialisation
|
|
await StreamServerFixtures.initialize()
|
|
|
|
// Seeding des données de streaming
|
|
await StreamServerFixtures.seedStreamingData()
|
|
|
|
// Génération de session
|
|
const session = StreamServerFixtures.generateStreamingSession(
|
|
user.id,
|
|
track.id
|
|
)
|
|
|
|
console.log(session)
|
|
// {
|
|
// id: 'stream_session_id',
|
|
// userId: 'user_id',
|
|
// trackId: 'track_id',
|
|
// quality: 'high',
|
|
// bitrate: 320,
|
|
// startTime: Date,
|
|
// device: { type: 'desktop', os: 'macOS' },
|
|
// network: { type: 'wifi', speed: 50 },
|
|
// status: 'active'
|
|
// }
|
|
```
|
|
|
|
#### Analytics et Métriques
|
|
|
|
```typescript
|
|
// Analytics de streaming
|
|
const analytics = StreamServerFixtures.generateStreamingAnalytics()
|
|
|
|
console.log(analytics)
|
|
// {
|
|
// overview: { totalSessions, activeSessions, totalDuration },
|
|
// byQuality: [{ quality: 'high', count: 150 }],
|
|
// byPlatform: [{ platform: 'web', count: 300 }],
|
|
// realtime: { currentListeners, peakListeners, bandwidth }
|
|
// }
|
|
```
|
|
|
|
#### Queue de Traitement
|
|
|
|
```typescript
|
|
// Jobs de traitement audio
|
|
const jobs = StreamServerFixtures.generateAudioProcessingJobs(tracks)
|
|
|
|
jobs.forEach(job => {
|
|
console.log(`${job.type}: ${job.status} (${job.progress}%)`)
|
|
})
|
|
|
|
// Types de jobs :
|
|
// - transcode : Conversion de format
|
|
// - analyze : Analyse audio
|
|
// - thumbnail : Génération de miniatures
|
|
// - waveform : Génération de waveform
|
|
// - metadata : Extraction de métadonnées
|
|
```
|
|
|
|
## 🎬 Scénarios de Test
|
|
|
|
### Scénario d'Onboarding
|
|
|
|
```typescript
|
|
import { NewUserOnboardingScenario } from '@veza/fixtures'
|
|
|
|
// Configuration du scénario
|
|
const context = await NewUserOnboardingScenario.setup()
|
|
|
|
console.log('Nouvel utilisateur:', context.user.username)
|
|
console.log('Étapes d\'onboarding:', context.initialData.onboardingSteps.length)
|
|
console.log('Tracks recommandées:', context.initialData.recommendedTracks.length)
|
|
|
|
// Simulation de complétion
|
|
const completion = NewUserOnboardingScenario.simulateOnboardingCompletion(context)
|
|
|
|
console.log('Étapes complétées:', completion.completedSteps.length)
|
|
console.log('Première playlist:', completion.generatedContent.firstPlaylist.title)
|
|
|
|
// Validation
|
|
const validation = NewUserOnboardingScenario.validateScenario(context)
|
|
console.log('Validation:', validation.isValid ? '✅ PASS' : '❌ FAIL')
|
|
```
|
|
|
|
#### Étapes d'Onboarding Générées
|
|
|
|
1. **Bienvenue** - Message d'accueil personnalisé
|
|
2. **Vérification Email** - Code de vérification
|
|
3. **Profil** - Complétion du profil utilisateur
|
|
4. **Préférences Musicales** - Sélection des genres
|
|
5. **Première Playlist** - Création d'une playlist
|
|
6. **Communauté** - Rejoindre les discussions
|
|
|
|
### Scénario de Charge Haute
|
|
|
|
```typescript
|
|
import { HighLoadScenario } from '@veza/fixtures'
|
|
|
|
// Configuration du test de charge
|
|
const context = await HighLoadScenario.setup({
|
|
name: 'Heavy Load Test',
|
|
peakUsers: 1000,
|
|
duration: 600, // 10 minutes
|
|
expectedThroughput: 500 // req/s
|
|
})
|
|
|
|
console.log(`Test de charge: ${context.loadProfile.peakUsers} utilisateurs`)
|
|
console.log(`Sessions streaming: ${context.streamingSessions.length}`)
|
|
console.log(`Flood de messages: ${context.messageFlood.length}`)
|
|
|
|
// Simulation d'exécution
|
|
const simulation = HighLoadScenario.simulateLoadTest(context)
|
|
|
|
console.log('Plan d\'exécution:', simulation.executionPlan.length, 'phases')
|
|
console.log('Résultats attendus:', simulation.expectedResults.throughput)
|
|
```
|
|
|
|
#### Métriques de Performance
|
|
|
|
```typescript
|
|
// Métriques système attendues
|
|
const metrics = context.systemMetrics
|
|
|
|
console.log('Charge CPU attendue:', metrics.expectedLoad.cpuUsage, '%')
|
|
console.log('Utilisation mémoire:', metrics.expectedLoad.memoryUsage, '%')
|
|
console.log('Connexions DB:', metrics.expectedLoad.databaseConnections)
|
|
console.log('Streams concurrent:', metrics.performanceTargets.concurrentStreams)
|
|
```
|
|
|
|
### Scénario d'Intégration Cross-Service
|
|
|
|
```typescript
|
|
import { CrossServiceCommunicationScenario } from '@veza/fixtures'
|
|
|
|
// Configuration du test d'intégration
|
|
const context = await CrossServiceCommunicationScenario.setup()
|
|
|
|
console.log('Services testés:', context.testFlow.services)
|
|
console.log('Participants:', context.participants.length)
|
|
console.log('Interactions:', context.expectedInteractions.length)
|
|
|
|
// Simulation d'exécution
|
|
const simulation = await CrossServiceCommunicationScenario.simulateIntegrationTest(context)
|
|
|
|
console.log('Résultats d\'exécution:', simulation.executionResults.length)
|
|
console.log('Métriques de performance:', simulation.performanceMetrics.length)
|
|
console.log('Rapport de cohérence:', simulation.dataConsistencyReport)
|
|
```
|
|
|
|
#### Parcours Utilisateur Généré
|
|
|
|
```typescript
|
|
// Génération d'un parcours utilisateur réaliste
|
|
const { journey, expectedDataFlow, validationPoints } =
|
|
CrossServiceCommunicationScenario.generateUserJourney()
|
|
|
|
journey.forEach((step, index) => {
|
|
console.log(`${index + 1}. ${step.description}`)
|
|
console.log(` Services: ${step.expectedServices.join(', ')}`)
|
|
console.log(` Durée: ${step.duration}ms`)
|
|
})
|
|
|
|
// Exemple de parcours :
|
|
// 1. User logs in via web interface
|
|
// Services: web, backend-api
|
|
// Durée: 2000ms
|
|
// 2. Load user dashboard with personalized content
|
|
// Services: web, backend-api, stream-server
|
|
// Durée: 1500ms
|
|
// 3. Start streaming an audio track
|
|
// Services: web, stream-server
|
|
// Durée: 500ms
|
|
```
|
|
|
|
## 🛠️ CLI et Outils
|
|
|
|
### Commandes Principales
|
|
|
|
#### Generate - Génération de Données
|
|
|
|
```bash
|
|
# Génération basique
|
|
veza-fixtures generate
|
|
|
|
# Environnement spécifique
|
|
veza-fixtures generate --env staging
|
|
|
|
# Taille personnalisée
|
|
veza-fixtures generate --users 500 --tracks 2000 --conversations 100
|
|
|
|
# Avec seed spécifique
|
|
veza-fixtures generate --seed "my-custom-seed-2025"
|
|
|
|
# Format d'export
|
|
veza-fixtures generate --format sql --output ./exports/staging
|
|
|
|
# Mode dry-run (simulation)
|
|
veza-fixtures generate --dry-run
|
|
```
|
|
|
|
#### Seed - Population des Services
|
|
|
|
```bash
|
|
# Tous les services
|
|
veza-fixtures seed --service all
|
|
|
|
# Service spécifique
|
|
veza-fixtures seed --service web
|
|
|
|
# Avec nettoyage préalable
|
|
veza-fixtures seed --clean --service chat-server
|
|
|
|
# Avec validation
|
|
veza-fixtures seed --service all --validate
|
|
|
|
# Environnement spécifique
|
|
veza-fixtures seed --env staging --service stream-server
|
|
```
|
|
|
|
#### Validate - Validation des Données
|
|
|
|
```bash
|
|
# Validation complète
|
|
veza-fixtures validate
|
|
|
|
# Relations seulement
|
|
veza-fixtures validate --check-relations
|
|
|
|
# Performance seulement
|
|
veza-fixtures validate --check-performance
|
|
|
|
# Service spécifique
|
|
veza-fixtures validate --service chat-server
|
|
|
|
# Avec rapport
|
|
veza-fixtures validate --report validation-report.json
|
|
```
|
|
|
|
#### Clean - Nettoyage
|
|
|
|
```bash
|
|
# Nettoyage interactif
|
|
veza-fixtures clean
|
|
|
|
# Service spécifique
|
|
veza-fixtures clean --service web
|
|
|
|
# Force (sans confirmation)
|
|
veza-fixtures clean --service all --force
|
|
|
|
# Environnement spécifique
|
|
veza-fixtures clean --env testing --force
|
|
```
|
|
|
|
#### Scenario - Gestion des Scénarios
|
|
|
|
```bash
|
|
# Lister les scénarios
|
|
veza-fixtures scenario --list
|
|
|
|
# Lancer un scénario
|
|
veza-fixtures scenario --run onboarding
|
|
|
|
# Créer un nouveau scénario
|
|
veza-fixtures scenario --create my-scenario --interactive
|
|
|
|
# Scénarios disponibles :
|
|
# - onboarding : Parcours nouvel utilisateur
|
|
# - high-load : Test de charge haute
|
|
# - integration : Test d'intégration cross-service
|
|
```
|
|
|
|
#### Status - État du Système
|
|
|
|
```bash
|
|
# État basique
|
|
veza-fixtures status
|
|
|
|
# Informations détaillées
|
|
veza-fixtures status --verbose
|
|
|
|
# Environnement spécifique
|
|
veza-fixtures status --env staging
|
|
```
|
|
|
|
### Options Globales
|
|
|
|
```bash
|
|
# Toutes les commandes supportent :
|
|
--env <environment> # Environnement (development, testing, staging, demo)
|
|
--verbose # Mode verbeux
|
|
--help # Aide de la commande
|
|
```
|
|
|
|
### Scripts NPM
|
|
|
|
```bash
|
|
# Scripts disponibles dans package.json
|
|
npm run generate # Génération avec options par défaut
|
|
npm run seed # Seeding de tous les services
|
|
npm run validate # Validation complète
|
|
npm run clean # Nettoyage interactif
|
|
npm run status # État du système
|
|
|
|
# Scripts avec fixtures
|
|
npm run dev:with-fixtures # Développement avec données
|
|
npm run test:with-fixtures # Tests avec données fraîches
|
|
npm run e2e:with-fixtures # Tests E2E avec données
|
|
```
|
|
|
|
### Configuration CLI
|
|
|
|
```bash
|
|
# Configuration globale via variables d'environnement
|
|
export FIXTURES_ENV=staging
|
|
export FIXTURES_SEED=my-seed-2025
|
|
export FIXTURES_LOCALE=en
|
|
|
|
# Ou via fichier .env
|
|
echo "FIXTURES_ENV=staging" >> .env
|
|
```
|
|
|
|
## 🚀 Cas d'Usage Avancés
|
|
|
|
### Développement Local
|
|
|
|
#### Setup Rapide
|
|
|
|
```bash
|
|
# Terminal 1 : Services infrastructure
|
|
docker-compose up postgres redis
|
|
|
|
# Terminal 2 : Fixtures
|
|
cd fixtures
|
|
npm run generate -- --env development
|
|
npm run seed -- --service all
|
|
|
|
# Terminal 3 : Application
|
|
cd ../apps/web
|
|
npm run dev
|
|
```
|
|
|
|
#### Workflow de Développement
|
|
|
|
```typescript
|
|
// scripts/dev-setup.js
|
|
import { quickStart } from '@veza/fixtures'
|
|
|
|
async function setupDevEnvironment() {
|
|
console.log('🚀 Configuration environnement de développement...')
|
|
|
|
const result = await quickStart({
|
|
environment: 'development',
|
|
services: ['web', 'chat'],
|
|
scenario: 'onboarding'
|
|
})
|
|
|
|
console.log('✅ Environnement prêt!')
|
|
console.log(`📊 ${result.stats.users} utilisateurs générés`)
|
|
console.log(`🎵 ${result.stats.tracks} tracks disponibles`)
|
|
|
|
return result
|
|
}
|
|
|
|
setupDevEnvironment()
|
|
```
|
|
|
|
### Tests Automatisés
|
|
|
|
#### Tests d'Intégration
|
|
|
|
```typescript
|
|
// tests/integration/user-flow.test.ts
|
|
import { WebFixtures, ChatServerFixtures } from '@veza/fixtures'
|
|
import { NewUserOnboardingScenario } from '@veza/fixtures'
|
|
|
|
describe('User Flow Integration', () => {
|
|
beforeAll(async () => {
|
|
// Setup fixtures
|
|
await WebFixtures.initialize()
|
|
await ChatServerFixtures.initialize()
|
|
})
|
|
|
|
it('should complete user onboarding flow', async () => {
|
|
const scenario = await NewUserOnboardingScenario.setup()
|
|
|
|
// Test login
|
|
const response = await fetch('/api/auth/login', {
|
|
method: 'POST',
|
|
body: JSON.stringify(scenario.testData.loginCredentials)
|
|
})
|
|
|
|
expect(response.ok).toBe(true)
|
|
|
|
// Test dashboard load
|
|
const dashboard = await fetch('/api/dashboard')
|
|
const data = await dashboard.json()
|
|
|
|
expect(data.user.username).toBe(scenario.user.username)
|
|
expect(data.recommendations).toHaveLength(20)
|
|
})
|
|
})
|
|
```
|
|
|
|
#### Tests de Performance
|
|
|
|
```typescript
|
|
// tests/performance/load.test.ts
|
|
import { HighLoadScenario } from '@veza/fixtures'
|
|
|
|
describe('Performance Tests', () => {
|
|
it('should handle high concurrent load', async () => {
|
|
const scenario = await HighLoadScenario.setup({
|
|
peakUsers: 500,
|
|
duration: 300
|
|
})
|
|
|
|
const startTime = Date.now()
|
|
|
|
// Simulate concurrent requests
|
|
const promises = scenario.concurrentUsers.map(user =>
|
|
simulateUserSession(user)
|
|
)
|
|
|
|
const results = await Promise.all(promises)
|
|
const duration = Date.now() - startTime
|
|
|
|
expect(duration).toBeLessThan(scenario.loadProfile.duration * 1000)
|
|
expect(results.filter(r => r.success).length).toBeGreaterThan(450) // 90% success rate
|
|
})
|
|
})
|
|
```
|
|
|
|
### Démos et Présentations
|
|
|
|
#### Dataset de Démo
|
|
|
|
```bash
|
|
# Génération de données de démo professionnelles
|
|
veza-fixtures generate \
|
|
--env demo \
|
|
--users 30 \
|
|
--tracks 100 \
|
|
--conversations 10 \
|
|
--seed "demo-2025-client-presentation"
|
|
|
|
# Seeding pour démo
|
|
veza-fixtures seed --service all --env demo
|
|
```
|
|
|
|
#### Scénarios de Démo
|
|
|
|
```typescript
|
|
// scripts/demo-setup.js
|
|
import {
|
|
UserGenerator,
|
|
AudioGenerator,
|
|
ConversationGenerator,
|
|
DataRelationManager
|
|
} from '@veza/fixtures'
|
|
|
|
async function createDemoScenario() {
|
|
// Créer des personnages de démo
|
|
const ceo = UserGenerator.generate({
|
|
role: 'admin',
|
|
firstName: 'Marie',
|
|
lastName: 'Dubois',
|
|
username: 'marie_ceo',
|
|
isVerified: true
|
|
})
|
|
|
|
const artist = UserGenerator.generate({
|
|
role: 'artist',
|
|
firstName: 'Alex',
|
|
lastName: 'Martin',
|
|
username: 'alex_music',
|
|
isVerified: true
|
|
})
|
|
|
|
// Créer du contenu de démo
|
|
const album = AudioGenerator.generateAlbum(8, {
|
|
uploadedById: artist.id,
|
|
genre: 'electronic'
|
|
})
|
|
|
|
// Créer une conversation de démo
|
|
const conversation = ConversationGenerator.generateConversation({
|
|
type: 'group',
|
|
participantIds: [ceo.id, artist.id],
|
|
messageCount: 15
|
|
})
|
|
|
|
console.log('✅ Scénario de démo créé')
|
|
console.log(`👤 CEO: ${ceo.username}`)
|
|
console.log(`🎵 Artiste: ${artist.username}`)
|
|
console.log(`💿 Album: ${album.title} (${album.tracks.length} tracks)`)
|
|
}
|
|
```
|
|
|
|
### Environnements Multi-Stages
|
|
|
|
#### Configuration par Environnement
|
|
|
|
```typescript
|
|
// fixtures/environments/index.ts
|
|
export const environments = {
|
|
development: {
|
|
users: { count: 50 },
|
|
audio: { trackCount: 200 },
|
|
database: { host: 'localhost' }
|
|
},
|
|
|
|
testing: {
|
|
users: { count: 20 },
|
|
audio: { trackCount: 50 },
|
|
database: { host: 'test-db' }
|
|
},
|
|
|
|
staging: {
|
|
users: { count: 200 },
|
|
audio: { trackCount: 1000 },
|
|
database: { host: 'staging-db.example.com' }
|
|
},
|
|
|
|
production: {
|
|
// Pas de fixtures en production
|
|
enabled: false
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Déploiement Automatisé
|
|
|
|
```yaml
|
|
# .github/workflows/deploy-staging.yml
|
|
name: Deploy to Staging
|
|
on:
|
|
push:
|
|
branches: [develop]
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup fixtures
|
|
working-directory: fixtures
|
|
run: |
|
|
npm ci
|
|
npm run build
|
|
|
|
- name: Seed staging data
|
|
run: |
|
|
npm run generate -- --env staging
|
|
npm run seed -- --service all --env staging
|
|
|
|
- name: Validate deployment
|
|
run: |
|
|
npm run validate -- --env staging
|
|
```
|
|
|
|
### Monitoring et Alerting
|
|
|
|
#### Métriques de Santé
|
|
|
|
```typescript
|
|
// scripts/health-monitor.js
|
|
import {
|
|
WebFixtures,
|
|
ChatServerFixtures,
|
|
StreamServerFixtures
|
|
} from '@veza/fixtures'
|
|
|
|
async function monitorHealth() {
|
|
const results = {
|
|
web: { status: 'healthy', issues: [] },
|
|
chat: await ChatServerFixtures.healthCheck(),
|
|
stream: await StreamServerFixtures.healthCheck()
|
|
}
|
|
|
|
// Alerting logic
|
|
Object.entries(results).forEach(([service, health]) => {
|
|
if (!health.database || !health.redis) {
|
|
console.error(`🚨 Service ${service} unhealthy:`, health)
|
|
// Send alert to monitoring system
|
|
}
|
|
})
|
|
|
|
return results
|
|
}
|
|
|
|
// Run every 5 minutes
|
|
setInterval(monitorHealth, 5 * 60 * 1000)
|
|
```
|
|
|
|
## 🔧 Dépannage
|
|
|
|
### Problèmes Courants
|
|
|
|
#### Erreur de Connexion Base de Données
|
|
|
|
```bash
|
|
# Symptôme
|
|
❌ Chat server health check failed: connect ECONNREFUSED
|
|
|
|
# Solution
|
|
# 1. Vérifier que PostgreSQL est démarré
|
|
sudo systemctl status postgresql
|
|
|
|
# 2. Vérifier la configuration
|
|
cat .env | grep DB_
|
|
|
|
# 3. Tester la connexion
|
|
psql -h localhost -U veza -d veza_dev
|
|
|
|
# 4. Diagnostic complet
|
|
./tools/scripts/install.sh doctor
|
|
```
|
|
|
|
#### Données Incohérentes
|
|
|
|
```bash
|
|
# Symptôme
|
|
⚠️ Data validation warnings: User has tracks but no playlists
|
|
|
|
# Solution
|
|
# 1. Nettoyer les données
|
|
veza-fixtures clean --force
|
|
|
|
# 2. Régénérer avec validation
|
|
veza-fixtures generate --env development
|
|
veza-fixtures validate --check-relations
|
|
|
|
# 3. Si le problème persiste
|
|
npm run test -- --testPathPattern="relations"
|
|
```
|
|
|
|
#### Performance Lente
|
|
|
|
```bash
|
|
# Symptôme
|
|
⏱️ Generation took 45s for 100 users (expected: <10s)
|
|
|
|
# Solutions
|
|
# 1. Réduire la taille du dataset
|
|
veza-fixtures generate --users 50 --tracks 100
|
|
|
|
# 2. Vérifier la mémoire disponible
|
|
free -h
|
|
|
|
# 3. Profiler la génération
|
|
NODE_OPTIONS="--max-old-space-size=4096" npm run generate
|
|
|
|
# 4. Mode debug
|
|
DEBUG=veza:performance npm run generate
|
|
```
|
|
|
|
#### Erreurs de Validation
|
|
|
|
```bash
|
|
# Symptôme
|
|
❌ Validation failed: Invalid email format
|
|
|
|
# Solution
|
|
# 1. Vérifier la configuration Faker
|
|
cat fixtures/core/utils/faker-config.ts
|
|
|
|
# 2. Régénérer avec seed différent
|
|
veza-fixtures generate --seed "new-seed-$(date +%s)"
|
|
|
|
# 3. Forcer la validation stricte
|
|
npm run validate -- --strict
|
|
```
|
|
|
|
### Logs et Debug
|
|
|
|
#### Activation des Logs
|
|
|
|
```bash
|
|
# Logs détaillés
|
|
DEBUG=veza:* npm run generate
|
|
|
|
# Logs spécifiques
|
|
DEBUG=veza:generators npm run generate
|
|
DEBUG=veza:relations npm run validate
|
|
DEBUG=veza:services npm run seed
|
|
```
|
|
|
|
#### Fichiers de Log
|
|
|
|
```bash
|
|
# Logs CLI
|
|
tail -f ~/.veza-fixtures/logs/cli.log
|
|
|
|
# Logs de génération
|
|
tail -f ~/.veza-fixtures/logs/generation.log
|
|
|
|
# Logs de validation
|
|
tail -f ~/.veza-fixtures/logs/validation.log
|
|
```
|
|
|
|
#### Mode Verbose
|
|
|
|
```bash
|
|
# Toutes les commandes supportent --verbose
|
|
veza-fixtures generate --verbose
|
|
veza-fixtures seed --verbose --service chat-server
|
|
veza-fixtures validate --verbose --check-relations
|
|
```
|
|
|
|
### Récupération d'Erreurs
|
|
|
|
#### Nettoyage Complet
|
|
|
|
```bash
|
|
# Nettoyage de tout le système
|
|
./tools/scripts/install.sh uninstall
|
|
./tools/scripts/install.sh install
|
|
|
|
# Ou nettoyage sélectif
|
|
veza-fixtures clean --service all --force
|
|
rm -rf fixtures/exports/*
|
|
rm -rf fixtures/node_modules
|
|
npm install && npm run build
|
|
```
|
|
|
|
#### Réinitialisation de Base de Données
|
|
|
|
```sql
|
|
-- PostgreSQL
|
|
DROP DATABASE IF EXISTS veza_dev;
|
|
DROP DATABASE IF EXISTS veza_test;
|
|
DROP DATABASE IF EXISTS veza_chat;
|
|
|
|
CREATE DATABASE veza_dev;
|
|
CREATE DATABASE veza_test;
|
|
CREATE DATABASE veza_chat;
|
|
```
|
|
|
|
```bash
|
|
# Redis
|
|
redis-cli FLUSHALL
|
|
```
|
|
|
|
### Support et Aide
|
|
|
|
#### Diagnostic Automatique
|
|
|
|
```bash
|
|
# Diagnostic complet du système
|
|
./tools/scripts/install.sh doctor
|
|
|
|
# Rapport de diagnostic
|
|
veza-fixtures status --verbose > diagnostic-report.txt
|
|
```
|
|
|
|
#### Collecte d'Informations
|
|
|
|
```bash
|
|
# Informations système
|
|
node --version
|
|
npm --version
|
|
psql --version
|
|
redis-server --version
|
|
|
|
# Configuration fixtures
|
|
cat .env
|
|
npm list --depth=0
|
|
|
|
# Logs récents
|
|
tail -n 50 ~/.veza-fixtures/logs/*.log
|
|
```
|
|
|
|
## 🏆 Meilleures Pratiques
|
|
|
|
### Génération de Données
|
|
|
|
#### Cohérence et Réalisme
|
|
|
|
```typescript
|
|
// ✅ Bon : Relations cohérentes
|
|
const artist = UserGenerator.generateArtist()
|
|
const tracks = AudioGenerator.generateUserContent(artist.id, 'artist')
|
|
|
|
// ❌ Éviter : Relations incohérentes
|
|
const user = UserGenerator.generate({ role: 'user' })
|
|
const tracks = AudioGenerator.generateBatch(100, { uploadedById: user.id }) // Incohérent
|
|
```
|
|
|
|
#### Seeds Reproductibles
|
|
|
|
```typescript
|
|
// ✅ Bon : Seeds descriptifs et versionnés
|
|
const seed = 'veza-demo-2025-v1.2'
|
|
const config = loadConfig('demo')
|
|
config.seed = seed
|
|
|
|
// ❌ Éviter : Seeds aléatoires
|
|
const seed = Math.random().toString()
|
|
```
|
|
|
|
#### Taille de Dataset Appropriée
|
|
|
|
```typescript
|
|
// ✅ Bon : Taille adaptée à l'usage
|
|
const devConfig = {
|
|
users: { count: 50 }, // Développement : petit dataset
|
|
tracks: { trackCount: 200 }
|
|
}
|
|
|
|
const testConfig = {
|
|
users: { count: 20 }, // Tests : dataset minimal
|
|
tracks: { trackCount: 50 }
|
|
}
|
|
|
|
const stagingConfig = {
|
|
users: { count: 500 }, // Staging : dataset réaliste
|
|
tracks: { trackCount: 2000 }
|
|
}
|
|
```
|
|
|
|
### Intégration Services
|
|
|
|
#### Initialisation Ordonnée
|
|
|
|
```typescript
|
|
// ✅ Bon : Ordre d'initialisation logique
|
|
async function setupServices() {
|
|
// 1. Génération des données
|
|
const dataset = DataRelationManager.generateCompleteDataset()
|
|
|
|
// 2. Services de base (base de données)
|
|
await ChatServerFixtures.initialize()
|
|
await ChatServerFixtures.seedDatabase()
|
|
|
|
// 3. Services de cache
|
|
await ChatServerFixtures.seedRedis()
|
|
await StreamServerFixtures.initialize()
|
|
await StreamServerFixtures.seedStreamingData()
|
|
|
|
// 4. Services frontend (derniers)
|
|
await WebFixtures.initialize()
|
|
}
|
|
```
|
|
|
|
#### Gestion des Erreurs
|
|
|
|
```typescript
|
|
// ✅ Bon : Gestion d'erreurs robuste
|
|
async function seedService(serviceName: string) {
|
|
try {
|
|
await serviceFixtures[serviceName].initialize()
|
|
await serviceFixtures[serviceName].seed()
|
|
console.log(`✅ ${serviceName} seeded successfully`)
|
|
} catch (error) {
|
|
console.error(`❌ Failed to seed ${serviceName}:`, error)
|
|
// Cleanup partial state
|
|
await serviceFixtures[serviceName].cleanup()
|
|
throw error
|
|
}
|
|
}
|
|
```
|
|
|
|
### Tests et Validation
|
|
|
|
#### Tests Isolés
|
|
|
|
```typescript
|
|
// ✅ Bon : Isolation des tests
|
|
describe('UserGenerator', () => {
|
|
beforeEach(() => {
|
|
UserGenerator.clearCache()
|
|
DataRelationManager.clearAll()
|
|
})
|
|
|
|
it('should generate unique usernames', () => {
|
|
const users = UserGenerator.generateBatch(10)
|
|
const usernames = users.map(u => u.username)
|
|
expect(new Set(usernames).size).toBe(usernames.length)
|
|
})
|
|
})
|
|
```
|
|
|
|
#### Validation Systématique
|
|
|
|
```typescript
|
|
// ✅ Bon : Validation après chaque génération
|
|
function generateAndValidate() {
|
|
const dataset = DataRelationManager.generateCompleteDataset()
|
|
|
|
const validation = DataRelationManager.validateRelations()
|
|
if (!validation.isValid) {
|
|
throw new Error(`Data validation failed: ${validation.errors.join(', ')}`)
|
|
}
|
|
|
|
return dataset
|
|
}
|
|
```
|
|
|
|
### Performance
|
|
|
|
#### Génération Lazy
|
|
|
|
```typescript
|
|
// ✅ Bon : Génération à la demande
|
|
class LazyDataGenerator {
|
|
private users: User[] | null = null
|
|
|
|
getUsers(): User[] {
|
|
if (!this.users) {
|
|
this.users = UserGenerator.generateWithDistribution()
|
|
}
|
|
return this.users
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Mise en Cache Intelligente
|
|
|
|
```typescript
|
|
// ✅ Bon : Cache avec invalidation
|
|
class CachedGenerator {
|
|
private cache = new Map<string, any>()
|
|
|
|
generate(key: string, generator: () => any) {
|
|
if (!this.cache.has(key)) {
|
|
this.cache.set(key, generator())
|
|
}
|
|
return this.cache.get(key)
|
|
}
|
|
|
|
invalidate(key: string) {
|
|
this.cache.delete(key)
|
|
}
|
|
}
|
|
```
|
|
|
|
### Maintenance
|
|
|
|
#### Documentation à Jour
|
|
|
|
```typescript
|
|
// ✅ Bon : Documentation inline
|
|
/**
|
|
* Génère un utilisateur artiste avec contenu musical associé
|
|
*
|
|
* @param options - Options de génération
|
|
* @param options.trackCount - Nombre de tracks à générer (défaut: 5-15)
|
|
* @param options.isVerified - Si l'artiste est vérifié (défaut: 60% de chance)
|
|
* @returns Utilisateur artiste avec contenu associé
|
|
*
|
|
* @example
|
|
* const artist = generateArtistWithContent({ trackCount: 10, isVerified: true })
|
|
*/
|
|
function generateArtistWithContent(options: ArtistOptions = {}) {
|
|
// Implémentation
|
|
}
|
|
```
|
|
|
|
#### Monitoring Proactif
|
|
|
|
```typescript
|
|
// ✅ Bon : Métriques et alertes
|
|
class FixturesMonitor {
|
|
static recordGenerationTime(operation: string, duration: number) {
|
|
if (duration > PERFORMANCE_THRESHOLDS[operation]) {
|
|
console.warn(`⚠️ Slow ${operation}: ${duration}ms`)
|
|
// Send to monitoring system
|
|
}
|
|
}
|
|
|
|
static recordValidationFailure(type: string, error: string) {
|
|
console.error(`❌ Validation failure [${type}]: ${error}`)
|
|
// Send alert
|
|
}
|
|
}
|
|
```
|
|
|
|
### Sécurité
|
|
|
|
#### Données Sensibles
|
|
|
|
```typescript
|
|
// ✅ Bon : Pas de données sensibles réelles
|
|
const fakePassword = vezaFaker.internet.password()
|
|
const hashedPassword = '$2a$10$dummy.hash.for.development'
|
|
|
|
// ❌ Éviter : Vraies données sensibles
|
|
const realPassword = 'admin123' // Risque de sécurité
|
|
```
|
|
|
|
#### Environnements Séparés
|
|
|
|
```typescript
|
|
// ✅ Bon : Configuration par environnement
|
|
const config = {
|
|
development: { allowRealData: false },
|
|
testing: { allowRealData: false },
|
|
staging: { allowRealData: false },
|
|
production: { enabled: false } // Pas de fixtures en prod
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
Ce guide couvre tous les aspects du système de fixtures Veza. Pour des questions spécifiques ou des cas d'usage non couverts, consultez la documentation API ou contactez l'équipe de support. |