14 KiB
14 KiB
🏗️ Architecture du Système de Fixtures Veza
Vue d'Ensemble
Le système de fixtures Veza est conçu selon une architecture modulaire et extensible qui sépare clairement les responsabilités entre la génération de données, la gestion des relations, l'intégration avec les services, et l'exécution de scénarios de test.
🎯 Principes de Conception
1. Séparation des Responsabilités
- Core : Génération et validation des données
- Services : Intégration spécifique à chaque service
- Scenarios : Orchestration de tests complexes
- Tools : Interfaces utilisateur (CLI, scripts)
2. Cohérence des Données
- Relations bidirectionnelles automatiques
- Validation en temps réel
- Contraintes d'intégrité référentielle
3. Scalabilité
- Génération parallélisable
- Gestion mémoire optimisée
- Support multi-environnements
4. Reproductibilité
- Seeds déterministes
- Configuration versionnée
- Exports standardisés
🏛️ Architecture Détaillée
graph TB
subgraph "Configuration Layer"
CONFIG[Configuration Manager]
ENV[Environment Configs]
SEED[Seed Management]
end
subgraph "Core Layer"
GEN[Data Generators]
SCHEMA[Schema Validation]
FAKER[Enhanced Faker]
REL[Relation Manager]
end
subgraph "Service Integration Layer"
WEB[Web Fixtures]
CHAT[Chat Server Fixtures]
STREAM[Stream Server Fixtures]
API[Backend API Fixtures]
end
subgraph "Scenario Layer"
JOURNEY[User Journey]
PERF[Performance Tests]
INTEG[Integration Tests]
EDGE[Edge Cases]
end
subgraph "Interface Layer"
CLI[CLI Tools]
PROG[Programmatic API]
CI[CI/CD Integration]
end
CONFIG --> GEN
ENV --> CONFIG
SEED --> FAKER
GEN --> SCHEMA
GEN --> REL
FAKER --> GEN
REL --> WEB
REL --> CHAT
REL --> STREAM
REL --> API
WEB --> JOURNEY
CHAT --> PERF
STREAM --> INTEG
API --> EDGE
CLI --> CONFIG
PROG --> REL
CI --> CLI
📦 Modules Principaux
Core Module
Configuration Manager
// Gestion centralisée de la configuration
export class ConfigurationManager {
loadConfig(environment: string): FixtureConfig
validateConfig(config: FixtureConfig): ValidationResult
mergeConfigs(base: FixtureConfig, override: Partial<FixtureConfig>): FixtureConfig
}
Responsabilités:
- Chargement des configurations d'environnement
- Validation des paramètres
- Fusion des configurations
- Gestion des variables d'environnement
Data Generators
// Générateurs spécialisés par type d'entité
export abstract class BaseGenerator<T> {
abstract generate(options?: GenerationOptions): T
generateBatch(count: number, options?: GenerationOptions): T[]
clearCache(): void
}
export class UserGenerator extends BaseGenerator<User> {
// Implémentation spécifique aux utilisateurs
}
Responsabilités:
- Génération d'entités typées
- Gestion du cache en mémoire
- Options de personnalisation
- Validation des données générées
Relation Manager
// Gestionnaire central des relations entre entités
export class DataRelationManager {
static registerEntity<T>(entity: T, type: EntityType): void
static validateRelations(): ValidationResult
static exportForDatabase(): DatabaseExport
static exportForAPI(): APIExport
}
Responsabilités:
- Enregistrement des entités
- Maintien des relations bidirectionnelles
- Validation de l'intégrité référentielle
- Export dans différents formats
Service Integration Layer
Web Fixtures
export class WebFixtures {
// MSW handlers pour mocks API
static getMSWHandlers(): RequestHandler[]
// Données localStorage
static seedLocalStorage(): void
// État d'authentification
static setupAuthState(user: User): void
}
Responsabilités:
- Configuration MSW (Mock Service Worker)
- Gestion de l'état du navigateur
- Simulation d'authentification
- Données de session
Chat Server Fixtures
export class ChatServerFixtures {
// Seeding base de données PostgreSQL
static async seedDatabase(): Promise<void>
// Cache Redis
static async seedRedis(): Promise<void>
// Événements WebSocket
static generateWebSocketEvents(): WebSocketEvent[]
}
Responsabilités:
- Population de la base de données
- Gestion du cache Redis
- Simulation d'événements temps réel
- Métriques de performance
Stream Server Fixtures
export class StreamServerFixtures {
// Sessions de streaming
static generateStreamingSession(userId: string, trackId: string): StreamingSession
// Queue de traitement audio
static generateAudioProcessingJobs(tracks: Audio[]): ProcessingJob[]
// Analytics de streaming
static generateStreamingAnalytics(): StreamingAnalytics
}
Responsabilités:
- Simulation de sessions de streaming
- Queue de traitement audio
- Métriques en temps réel
- Données d'analytics
Scenario Layer
Scenario Framework
export abstract class BaseScenario<T> {
abstract setup(): Promise<T>
abstract validate(context: T): ValidationResult
abstract cleanup(context: T): Promise<void>
}
export class UserJourneyScenario extends BaseScenario<UserJourneyContext> {
// Implémentation spécifique au parcours utilisateur
}
Responsabilités:
- Orchestration de tests complexes
- Validation des résultats
- Nettoyage après exécution
- Métriques de performance
🔄 Flux de Données
1. Génération de Données
sequenceDiagram
participant CLI
participant Config
participant Generator
participant RelationManager
participant Validator
CLI->>Config: loadConfig(environment)
Config->>Generator: initialize(config)
Generator->>Generator: generateUsers()
Generator->>RelationManager: registerUsers(users)
Generator->>Generator: generateAudio()
Generator->>RelationManager: registerAudio(tracks)
RelationManager->>Validator: validateRelations()
Validator->>CLI: ValidationResult
2. Seeding de Services
sequenceDiagram
participant CLI
participant RelationManager
participant WebFixtures
participant ChatFixtures
participant StreamFixtures
CLI->>RelationManager: getDataset()
RelationManager->>WebFixtures: initialize(dataset)
WebFixtures->>WebFixtures: setupMSWHandlers()
RelationManager->>ChatFixtures: seedDatabase(dataset)
ChatFixtures->>ChatFixtures: seedRedis(dataset)
RelationManager->>StreamFixtures: seedStreaming(dataset)
StreamFixtures->>CLI: success
3. Exécution de Scénarios
sequenceDiagram
participant CLI
participant Scenario
participant Services
participant Validator
CLI->>Scenario: setup()
Scenario->>Services: initializeServices()
Services->>Scenario: ready
Scenario->>Scenario: executeSteps()
Scenario->>Validator: validateResults()
Validator->>CLI: ScenarioResult
🔧 Patterns de Conception
1. Factory Pattern
export class FixtureFactory {
static createUser(type: UserType): User {
switch (type) {
case 'admin': return UserGenerator.generateAdmin()
case 'artist': return UserGenerator.generateArtist()
default: return UserGenerator.generate()
}
}
}
2. Observer Pattern
export class GenerationObserver {
onUserGenerated(user: User): void
onAudioGenerated(audio: Audio): void
onRelationEstablished(from: string, to: string, type: string): void
}
3. Strategy Pattern
export interface ExportStrategy {
export(data: any): Promise<void>
}
export class JSONExportStrategy implements ExportStrategy {
async export(data: any): Promise<void> {
// Implémentation JSON
}
}
export class SQLExportStrategy implements ExportStrategy {
async export(data: any): Promise<void> {
// Implémentation SQL
}
}
4. Builder Pattern
export class ScenarioBuilder {
private scenario: Partial<Scenario> = {}
withUsers(count: number): this {
this.scenario.userCount = count
return this
}
withDuration(seconds: number): this {
this.scenario.duration = seconds
return this
}
build(): Scenario {
return new Scenario(this.scenario)
}
}
🗄️ Gestion des Données
Structure en Mémoire
interface DataStore {
users: Map<string, User>
audio: Map<string, Audio>
playlists: Map<string, Playlist>
conversations: Map<string, Conversation>
messages: Map<string, Message>
// Index pour les relations
userTracks: Map<string, string[]>
userPlaylists: Map<string, string[]>
conversationParticipants: Map<string, string[]>
}
Optimisations Mémoire
- Lazy Loading : Chargement à la demande des relations
- Weak References : Éviter les fuites mémoire
- Pagination : Traitement par chunks pour gros datasets
- Cache LRU : Éviction automatique des données anciennes
Persistence
interface PersistenceAdapter {
save(key: string, data: any): Promise<void>
load(key: string): Promise<any>
delete(key: string): Promise<void>
clear(): Promise<void>
}
export class FilePersistenceAdapter implements PersistenceAdapter {
// Implémentation fichier
}
export class DatabasePersistenceAdapter implements PersistenceAdapter {
// Implémentation base de données
}
🔒 Sécurité et Validation
Validation des Schémas
// Utilisation de Zod pour la validation
export const UserSchema = z.object({
id: z.string().uuid(),
username: z.string().min(3).max(50),
email: z.string().email(),
// ... autres champs
})
export const validateUser = (data: unknown): User => {
return UserSchema.parse(data)
}
Sanitisation des Données
export class DataSanitizer {
static sanitizeUser(user: User): User {
return {
...user,
email: this.sanitizeEmail(user.email),
username: this.sanitizeUsername(user.username)
}
}
private static sanitizeEmail(email: string): string {
// Nettoyage et validation
}
}
Gestion des Secrets
export class SecretManager {
static generateJWT(user: User): string
static hashPassword(password: string): string
static generateAPIKey(): string
}
🚀 Performance et Scalabilité
Génération Parallèle
export class ParallelGenerator {
static async generateBatch<T>(
generator: () => T,
count: number,
concurrency: number = 10
): Promise<T[]> {
const chunks = this.createChunks(count, concurrency)
const promises = chunks.map(chunk =>
Promise.all(chunk.map(() => generator()))
)
const results = await Promise.all(promises)
return results.flat()
}
}
Optimisations Base de Données
export class BatchInserter {
static async insertUsers(users: User[]): Promise<void> {
const BATCH_SIZE = 1000
const batches = this.createBatches(users, BATCH_SIZE)
for (const batch of batches) {
await this.insertBatch(batch)
}
}
}
Monitoring des Performances
export class PerformanceMonitor {
static time<T>(name: string, fn: () => T): T {
const start = Date.now()
const result = fn()
const duration = Date.now() - start
this.recordMetric(name, duration)
return result
}
static recordMetric(name: string, value: number): void {
// Enregistrement des métriques
}
}
🧪 Tests et Qualité
Architecture de Tests
test/
├── unit/ # Tests unitaires
│ ├── generators/ # Tests des générateurs
│ ├── utils/ # Tests des utilitaires
│ └── services/ # Tests des services
├── integration/ # Tests d'intégration
│ ├── cross-service/ # Tests inter-services
│ └── scenarios/ # Tests de scénarios
└── performance/ # Tests de performance
├── load/ # Tests de charge
└── stress/ # Tests de stress
Stratégies de Test
- Unit Tests : Chaque générateur et utilitaire
- Integration Tests : Communication entre modules
- Performance Tests : Métriques et benchmarks
- End-to-End Tests : Scénarios complets
🔄 CI/CD Integration
Pipeline de Validation
# Validation automatique des fixtures
- name: Validate Fixtures
run: |
npm run generate -- --dry-run
npm run validate -- --check-relations
npm run test -- --coverage
Déploiement Automatique
# Déploiement des fixtures en staging
- name: Deploy Fixtures
run: |
npm run seed -- --env staging --service all
npm run validate -- --env staging
🔮 Extensibilité
Ajout de Nouveaux Générateurs
// 1. Créer le générateur
export class MyEntityGenerator extends BaseGenerator<MyEntity> {
generate(options?: MyEntityOptions): MyEntity {
// Implémentation
}
}
// 2. Enregistrer dans le système
DataRelationManager.registerGenerator('myEntity', MyEntityGenerator)
// 3. Ajouter au CLI
CLI.addCommand('generate-my-entity', MyEntityGenerator.generate)
Nouveaux Types d'Export
// 1. Implémenter l'interface
export class XMLExportStrategy implements ExportStrategy {
async export(data: any): Promise<void> {
// Conversion en XML
}
}
// 2. Enregistrer la stratégie
ExportManager.registerStrategy('xml', XMLExportStrategy)
Intégration de Nouveaux Services
// 1. Créer la classe de fixtures
export class MyServiceFixtures {
static async initialize(): Promise<void>
static async seed(data: any): Promise<void>
static async validate(): Promise<ValidationResult>
}
// 2. Enregistrer dans le système
ServiceRegistry.register('my-service', MyServiceFixtures)
Cette architecture modulaire et extensible permet au système de fixtures Veza de s'adapter aux besoins évolutifs de la plateforme tout en maintenant la cohérence, la performance et la qualité des données générées.