# 🏗️ Blueprint система шаблонов

CSElement включает мощную систему Blueprint для создания шаблонов структур данных с параметрами, валидацией и генерацией элементов.

## 📋 Содержание

- [Основы Blueprint](#основы-blueprint)
- [Создание шаблонов](#создание-шаблонов)
- [Параметры и валидация](#параметры-и-валидация)
- [Генерация структур](#генерация-структур)
- [Полный пример](#полный-пример-система-управления-проектами)

## Основы Blueprint

### Создание простого шаблона

```typescript
import { 
  Blueprint, 
  BlueprintType, 
  BlueprintCategory,
  BlueprintParameter,
  BlueprintParameterGroup,
  BlueprintGenerationContext,
  BlueprintGenerationResult 
} from 'cs-element';

// Создание простого шаблона
const userProfileBlueprint = new Blueprint({
  id: 'user-profile',
  name: 'Профиль пользователя',
  description: 'Шаблон для создания профиля пользователя',
  type: BlueprintType.CUSTOM,
  category: BlueprintCategory.BUSINESS,
  version: '1.0.0',
  parameterGroups: [
    {
      id: 'basic',
      name: 'Основная информация',
      description: 'Базовые данные пользователя',
      parameters: [
        {
          id: 'name',
          name: 'Имя',
          type: 'string',
          required: true,
          defaultValue: 'Новый пользователь'
        },
        {
          id: 'email',
          name: 'Email',
          type: 'string',
          required: true,
          validation: {
            pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
            message: 'Некорректный email адрес'
          }
        },
        {
          id: 'age',
          name: 'Возраст',
          type: 'number',
          required: false,
          validation: {
            min: 18,
            max: 120
          }
        }
      ]
    }
  ],
  generator: async (context: BlueprintGenerationContext) => {
    const { parameters } = context;
    
    // Создаем корневой элемент
    const userElement = new CSElement(`user-${Date.now()}`);
    await userElement.setData('name', parameters.name);
    await userElement.setData('email', parameters.email);
    
    if (parameters.age) {
      await userElement.setData('age', parameters.age);
    }
    
    await userElement.setData('createdAt', new Date().toISOString());
    await userElement.setData('type', 'user-profile');

    return {
      elements: [userElement],
      rootElement: userElement,
      warnings: []
    };
  }
});

// Использование шаблона
const result = await userProfileBlueprint.generate({
  parameters: {
    name: 'John Doe',
    email: 'john@example.com',
    age: 30
  }
});

console.log('✅ Профиль создан:', result.rootElement?.id);
```

### Валидация параметров

```typescript
// Проверка параметров перед генерацией
const parameters = {
  name: 'John Doe',
  email: 'invalid-email',
  age: 150
};

const validation = userProfileBlueprint.validateParameters(parameters);

if (!validation.valid) {
  console.log('❌ Ошибки валидации:');
  validation.errors.forEach(error => {
    console.log(`  - ${error.parameter}: ${error.message}`);
  });
}

if (validation.warnings.length > 0) {
  console.log('⚠️ Предупреждения:');
  validation.warnings.forEach(warning => {
    console.log(`  - ${warning.parameter}: ${warning.message}`);
  });
}
```

## Создание шаблонов

### Шаблон с вложенными структурами

```typescript
const projectBlueprint = new Blueprint({
  id: 'project-structure',
  name: 'Структура проекта',
  description: 'Шаблон для создания структуры проекта',
  type: BlueprintType.CUSTOM,
  category: BlueprintCategory.TECHNICAL,
  parameterGroups: [
    {
      id: 'project-info',
      name: 'Информация о проекте',
      parameters: [
        {
          id: 'projectName',
          name: 'Название проекта',
          type: 'string',
          required: true
        },
        {
          id: 'projectType',
          name: 'Тип проекта',
          type: 'select',
          required: true,
          options: [
            { value: 'web', label: 'Веб-приложение' },
            { value: 'mobile', label: 'Мобильное приложение' },
            { value: 'desktop', label: 'Десктоп приложение' }
          ]
        },
        {
          id: 'teamSize',
          name: 'Размер команды',
          type: 'number',
          required: true,
          validation: {
            min: 1,
            max: 50
          }
        }
      ]
    },
    {
      id: 'features',
      name: 'Функциональность',
      parameters: [
        {
          id: 'modules',
          name: 'Модули',
          type: 'multiselect',
          required: false,
          options: [
            { value: 'auth', label: 'Авторизация' },
            { value: 'dashboard', label: 'Панель управления' },
            { value: 'reports', label: 'Отчеты' },
            { value: 'notifications', label: 'Уведомления' }
          ]
        },
        {
          id: 'database',
          name: 'База данных',
          type: 'select',
          required: false,
          options: [
            { value: 'mysql', label: 'MySQL' },
            { value: 'postgresql', label: 'PostgreSQL' },
            { value: 'mongodb', label: 'MongoDB' }
          ]
        }
      ]
    }
  ],
  generator: async (context: BlueprintGenerationContext) => {
    const { parameters } = context;
    const elements: CSElement[] = [];
    
    // Создаем корневой элемент проекта
    const projectElement = new CSElement(`project-${Date.now()}`);
    await projectElement.setData('name', parameters.projectName);
    await projectElement.setData('type', parameters.projectType);
    await projectElement.setData('teamSize', parameters.teamSize);
    await projectElement.setData('createdAt', new Date().toISOString());
    
    elements.push(projectElement);

    // Создаем команду
    const teamElement = new CSElement(`team-${Date.now()}`);
    await teamElement.setData('name', `${parameters.projectName} Team`);
    await teamElement.setData('size', parameters.teamSize);
    
    // Создаем участников команды
    for (let i = 1; i <= parameters.teamSize; i++) {
      const memberElement = new CSElement(`member-${i}`);
      await memberElement.setData('name', `Team Member ${i}`);
      await memberElement.setData('role', i === 1 ? 'lead' : 'developer');
      teamElement.withChild(memberElement);
    }
    
    projectElement.withChild(teamElement);
    elements.push(teamElement);

    // Создаем модули если указаны
    if (parameters.modules && parameters.modules.length > 0) {
      const modulesElement = new CSElement(`modules-${Date.now()}`);
      await modulesElement.setData('name', 'Modules');
      
      for (const moduleId of parameters.modules) {
        const moduleElement = new CSElement(`module-${moduleId}`);
        await moduleElement.setData('name', moduleId);
        await moduleElement.setData('type', 'module');
        await moduleElement.setData('status', 'planned');
        
        modulesElement.withChild(moduleElement);
        elements.push(moduleElement);
      }
      
      projectElement.withChild(modulesElement);
      elements.push(modulesElement);
    }

    // Создаем конфигурацию базы данных
    if (parameters.database) {
      const dbElement = new CSElement(`database-${Date.now()}`);
      await dbElement.setData('name', 'Database');
      await dbElement.setData('type', parameters.database);
      await dbElement.setData('status', 'configured');
      
      projectElement.withChild(dbElement);
      elements.push(dbElement);
    }

    return {
      elements,
      rootElement: projectElement,
      warnings: []
    };
  }
});
```

### Условные параметры

```typescript
const conditionalBlueprint = new Blueprint({
  id: 'conditional-form',
  name: 'Условная форма',
  description: 'Форма с условными полями',
  type: BlueprintType.CUSTOM,
  category: BlueprintCategory.BUSINESS,
  parameterGroups: [
    {
      id: 'basic',
      name: 'Основные параметры',
      parameters: [
        {
          id: 'formType',
          name: 'Тип формы',
          type: 'select',
          required: true,
          options: [
            { value: 'contact', label: 'Контактная форма' },
            { value: 'registration', label: 'Регистрация' },
            { value: 'survey', label: 'Опрос' }
          ]
        },
        {
          id: 'includePhone',
          name: 'Включить телефон',
          type: 'boolean',
          required: false,
          defaultValue: false,
          condition: (params) => params.formType === 'contact' || params.formType === 'registration'
        },
        {
          id: 'phoneNumber',
          name: 'Номер телефона',
          type: 'string',
          required: false,
          condition: (params) => params.includePhone === true,
          dependencies: ['includePhone']
        },
        {
          id: 'surveyQuestions',
          name: 'Количество вопросов',
          type: 'number',
          required: false,
          condition: (params) => params.formType === 'survey',
          validation: {
            min: 1,
            max: 20
          }
        }
      ]
    }
  ],
  generator: async (context: BlueprintGenerationContext) => {
    const { parameters } = context;
    const elements: CSElement[] = [];
    
    const formElement = new CSElement(`form-${Date.now()}`);
    await formElement.setData('type', parameters.formType);
    await formElement.setData('createdAt', new Date().toISOString());
    
    // Базовые поля
    const nameField = new CSElement('field-name');
    await nameField.setData('type', 'text');
    await nameField.setData('label', 'Имя');
    await nameField.setData('required', true);
    formElement.withChild(nameField);
    
    const emailField = new CSElement('field-email');
    await emailField.setData('type', 'email');
    await emailField.setData('label', 'Email');
    await emailField.setData('required', true);
    formElement.withChild(emailField);

    // Условное поле телефона
    if (parameters.includePhone && parameters.phoneNumber) {
      const phoneField = new CSElement('field-phone');
      await phoneField.setData('type', 'tel');
      await phoneField.setData('label', 'Телефон');
      await phoneField.setData('defaultValue', parameters.phoneNumber);
      formElement.withChild(phoneField);
    }

    // Поля опроса
    if (parameters.formType === 'survey' && parameters.surveyQuestions) {
      for (let i = 1; i <= parameters.surveyQuestions; i++) {
        const questionField = new CSElement(`field-question-${i}`);
        await questionField.setData('type', 'textarea');
        await questionField.setData('label', `Вопрос ${i}`);
        await questionField.setData('required', false);
        formElement.withChild(questionField);
      }
    }

    elements.push(formElement);

    return {
      elements,
      rootElement: formElement,
      warnings: []
    };
  }
});
```

## Параметры и валидация

### Сложная валидация

```typescript
class AdvancedValidator {
  static validateEmail(email: string): string | true {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      return 'Некорректный формат email';
    }
    
    const parts = email.split('@');
    if (parts[1].length < 3) {
      return 'Слишком короткий домен';
    }
    
    return true;
  }

  static validatePassword(password: string): string | true {
    if (password.length < 8) {
      return 'Пароль должен содержать минимум 8 символов';
    }
    
    if (!/[A-Z]/.test(password)) {
      return 'Пароль должен содержать заглавные буквы';
    }
    
    if (!/[a-z]/.test(password)) {
      return 'Пароль должен содержать строчные буквы';
    }
    
    if (!/[0-9]/.test(password)) {
      return 'Пароль должен содержать цифры';
    }
    
    return true;
  }

  static validateDateRange(startDate: string, endDate: string): string | true {
    const start = new Date(startDate);
    const end = new Date(endDate);
    
    if (isNaN(start.getTime()) || isNaN(end.getTime())) {
      return 'Некорректный формат даты';
    }
    
    if (start >= end) {
      return 'Дата начала должна быть раньше даты окончания';
    }
    
    const diffDays = (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24);
    if (diffDays > 365) {
      return 'Период не может превышать 365 дней';
    }
    
    return true;
  }
}

// Шаблон с продвинутой валидацией
const advancedUserBlueprint = new Blueprint({
  id: 'advanced-user',
  name: 'Продвинутый пользователь',
  description: 'Шаблон с расширенной валидацией',
  type: BlueprintType.CUSTOM,
  category: BlueprintCategory.BUSINESS,
  parameterGroups: [
    {
      id: 'credentials',
      name: 'Учетные данные',
      parameters: [
        {
          id: 'email',
          name: 'Email',
          type: 'string',
          required: true,
          validation: {
            custom: AdvancedValidator.validateEmail
          }
        },
        {
          id: 'password',
          name: 'Пароль',
          type: 'string',
          required: true,
          validation: {
            custom: AdvancedValidator.validatePassword
          }
        }
      ]
    },
    {
      id: 'subscription',
      name: 'Подписка',
      parameters: [
        {
          id: 'startDate',
          name: 'Дата начала',
          type: 'string',
          required: true
        },
        {
          id: 'endDate',
          name: 'Дата окончания',
          type: 'string',
          required: true,
          dependencies: ['startDate'],
          validation: {
            custom: (value: string, allParams: any) => {
              return AdvancedValidator.validateDateRange(allParams.startDate, value);
            }
          }
        }
      ]
    }
  ],
  generator: async (context: BlueprintGenerationContext) => {
    // Генерация элементов...
    const userElement = new CSElement(`user-${Date.now()}`);
    // ... логика генерации
    
    return {
      elements: [userElement],
      rootElement: userElement,
      warnings: []
    };
  }
});
```

### Динамические параметры

```typescript
class DynamicParameterGenerator {
  static generateFieldParameters(fieldCount: number): BlueprintParameter[] {
    const parameters: BlueprintParameter[] = [];
    
    for (let i = 1; i <= fieldCount; i++) {
      parameters.push({
        id: `field${i}Name`,
        name: `Поле ${i} - Название`,
        type: 'string',
        required: true,
        defaultValue: `Поле ${i}`
      });
      
      parameters.push({
        id: `field${i}Type`,
        name: `Поле ${i} - Тип`,
        type: 'select',
        required: true,
        options: [
          { value: 'text', label: 'Текст' },
          { value: 'number', label: 'Число' },
          { value: 'boolean', label: 'Логическое' },
          { value: 'date', label: 'Дата' }
        ],
        defaultValue: 'text'
      });
      
      parameters.push({
        id: `field${i}Required`,
        name: `Поле ${i} - Обязательное`,
        type: 'boolean',
        required: false,
        defaultValue: false
      });
    }
    
    return parameters;
  }
}

// Создание шаблона с динамическими параметрами
function createDynamicFormBlueprint(fieldCount: number): Blueprint {
  const dynamicParameters = DynamicParameterGenerator.generateFieldParameters(fieldCount);
  
  return new Blueprint({
    id: `dynamic-form-${fieldCount}`,
    name: `Динамическая форма (${fieldCount} полей)`,
    description: `Форма с ${fieldCount} настраиваемыми полями`,
    type: BlueprintType.CUSTOM,
    category: BlueprintCategory.BUSINESS,
    parameterGroups: [
      {
        id: 'form-config',
        name: 'Конфигурация формы',
        parameters: [
          {
            id: 'formTitle',
            name: 'Заголовок формы',
            type: 'string',
            required: true,
            defaultValue: 'Новая форма'
          },
          ...dynamicParameters
        ]
      }
    ],
    generator: async (context: BlueprintGenerationContext) => {
      const { parameters } = context;
      const elements: CSElement[] = [];
      
      const formElement = new CSElement(`form-${Date.now()}`);
      await formElement.setData('title', parameters.formTitle);
      await formElement.setData('createdAt', new Date().toISOString());
      
      // Создаем поля динамически
      for (let i = 1; i <= fieldCount; i++) {
        const fieldName = parameters[`field${i}Name`];
        const fieldType = parameters[`field${i}Type`];
        const fieldRequired = parameters[`field${i}Required`];
        
        const fieldElement = new CSElement(`field-${i}`);
        await fieldElement.setData('name', fieldName);
        await fieldElement.setData('type', fieldType);
        await fieldElement.setData('required', fieldRequired);
        
        formElement.withChild(fieldElement);
        elements.push(fieldElement);
      }
      
      elements.push(formElement);
      
      return {
        elements,
        rootElement: formElement,
        warnings: []
      };
    }
  });
}

// Использование динамического шаблона
const dynamicForm = createDynamicFormBlueprint(5);
```

## Генерация структур

### Предварительный просмотр

```typescript
// Предварительный просмотр структуры
const previewResult = await projectBlueprint.preview({
  projectName: 'My Project',
  projectType: 'web',
  teamSize: 5,
  modules: ['auth', 'dashboard'],
  database: 'postgresql'
});

console.log('📊 Предварительный просмотр:', {
  structure: previewResult.structure,
  elementCount: previewResult.elementCount,
  estimatedSize: previewResult.estimatedSize
});
```

### Генерация с обработкой ошибок

```typescript
async function generateWithErrorHandling(
  blueprint: Blueprint,
  parameters: Record<string, any>
): Promise<BlueprintGenerationResult | null> {
  try {
    // Валидация параметров
    const validation = blueprint.validateParameters(parameters);
    if (!validation.valid) {
      console.error('❌ Ошибки валидации параметров:');
      validation.errors.forEach(error => {
        console.error(`  - ${error.parameter}: ${error.message}`);
      });
      return null;
    }

    // Показываем предупреждения
    if (validation.warnings.length > 0) {
      console.warn('⚠️ Предупреждения:');
      validation.warnings.forEach(warning => {
        console.warn(`  - ${warning.parameter}: ${warning.message}`);
      });
    }

    // Генерация
    const result = await blueprint.generate({ parameters });
    
    // Проверяем результат
    if (!result.rootElement) {
      console.error('❌ Не создан корневой элемент');
      return null;
    }

    if (result.warnings && result.warnings.length > 0) {
      console.warn('⚠️ Предупреждения генерации:');
      result.warnings.forEach(warning => {
        console.warn(`  - ${warning}`);
      });
    }

    console.log(`✅ Успешно сгенерировано ${result.elements.length} элементов`);
    return result;

  } catch (error) {
    console.error('❌ Ошибка генерации:', error);
    return null;
  }
}

// Использование
const result = await generateWithErrorHandling(projectBlueprint, {
  projectName: 'My Project',
  projectType: 'web',
  teamSize: 5,
  modules: ['auth', 'dashboard'],
  database: 'postgresql'
});
```

## Полный пример: Система управления проектами

```typescript
class ProjectManagementBlueprintSystem {
  private blueprints: Map<string, Blueprint> = new Map();
  private generatedProjects: Map<string, CSElement> = new Map();

  constructor() {
    this.initializeBlueprints();
  }

  private initializeBlueprints(): void {
    // Шаблон простого проекта
    const simpleProjectBlueprint = new Blueprint({
      id: 'simple-project',
      name: 'Простой проект',
      description: 'Базовый шаблон проекта',
      type: BlueprintType.TEMPLATE,
      category: BlueprintCategory.BUSINESS,
      parameterGroups: [
        {
          id: 'basic',
          name: 'Основная информация',
          parameters: [
            {
              id: 'name',
              name: 'Название проекта',
              type: 'string',
              required: true
            },
            {
              id: 'description',
              name: 'Описание',
              type: 'string',
              required: false
            },
            {
              id: 'deadline',
              name: 'Крайний срок',
              type: 'string',
              required: false
            }
          ]
        }
      ],
      generator: this.generateSimpleProject
    });

    // Шаблон agile проекта
    const agileProjectBlueprint = new Blueprint({
      id: 'agile-project',
      name: 'Agile проект',
      description: 'Проект с agile методологией',
      type: BlueprintType.TEMPLATE,
      category: BlueprintCategory.BUSINESS,
      parameterGroups: [
        {
          id: 'project-info',
          name: 'Информация о проекте',
          parameters: [
            {
              id: 'name',
              name: 'Название проекта',
              type: 'string',
              required: true
            },
            {
              id: 'sprintDuration',
              name: 'Длительность спринта (недели)',
              type: 'number',
              required: true,
              defaultValue: 2,
              validation: {
                min: 1,
                max: 4
              }
            },
            {
              id: 'sprintCount',
              name: 'Количество спринтов',
              type: 'number',
              required: true,
              defaultValue: 6,
              validation: {
                min: 1,
                max: 20
              }
            }
          ]
        },
        {
          id: 'team',
          name: 'Команда',
          parameters: [
            {
              id: 'scrumMaster',
              name: 'Scrum Master',
              type: 'string',
              required: true
            },
            {
              id: 'productOwner',
              name: 'Product Owner',
              type: 'string',
              required: true
            },
            {
              id: 'developers',
              name: 'Разработчики',
              type: 'array',
              required: true,
              validation: {
                min: 1,
                max: 10
              }
            }
          ]
        }
      ],
      generator: this.generateAgileProject
    });

    this.blueprints.set('simple-project', simpleProjectBlueprint);
    this.blueprints.set('agile-project', agileProjectBlueprint);
  }

  private generateSimpleProject = async (context: BlueprintGenerationContext): Promise<BlueprintGenerationResult> => {
    const { parameters } = context;
    const elements: CSElement[] = [];

    // Создаем корневой элемент проекта
    const projectElement = new CSElement(`project-${Date.now()}`);
    await projectElement.setData('name', parameters.name);
    await projectElement.setData('description', parameters.description || '');
    await projectElement.setData('deadline', parameters.deadline || '');
    await projectElement.setData('type', 'simple');
    await projectElement.setData('status', 'created');
    await projectElement.setData('createdAt', new Date().toISOString());

    // Создаем список задач
    const tasksElement = new CSElement(`tasks-${Date.now()}`);
    await tasksElement.setData('name', 'Задачи');
    await tasksElement.setData('type', 'task-list');

    // Создаем несколько начальных задач
    const initialTasks = ['Планирование', 'Анализ требований', 'Разработка', 'Тестирование', 'Деплой'];
    
    for (const taskName of initialTasks) {
      const taskElement = new CSElement(`task-${taskName.toLowerCase()}`);
      await taskElement.setData('name', taskName);
      await taskElement.setData('status', 'todo');
      await taskElement.setData('priority', 'medium');
      
      tasksElement.withChild(taskElement);
      elements.push(taskElement);
    }

    projectElement.withChild(tasksElement);
    elements.push(projectElement, tasksElement);

    return {
      elements,
      rootElement: projectElement,
      warnings: []
    };
  };

  private generateAgileProject = async (context: BlueprintGenerationContext): Promise<BlueprintGenerationResult> => {
    const { parameters } = context;
    const elements: CSElement[] = [];
    const warnings: string[] = [];

    // Создаем корневой элемент проекта
    const projectElement = new CSElement(`agile-project-${Date.now()}`);
    await projectElement.setData('name', parameters.name);
    await projectElement.setData('type', 'agile');
    await projectElement.setData('sprintDuration', parameters.sprintDuration);
    await projectElement.setData('sprintCount', parameters.sprintCount);
    await projectElement.setData('status', 'created');
    await projectElement.setData('createdAt', new Date().toISOString());

    // Создаем команду
    const teamElement = new CSElement(`team-${Date.now()}`);
    await teamElement.setData('name', 'Команда проекта');
    await teamElement.setData('scrumMaster', parameters.scrumMaster);
    await teamElement.setData('productOwner', parameters.productOwner);

    // Добавляем разработчиков
    const developersElement = new CSElement(`developers-${Date.now()}`);
    await developersElement.setData('name', 'Разработчики');

    for (let i = 0; i < parameters.developers.length; i++) {
      const developerElement = new CSElement(`developer-${i}`);
      await developerElement.setData('name', parameters.developers[i]);
      await developerElement.setData('role', 'developer');
      
      developersElement.withChild(developerElement);
      elements.push(developerElement);
    }

    teamElement.withChild(developersElement);
    projectElement.withChild(teamElement);
    elements.push(teamElement, developersElement);

    // Создаем спринты
    const sprintsElement = new CSElement(`sprints-${Date.now()}`);
    await sprintsElement.setData('name', 'Спринты');

    for (let i = 1; i <= parameters.sprintCount; i++) {
      const sprintElement = new CSElement(`sprint-${i}`);
      await sprintElement.setData('name', `Спринт ${i}`);
      await sprintElement.setData('number', i);
      await sprintElement.setData('duration', parameters.sprintDuration);
      await sprintElement.setData('status', i === 1 ? 'active' : 'planned');

      // Создаем backlog для спринта
      const backlogElement = new CSElement(`backlog-sprint-${i}`);
      await backlogElement.setData('name', `Backlog спринта ${i}`);
      await backlogElement.setData('type', 'backlog');

      sprintElement.withChild(backlogElement);
      sprintsElement.withChild(sprintElement);
      elements.push(sprintElement, backlogElement);
    }

    projectElement.withChild(sprintsElement);
    elements.push(sprintsElement);

    // Создаем product backlog
    const productBacklogElement = new CSElement(`product-backlog-${Date.now()}`);
    await productBacklogElement.setData('name', 'Product Backlog');
    await productBacklogElement.setData('type', 'product-backlog');

    // Добавляем начальные пользовательские истории
    const initialStories = [
      'Как пользователь, я хочу войти в систему',
      'Как пользователь, я хочу просматривать данные',
      'Как администратор, я хочу управлять пользователями'
    ];

    for (let i = 0; i < initialStories.length; i++) {
      const storyElement = new CSElement(`story-${i}`);
      await storyElement.setData('name', initialStories[i]);
      await storyElement.setData('type', 'user-story');
      await storyElement.setData('priority', 'high');
      await storyElement.setData('storyPoints', 5);

      productBacklogElement.withChild(storyElement);
      elements.push(storyElement);
    }

    projectElement.withChild(productBacklogElement);
    elements.push(productBacklogElement);

    // Проверяем размер команды
    if (parameters.developers.length > 7) {
      warnings.push('Размер команды больше рекомендуемого (7 человек) для agile проекта');
    }

    elements.push(projectElement);

    return {
      elements,
      rootElement: projectElement,
      warnings
    };
  };

  async createProject(blueprintId: string, parameters: Record<string, any>): Promise<string | null> {
    const blueprint = this.blueprints.get(blueprintId);
    if (!blueprint) {
      console.error(`❌ Шаблон ${blueprintId} не найден`);
      return null;
    }

    const result = await generateWithErrorHandling(blueprint, parameters);
    if (!result) {
      return null;
    }

    const projectId = result.rootElement!.id;
    this.generatedProjects.set(projectId, result.rootElement!);

    console.log(`✅ Проект ${projectId} создан по шаблону ${blueprintId}`);
    return projectId;
  }

  getProject(projectId: string): CSElement | null {
    return this.generatedProjects.get(projectId) || null;
  }

  getAllProjects(): Array<{
    id: string;
    name: string;
    type: string;
    createdAt: string;
  }> {
    return Array.from(this.generatedProjects.entries()).map(([id, element]) => ({
      id,
      name: element.getData('name') as string,
      type: element.getData('type') as string,
      createdAt: element.getData('createdAt') as string
    }));
  }

  getAvailableBlueprints(): Array<{
    id: string;
    name: string;
    description: string;
    category: string;
    parameterGroups: any[];
  }> {
    return Array.from(this.blueprints.values()).map(blueprint => ({
      id: blueprint.id,
      name: blueprint.name,
      description: blueprint.description,
      category: blueprint.category,
      parameterGroups: blueprint.parameterGroups
    }));
  }

  async exportProject(projectId: string): Promise<Blob | null> {
    const project = this.getProject(projectId);
    if (!project) {
      console.error(`❌ Проект ${projectId} не найден`);
      return null;
    }

    const exportData = project.serialize({
      includeChildren: true,
      includeData: true,
      includeMetadata: true
    });

    return new Blob([JSON.stringify(exportData, null, 2)], {
      type: 'application/json'
    });
  }

  async cloneProject(projectId: string, newName: string): Promise<string | null> {
    const project = this.getProject(projectId);
    if (!project) {
      console.error(`❌ Проект ${projectId} не найден`);
      return null;
    }

    // Создаем копию проекта
    const clonedProject = new CSElement(`cloned-${Date.now()}`);
    const originalData = project.serialize({
      includeChildren: true,
      includeData: true,
      includeMetadata: true
    });

    // Восстанавливаем структуру
    const restored = CSElement.deserialize(originalData);
    await restored.setData('name', newName);
    await restored.setData('createdAt', new Date().toISOString());

    this.generatedProjects.set(restored.id, restored);

    console.log(`✅ Проект ${projectId} клонирован как ${restored.id}`);
    return restored.id;
  }
}

// Демонстрация использования
async function demonstrateProjectManagement() {
  const system = new ProjectManagementBlueprintSystem();

  try {
    // Просмотр доступных шаблонов
    const blueprints = system.getAvailableBlueprints();
    console.log('📋 Доступные шаблоны:', blueprints.map(b => b.name));

    // Создание простого проекта
    const simpleProjectId = await system.createProject('simple-project', {
      name: 'Мой первый проект',
      description: 'Тестовый проект',
      deadline: '2024-12-31'
    });

    // Создание agile проекта
    const agileProjectId = await system.createProject('agile-project', {
      name: 'Agile проект',
      sprintDuration: 2,
      sprintCount: 8,
      scrumMaster: 'Alice Smith',
      productOwner: 'Bob Johnson',
      developers: ['Charlie Brown', 'Diana Prince', 'Eve Adams']
    });

    // Просмотр созданных проектов
    const projects = system.getAllProjects();
    console.log('📊 Созданные проекты:', projects);

    // Экспорт проекта
    if (agileProjectId) {
      const exportBlob = await system.exportProject(agileProjectId);
      if (exportBlob) {
        console.log(`📦 Проект экспортирован, размер: ${exportBlob.size} байт`);
      }
    }

    // Клонирование проекта
    if (simpleProjectId) {
      const clonedId = await system.cloneProject(simpleProjectId, 'Клон проекта');
      console.log(`📋 Проект клонирован: ${clonedId}`);
    }

  } catch (error) {
    console.error('❌ Ошибка в системе управления проектами:', error);
  }
}

demonstrateProjectManagement().catch(console.error);
```

## 🎯 Заключение

Система Blueprint в CSElement обеспечивает:

- **🏗️ Структурированное создание** - шаблоны для повторяющихся структур
- **✅ Валидация параметров** - проверка входных данных перед генерацией
- **🔧 Гибкость** - условные параметры и динамическая генерация
- **📊 Предварительный просмотр** - оценка результата до генерации
- **🎯 Категоризация** - организация шаблонов по типам и категориям

---

**Заключение:** Вы изучили все основные возможности библиотеки CSElement! 🎉 