37 KiB
37 KiB
📖 Guide Complet du Système de Fixtures Veza
Table des Matières
- Introduction
- Installation et Configuration
- Concepts Fondamentaux
- Génération de Données
- Intégration avec les Services
- Scénarios de Test
- CLI et Outils
- Cas d'Usage Avancés
- Dépannage
- 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
# 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
# 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
# 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
# .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
// 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
# 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
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
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
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 :
// 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
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 :
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
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 :
// 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
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 :
// 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
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
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
// 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
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
// 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
// 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
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
// 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
// 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
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
// 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
// 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
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
- Bienvenue - Message d'accueil personnalisé
- Vérification Email - Code de vérification
- Profil - Complétion du profil utilisateur
- Préférences Musicales - Sélection des genres
- Première Playlist - Création d'une playlist
- Communauté - Rejoindre les discussions
Scénario de Charge Haute
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
// 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
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é
// 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
# 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
# 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
# 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
# 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
# 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
# État basique
veza-fixtures status
# Informations détaillées
veza-fixtures status --verbose
# Environnement spécifique
veza-fixtures status --env staging
Options Globales
# Toutes les commandes supportent :
--env <environment> # Environnement (development, testing, staging, demo)
--verbose # Mode verbeux
--help # Aide de la commande
Scripts NPM
# 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
# 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
# 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
// 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
// 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
// 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
# 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
// 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
// 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é
# .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é
// 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
-- 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;
# Redis
redis-cli FLUSHALL
Support et Aide
Diagnostic Automatique
# Diagnostic complet du système
./tools/scripts/install.sh doctor
# Rapport de diagnostic
veza-fixtures status --verbose > diagnostic-report.txt
Collecte d'Informations
# 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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
// ✅ 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.