# 🚀 Batch операции и массовые операции

CSElement предоставляет мощную систему для выполнения массовых операций с оптимизацией производительности и гибким управлением выполнением.

## 📋 Содержание

1. [Основы batch операций](#основы-batch-операций)
2. [Создание и управление батчами](#создание-и-управление-батчами)
3. [Типы операций](#типы-операций)
4. [Стратегии выполнения](#стратегии-выполнения)
5. [Обработка ошибок](#обработка-ошибок)
6. [Мониторинг и прогресс](#мониторинг-и-прогресс)
7. [Оптимизация производительности](#оптимизация-производительности)
8. [Полный пример: Система импорта данных](#полный-пример-система-импорта-данных)

## Основы batch операций

Batch операции позволяют группировать множество операций и выполнять их эффективно с контролем производительности, обработкой ошибок и отслеживанием прогресса.

### Простой пример

```typescript
import { CSElement, BatchManager, BatchOperationType, BatchPriority } from 'cs-element';

// Создаем менеджер батчей
const batchManager = new BatchManager();

// Создаем новый батч
const batchId = batchManager.createBatch({
  executionStrategy: 'parallel',
  maxConcurrency: 5
});

// Добавляем операции
const operations = [
  {
    id: 'create-user-1',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.NORMAL,
    execute: async () => {
      const user = new CSElement('user-1');
      await user.setData('name', 'Алексей');
      await user.setData('email', 'alexey@example.com');
      return user;
    }
  },
  {
    id: 'create-user-2',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.NORMAL,
    execute: async () => {
      const user = new CSElement('user-2');
      await user.setData('name', 'Мария');
      await user.setData('email', 'maria@example.com');
      return user;
    }
  }
];

batchManager.addOperations(batchId, operations);

// Выполняем батч
const result = await batchManager.executeBatch(batchId);

console.log(`Батч выполнен: ${result.success}`);
console.log(`Операций выполнено: ${result.operationResults.length}`);
```

## Создание и управление батчами

### Конфигурация батча

```typescript
import { 
  BatchExecutionStrategy, 
  BatchErrorMode,
  BatchConfig 
} from 'cs-element';

const config: BatchConfig = {
  executionStrategy: BatchExecutionStrategy.PARALLEL,
  errorMode: BatchErrorMode.COLLECT_ERRORS,
  maxConcurrency: 10,
  timeout: 300000, // 5 минут
  progressUpdateInterval: 1000, // 1 секунда
  enableRollback: true,
  validateBeforeExecution: true,
  persistIntermediateResults: false
};

const batchId = batchManager.createBatch(config);
```

### Управление жизненным циклом

```typescript
// Создание батча
const batchId = batchManager.createBatch();

// Проверка статуса
const progress = batchManager.getProgress(batchId);
console.log(`Прогресс: ${progress?.percentage}%`);

// Отмена выполнения
await batchManager.cancelBatch(batchId);

// Получение результата
const result = batchManager.getBatchResult(batchId);

// Удаление батча
batchManager.removeBatch(batchId);
```

## Типы операций

### Базовые операции с элементами

```typescript
import { DefaultBatchOperationFactory } from 'cs-element';

const factory = new DefaultBatchOperationFactory();
const root = new CSElement('root');

// Операция создания элемента
const createOp = factory.createElementOperation({
  name: 'new-element',
  data: { type: 'document', status: 'draft' }
});

// Операция обновления элемента
const element = await root.addElement('existing-element');
const updateOp = factory.updateElementOperation(element, {
  status: 'published',
  lastModified: new Date()
});

// Операция удаления элемента
const deleteOp = factory.deleteElementOperation(element);

// Операция перемещения элемента
const newParent = new CSElement('new-parent');
const moveOp = factory.moveElementOperation(element, newParent);

// Операция копирования элемента
const copyOp = factory.copyElementOperation(element, newParent);
```

### Пользовательские операции

```typescript
// Сложная пользовательская операция
const customOperation = {
  id: 'complex-data-processing',
  type: BatchOperationType.CUSTOM,
  priority: BatchPriority.HIGH,
  timeout: 60000,
  maxRetries: 3,
  
  validate: async (context) => {
    // Валидация перед выполнением
    const hasRequiredData = context.sharedData.has('inputData');
    return {
      valid: hasRequiredData,
      errors: hasRequiredData ? [] : ['Отсутствуют входные данные'],
      warnings: []
    };
  },
  
  execute: async (context) => {
    const inputData = context.sharedData.get('inputData');
    
    // Обновляем прогресс
    context.updateProgress?.({ 
      currentOperation: 'Обработка данных...' 
    });
    
    // Выполняем обработку
    const processedData = await processComplexData(inputData);
    
    // Сохраняем результат для других операций
    context.sharedData.set('processedData', processedData);
    
    return processedData;
  },
  
  rollback: async (context) => {
    // Откат изменений при ошибке
    context.sharedData.delete('processedData');
    console.log('Откат операции обработки данных');
  }
};

async function processComplexData(data: any): Promise<any> {
  // Симуляция сложной обработки
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ ...data, processed: true, timestamp: Date.now() });
    }, 2000);
  });
}
```

## Стратегии выполнения

### Параллельное выполнение

```typescript
// Быстрое выполнение независимых операций
const parallelBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.PARALLEL,
  maxConcurrency: 8
});

const parallelOps = Array.from({ length: 20 }, (_, i) => ({
  id: `parallel-op-${i}`,
  type: BatchOperationType.CREATE,
  priority: BatchPriority.NORMAL,
  execute: async () => {
    const element = new CSElement(`element-${i}`);
    await element.setData('index', i);
    await element.setData('created', new Date());
    return element;
  }
}));

batchManager.addOperations(parallelBatch, parallelOps);
const parallelResult = await batchManager.executeBatch(parallelBatch);
```

### Последовательное выполнение

```typescript
// Операции с зависимостями
const sequentialBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.SEQUENTIAL
});

const sequentialOps = [
  {
    id: 'step-1',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.HIGH,
    execute: async (context) => {
      const config = new CSElement('config');
      await config.setData('database', 'initialized');
      context.sharedData.set('config', config);
      return config;
    }
  },
  {
    id: 'step-2',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.NORMAL,
    dependencies: ['step-1'],
    execute: async (context) => {
      const config = context.sharedData.get('config');
      const users = new CSElement('users');
      await users.setData('configRef', config.id);
      context.sharedData.set('users', users);
      return users;
    }
  },
  {
    id: 'step-3',
    type: BatchOperationType.UPDATE,
    priority: BatchPriority.NORMAL,
    dependencies: ['step-1', 'step-2'],
    execute: async (context) => {
      const config = context.sharedData.get('config');
      const users = context.sharedData.get('users');
      
      await config.setData('usersRef', users.id);
      await config.setData('status', 'ready');
      
      return { config, users };
    }
  }
];

batchManager.addOperations(sequentialBatch, sequentialOps);
```

### Смешанная стратегия

```typescript
// Комбинация параллельного и последовательного выполнения
const mixedBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.MIXED,
  maxConcurrency: 4
});

const mixedOps = [
  // Группа 1: Параллельная инициализация
  {
    id: 'init-database',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.CRITICAL,
    execute: async () => {
      const db = new CSElement('database');
      await db.setData('status', 'initializing');
      await new Promise(resolve => setTimeout(resolve, 1000));
      await db.setData('status', 'ready');
      return db;
    }
  },
  {
    id: 'init-cache',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.CRITICAL,
    execute: async () => {
      const cache = new CSElement('cache');
      await cache.setData('status', 'initializing');
      await new Promise(resolve => setTimeout(resolve, 800));
      await cache.setData('status', 'ready');
      return cache;
    }
  },
  
  // Группа 2: Зависимые операции (выполняются после группы 1)
  {
    id: 'create-users',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.HIGH,
    dependencies: ['init-database'],
    execute: async () => {
      const users = new CSElement('users');
      await users.setData('table', 'users');
      return users;
    }
  },
  {
    id: 'create-sessions',
    type: BatchOperationType.CREATE,
    priority: BatchPriority.HIGH,
    dependencies: ['init-cache'],
    execute: async () => {
      const sessions = new CSElement('sessions');
      await sessions.setData('storage', 'cache');
      return sessions;
    }
  }
];

batchManager.addOperations(mixedBatch, mixedOps);
```

## Обработка ошибок

### Режимы обработки ошибок

```typescript
// Остановка при первой ошибке
const failFastBatch = batchManager.createBatch({
  errorMode: BatchErrorMode.FAIL_FAST
});

// Продолжение выполнения несмотря на ошибки
const continueBatch = batchManager.createBatch({
  errorMode: BatchErrorMode.CONTINUE
});

// Сбор всех ошибок
const collectErrorsBatch = batchManager.createBatch({
  errorMode: BatchErrorMode.COLLECT_ERRORS
});
```

### Операции с обработкой ошибок

```typescript
const resilientOp = {
  id: 'resilient-operation',
  type: BatchOperationType.CUSTOM,
  priority: BatchPriority.NORMAL,
  maxRetries: 3,
  
  execute: async (context) => {
    const attempt = context.operation.metadata?.attempt || 1;
    
    try {
      // Операция, которая может завершиться ошибкой
      if (Math.random() < 0.7 && attempt < 3) {
        throw new Error(`Временная ошибка (попытка ${attempt})`);
      }
      
      return { success: true, attempt };
      
    } catch (error) {
      console.log(`Ошибка в попытке ${attempt}: ${error.message}`);
      
      if (attempt >= 3) {
        // Последняя попытка - выполняем fallback
        return { success: false, fallback: true };
      }
      
      throw error; // Повторить попытку
    }
  },
  
  rollback: async (context) => {
    console.log('Выполняем откат операции');
    // Логика отката
  }
};
```

## Мониторинг и прогресс

### Отслеживание прогресса

```typescript
// Подписка на события батча
batchManager.addEventListener({
  onBatchStart: (batchId) => {
    console.log(`🚀 Начало выполнения батча: ${batchId}`);
  },
  
  onBatchComplete: (result) => {
    console.log(`✅ Батч завершен: ${result.batchId}`);
    console.log(`Успешно: ${result.success}`);
    console.log(`Время выполнения: ${result.totalExecutionTime}мс`);
  },
  
  onOperationStart: (operation) => {
    console.log(`▶️ Начало операции: ${operation.id}`);
  },
  
  onOperationComplete: (result) => {
    console.log(`✔️ Операция завершена: ${result.operationId}`);
  },
  
  onProgressUpdate: (progress) => {
    console.log(`📊 Прогресс: ${progress.percentage}% (${progress.completedOperations}/${progress.totalOperations})`);
    
    if (progress.estimatedTimeRemaining) {
      console.log(`⏱️ Осталось: ${Math.round(progress.estimatedTimeRemaining / 1000)}с`);
    }
  },
  
  onBatchError: (batchId, error) => {
    console.error(`❌ Ошибка в батче ${batchId}:`, error.message);
  }
});
```

### Статистика выполнения

```typescript
// Получение статистики менеджера
const stats = batchManager.getStatistics();
console.log('📈 Статистика BatchManager:');
console.log(`Всего батчей: ${stats.totalBatches}`);
console.log(`Успешных: ${stats.successfulBatches}`);
console.log(`Неудачных: ${stats.failedBatches}`);
console.log(`Активных: ${stats.activeBatches}`);
console.log(`Среднее время выполнения: ${stats.averageBatchExecutionTime}мс`);

// Статистика конкретного батча
const batchResult = batchManager.getBatchResult(batchId);
if (batchResult) {
  console.log('📊 Статистика батча:');
  console.log(`Операций: ${batchResult.statistics.totalOperations}`);
  console.log(`Успешных: ${batchResult.statistics.successfulOperations}`);
  console.log(`Неудачных: ${batchResult.statistics.failedOperations}`);
  console.log(`Среднее время операции: ${batchResult.statistics.averageExecutionTime}мс`);
}
```

## Оптимизация производительности

### Настройка параллелизма

```typescript
// Оптимальная настройка для разных типов операций
const cpuIntensiveBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.PARALLEL,
  maxConcurrency: Math.max(1, Math.floor(navigator.hardwareConcurrency * 0.8))
});

const ioIntensiveBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.PARALLEL,
  maxConcurrency: 20 // Больше для I/O операций
});

const mixedWorkloadBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.MIXED,
  maxConcurrency: 6
});
```

### Группировка операций

```typescript
// Группировка схожих операций для лучшей производительности
const groupedOperations = [
  // Группа 1: Быстрые операции создания
  ...Array.from({ length: 100 }, (_, i) => ({
    id: `quick-create-${i}`,
    type: BatchOperationType.CREATE,
    priority: BatchPriority.NORMAL,
    execute: async () => {
      const element = new CSElement(`quick-${i}`);
      await element.setData('type', 'quick');
      return element;
    }
  })),
  
  // Группа 2: Медленные операции обработки
  ...Array.from({ length: 10 }, (_, i) => ({
    id: `slow-process-${i}`,
    type: BatchOperationType.TRANSFORM,
    priority: BatchPriority.LOW,
    execute: async () => {
      // Симуляция тяжелой обработки
      await new Promise(resolve => setTimeout(resolve, 2000));
      return { processed: i };
    }
  }))
];
```

### Управление памятью

```typescript
const memoryOptimizedBatch = batchManager.createBatch({
  executionStrategy: BatchExecutionStrategy.SEQUENTIAL,
  persistIntermediateResults: false, // Не сохраняем промежуточные результаты
  progressUpdateInterval: 5000 // Реже обновляем прогресс
});

// Операция с очисткой памяти
const memoryEfficientOp = {
  id: 'memory-efficient',
  type: BatchOperationType.CUSTOM,
  priority: BatchPriority.NORMAL,
  execute: async (context) => {
    try {
      // Обработка данных
      const result = await processLargeDataset();
      
      // Очистка промежуточных данных
      context.sharedData.clear();
      
      return result;
    } finally {
      // Принудительная сборка мусора (если доступна)
      if (global.gc) {
        global.gc();
      }
    }
  }
};

async function processLargeDataset(): Promise<any> {
  // Симуляция обработки большого объема данных
  return { size: 'large', processed: true };
}
```

## Полный пример: Система импорта данных

```typescript
import { 
  CSElement, 
  BatchManager, 
  DefaultBatchOperationFactory,
  BatchOperationType,
  BatchPriority,
  BatchExecutionStrategy,
  BatchErrorMode
} from 'cs-element';

interface ImportData {
  users: Array<{
    id: string;
    name: string;
    email: string;
    department: string;
  }>;
  departments: Array<{
    id: string;
    name: string;
    description: string;
  }>;
  projects: Array<{
    id: string;
    name: string;
    departmentId: string;
    memberIds: string[];
  }>;
}

class DataImportSystem {
  private batchManager: BatchManager;
  private factory: DefaultBatchOperationFactory;
  private root: CSElement;

  constructor() {
    this.batchManager = new BatchManager();
    this.factory = new DefaultBatchOperationFactory();
    this.root = new CSElement('company');
  }

  async importData(data: ImportData): Promise<{
    success: boolean;
    imported: {
      departments: number;
      users: number;
      projects: number;
    };
    errors: string[];
  }> {
    console.log('🚀 Начинаем импорт данных...');

    // Создаем батч с оптимальной конфигурацией
    const batchId = this.batchManager.createBatch({
      executionStrategy: BatchExecutionStrategy.MIXED,
      errorMode: BatchErrorMode.COLLECT_ERRORS,
      maxConcurrency: 6,
      timeout: 600000, // 10 минут
      enableRollback: true,
      validateBeforeExecution: true
    });

    // Настраиваем мониторинг
    this.setupProgressMonitoring(batchId);

    try {
      // Создаем операции импорта
      const operations = [
        ...this.createDepartmentOperations(data.departments),
        ...this.createUserOperations(data.users),
        ...this.createProjectOperations(data.projects),
        this.createValidationOperation(),
        this.createIndexingOperation()
      ];

      this.batchManager.addOperations(batchId, operations);

      // Выполняем импорт
      const result = await this.batchManager.executeBatch(batchId);

      // Анализируем результаты
      const stats = this.analyzeResults(result);

      console.log('✅ Импорт завершен!');
      console.log(`📊 Статистика: ${JSON.stringify(stats, null, 2)}`);

      return {
        success: result.success,
        imported: stats.imported,
        errors: result.errors.map(e => e.message)
      };

    } catch (error) {
      console.error('❌ Критическая ошибка импорта:', error);
      return {
        success: false,
        imported: { departments: 0, users: 0, projects: 0 },
        errors: [error.message]
      };
    } finally {
      // Очистка ресурсов
      this.batchManager.removeBatch(batchId);
    }
  }

  private createDepartmentOperations(departments: ImportData['departments']) {
    return departments.map(dept => ({
      id: `import-dept-${dept.id}`,
      type: BatchOperationType.CREATE,
      priority: BatchPriority.HIGH, // Высокий приоритет - другие зависят от отделов
      
      validate: async () => ({
        valid: !!dept.name && !!dept.id,
        errors: [
          !dept.id && 'Отсутствует ID отдела',
          !dept.name && 'Отсутствует название отдела'
        ].filter(Boolean),
        warnings: []
      }),
      
      execute: async (context) => {
        context.updateProgress?.({
          currentOperation: `Создание отдела: ${dept.name}`
        });

        const department = await this.root.addElement(`dept-${dept.id}`) as CSElement;
        await department.setData('name', dept.name);
        await department.setData('description', dept.description);
        await department.setData('type', 'department');
        await department.setData('importId', dept.id);

        // Сохраняем для использования в других операциях
        context.sharedData.set(`dept-${dept.id}`, department);

        return department;
      },
      
      rollback: async (context) => {
        const department = context.sharedData.get(`dept-${dept.id}`);
        if (department) {
          await this.root.removeElement(department);
          context.sharedData.delete(`dept-${dept.id}`);
        }
      }
    }));
  }

  private createUserOperations(users: ImportData['users']) {
    return users.map(user => ({
      id: `import-user-${user.id}`,
      type: BatchOperationType.CREATE,
      priority: BatchPriority.NORMAL,
      dependencies: [`import-dept-${user.department}`], // Зависит от создания отдела
      
      execute: async (context) => {
        context.updateProgress?.({
          currentOperation: `Создание пользователя: ${user.name}`
        });

        const department = context.sharedData.get(`dept-${user.department}`);
        if (!department) {
          throw new Error(`Отдел ${user.department} не найден для пользователя ${user.name}`);
        }

        const userElement = await department.addElement(`user-${user.id}`) as CSElement;
        await userElement.setData('name', user.name);
        await userElement.setData('email', user.email);
        await userElement.setData('type', 'user');
        await userElement.setData('importId', user.id);

        context.sharedData.set(`user-${user.id}`, userElement);

        return userElement;
      }
    }));
  }

  private createProjectOperations(projects: ImportData['projects']) {
    return projects.map(project => ({
      id: `import-project-${project.id}`,
      type: BatchOperationType.CREATE,
      priority: BatchPriority.NORMAL,
      dependencies: [
        `import-dept-${project.departmentId}`,
        ...project.memberIds.map(id => `import-user-${id}`)
      ],
      
      execute: async (context) => {
        context.updateProgress?.({
          currentOperation: `Создание проекта: ${project.name}`
        });

        const department = context.sharedData.get(`dept-${project.departmentId}`);
        const projectElement = await department.addElement(`project-${project.id}`) as CSElement;
        
        await projectElement.setData('name', project.name);
        await projectElement.setData('type', 'project');
        await projectElement.setData('importId', project.id);

        // Связываем с участниками
        for (const memberId of project.memberIds) {
          const user = context.sharedData.get(`user-${memberId}`);
          if (user) {
            await projectElement.addElement(user);
          }
        }

        return projectElement;
      }
    }));
  }

  private createValidationOperation() {
    return {
      id: 'validate-import',
      type: BatchOperationType.VALIDATE,
      priority: BatchPriority.LOW,
      dependencies: [], // Выполняется в конце
      
      execute: async (context) => {
        context.updateProgress?.({
          currentOperation: 'Валидация импортированных данных'
        });

        const departments = this.root.query('[type="department"]');
        const users = this.root.query('[type="user"]');
        const projects = this.root.query('[type="project"]');

        const validation = {
          departments: departments.length,
          users: users.length,
          projects: projects.length,
          issues: []
        };

        // Проверяем целостность данных
        for (const project of projects) {
          const members = project.getAllElements().filter(e => 
            e.getData('type') === 'user'
          );
          
          if (members.length === 0) {
            validation.issues.push(`Проект ${project.getData('name')} не имеет участников`);
          }
        }

        console.log('🔍 Результаты валидации:', validation);
        return validation;
      }
    };
  }

  private createIndexingOperation() {
    return {
      id: 'create-indexes',
      type: BatchOperationType.CUSTOM,
      priority: BatchPriority.LOW,
      
      execute: async (context) => {
        context.updateProgress?.({
          currentOperation: 'Создание индексов для быстрого поиска'
        });

        // Создаем индексы для быстрого поиска
        const emailIndex = new CSElement('email-index');
        const departmentIndex = new CSElement('department-index');

        await this.root.addElement(emailIndex);
        await this.root.addElement(departmentIndex);

        // Индексируем пользователей по email
        const users = this.root.query('[type="user"]');
        for (const user of users) {
          const email = user.getData('email');
          if (email) {
            await emailIndex.setData(email, user.id);
          }
        }

        // Индексируем по отделам
        const departments = this.root.query('[type="department"]');
        for (const dept of departments) {
          const name = dept.getData('name');
          if (name) {
            await departmentIndex.setData(name, dept.id);
          }
        }

        return { emailIndex: emailIndex.id, departmentIndex: departmentIndex.id };
      }
    };
  }

  private setupProgressMonitoring(batchId: string) {
    this.batchManager.addEventListener({
      onProgressUpdate: (progress) => {
        const percentage = Math.round(progress.percentage);
        const completed = progress.completedOperations;
        const total = progress.totalOperations;
        const current = progress.currentOperation || 'Выполнение операций';

        console.log(`📊 ${percentage}% (${completed}/${total}) - ${current}`);

        if (progress.estimatedTimeRemaining) {
          const minutes = Math.round(progress.estimatedTimeRemaining / 60000);
          console.log(`⏱️ Осталось примерно: ${minutes} мин`);
        }
      },

      onOperationComplete: (result) => {
        if (result.success) {
          console.log(`✔️ ${result.operationId} (${result.executionTime}мс)`);
        } else {
          console.log(`❌ ${result.operationId}: ${result.error?.message}`);
        }
      }
    });
  }

  private analyzeResults(result: any) {
    const imported = {
      departments: 0,
      users: 0,
      projects: 0
    };

    for (const opResult of result.operationResults) {
      if (opResult.success) {
        if (opResult.operationId.startsWith('import-dept-')) {
          imported.departments++;
        } else if (opResult.operationId.startsWith('import-user-')) {
          imported.users++;
        } else if (opResult.operationId.startsWith('import-project-')) {
          imported.projects++;
        }
      }
    }

    return {
      imported,
      totalTime: result.totalExecutionTime,
      averageOpTime: result.statistics.averageExecutionTime,
      successRate: (result.statistics.successfulOperations / result.statistics.totalOperations) * 100
    };
  }
}

// Использование системы импорта
async function demonstrateImport() {
  const importSystem = new DataImportSystem();

  const sampleData: ImportData = {
    departments: [
      { id: 'IT', name: 'IT отдел', description: 'Информационные технологии' },
      { id: 'HR', name: 'HR отдел', description: 'Управление персоналом' },
      { id: 'SALES', name: 'Отдел продаж', description: 'Продажи и маркетинг' }
    ],
    users: [
      { id: '1', name: 'Алексей Петров', email: 'alexey@company.com', department: 'IT' },
      { id: '2', name: 'Мария Иванова', email: 'maria@company.com', department: 'HR' },
      { id: '3', name: 'Сергей Сидоров', email: 'sergey@company.com', department: 'IT' },
      { id: '4', name: 'Анна Козлова', email: 'anna@company.com', department: 'SALES' }
    ],
    projects: [
      { 
        id: 'P1', 
        name: 'Новая CRM система', 
        departmentId: 'IT', 
        memberIds: ['1', '3'] 
      },
      { 
        id: 'P2', 
        name: 'Кампания по найму', 
        departmentId: 'HR', 
        memberIds: ['2'] 
      }
    ]
  };

  const result = await importSystem.importData(sampleData);
  
  console.log('🎉 Результат импорта:');
  console.log(`Успешно: ${result.success}`);
  console.log(`Импортировано отделов: ${result.imported.departments}`);
  console.log(`Импортировано пользователей: ${result.imported.users}`);
  console.log(`Импортировано проектов: ${result.imported.projects}`);
  
  if (result.errors.length > 0) {
    console.log('❌ Ошибки:', result.errors);
  }
}

// demonstrateImport();
```

## 🎯 Заключение

Система batch операций CSElement предоставляет:

- **🚀 Высокую производительность** - оптимизированное выполнение массовых операций
- **🔧 Гибкую конфигурацию** - различные стратегии выполнения и обработки ошибок
- **📊 Подробный мониторинг** - отслеживание прогресса и статистики
- **🛡️ Надежность** - обработка ошибок, откат операций и валидация
- **⚡ Масштабируемость** - эффективная работа с большими объемами данных

Используйте batch операции для импорта данных, массовых обновлений, миграций и других задач, требующих обработки множества элементов.

---

**Следующий раздел:** [React интеграция](06-react-integration.md) - изучите, как интегрировать CSElement с React приложениями. 