cs-element
Version:
Advanced reactive data management library with state machines, blueprints, persistence, compression, networking, and multithreading support
1,135 lines (985 loc) • 37.9 kB
Markdown
# 🏗️ 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! 🎉