# Подключение PouchDB PouchDB = require 'pouchdb' # Важно сохранять для seed-events.coffee debug = require('../../../utils/coffee/debug.coffee').default class DatabaseSeeder constructor: (dbName, baseUrl = 'http://oleg:631074@localhost:5984') -> @dbName = dbName @baseUrl = baseUrl @db = new PouchDB(@baseUrl+"/"+@dbName) @designDoc = require './design-documents.coffee' @orderCounter = 0 @currentYear = new Date().getFullYear() # Генератор ID для категорий generateCategoryId: (name, parentId = null, domain = null) -> slug = name .toLowerCase() .replace(/[^a-z0-9а-яё]/g, '_') .replace(/_+/g, '_') .replace(/^_|_$/g, '') id = "category_"+slug if parentId parentSlug = parentId.replace(/^category_/, '') id += "_"+parentSlug if domain domainPart = domain.replace(/\./g, '_') id += "_"+domainPart return id # Генератор ID для заказов generateOrderId: -> @orderCounter++ return "order_"+@currentYear+"_"+@orderCounter.toString().padStart(3, '0') # Генератор ID для блог постов generateBlogPostId: (title, domain = null) -> slug = title .toLowerCase() .replace(/[^a-z0-9а-яё]/g, '_') .replace(/_+/g, '_') .replace(/^_|_$/g, '') year = new Date().getFullYear() id = "blog_post_"+slug+"_"+year if domain domainPart = domain.replace(/\./g, '_') id += "_"+domainPart return id # Генератор ID для мероприятий generateEventId: (title, eventDate, domain = null) -> slug = title .toLowerCase() .replace(/[^a-z0-9а-яё]/g, '_') .replace(/_+/g, '_') .replace(/^_|_$/g, '') date = new Date(eventDate) year = date.getFullYear() month = (date.getMonth() + 1).toString().padStart(2, '0') id = "event_"+slug+"_"+year+"_"+month if domain domainPart = domain.replace(/\./g, '_') id += "_"+domainPart return id # Проверка существования базы данных checkDatabaseExists: -> try info = await @db.info() debug.log "База данных "+@dbName+" существует" return true catch error debug.log "База данных "+@dbName+" не существует: "+error return false # Создание базы данных если не существует createDatabaseIfNotExists: -> exists = await @checkDatabaseExists() if not exists try response = await fetch(@baseUrl+"/"+@dbName, method: 'PUT') if response.ok debug.log "База данных "+@dbName+" создана" else debug.log "Ошибка создания базы: "+response.statusText catch error debug.log "Ошибка при создании базы: "+error return exists # Удаление старых версий документов cleanupOldDocuments: -> try debug.log "Начало очистки старых документов" allDocs = await @db.allDocs(include_docs: true) documentsToDelete = [] documentsToKeep = new Set() documentsByType = {} for row in allDocs.rows doc = row.doc if doc._id.startsWith('_design/') continue docType = doc.type or 'unknown' if not documentsByType[docType] documentsByType[docType] = [] documentsByType[docType].push(doc) for docType, docs of documentsByType if docs.length <= 6 for doc in docs documentsToKeep.add(doc._id) continue sortedDocs = docs.sort (a, b) -> new Date(b.created_at) - new Date(a.created_at) for doc, index in sortedDocs if index < 6 documentsToKeep.add(doc._id) else documentsToDelete.push({ _id: doc._id _rev: doc._rev _deleted: true }) if documentsToDelete.length > 0 result = await @db.bulkDocs(documentsToDelete) debug.log "Удалено старых документов: "+documentsToDelete.length else debug.log "Старые документы для удаления не найдены" debug.log "Очистка старых документов завершена" catch error debug.log "Ошибка при очистке старых документов: "+error # Проверка и создание design документов setupDesignDocuments: -> try for designName, designDoc of @designDoc docId = "_design/"+designName try currentDoc = await @db.get(docId) if currentDoc.version isnt designDoc.version debug.log "Обновление design документа: "+designName designDoc._id = docId designDoc._rev = currentDoc._rev await @db.put(designDoc) debug.log "Design документ "+designName+" обновлен до версии "+designDoc.version else debug.log "Design документ "+designName+" актуален" catch error if error.status is 404 debug.log "Создание design документа: "+designName designDoc._id = docId await @db.put(designDoc) debug.log "Design документ "+designName+" создан" else throw error catch error debug.log "Ошибка при настройке design документов: "+error # Создание иерархической структуры категорий createCategoryHierarchy: -> categories = [ # Корневые категории { _id: @generateCategoryId("Мероприятия", null, "borbad") type: "category" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" name: "Мероприятия" slug: "events" description: "Все мероприятия концертного зала" image: "/assets/borbad.s5l.ru/categories/events.jpg" icon: "calendar" parent_id: null parent_path: [] # Путь от корня level: 0 # Уровень в иерархии (0 - корень) order: 1 children_count: 4 meta_title: "Мероприятия - Кохи Борбад" meta_description: "Концерты, выставки и другие мероприятия в концертном зале Борбад" active: true featured: true show_in_menu: true menu_order: 1 color: "#3B82F6" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Новости", null, "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Новости" slug: "news" description: "Новости и анонсы концертного зала" image: "/assets/borbad.s5l.ru/categories/news.jpg" icon: "news" parent_id: null parent_path: [] level: 0 order: 2 children_count: 0 meta_title: "Новости - Кохи Борбад" meta_description: "Последние новости и анонсы концертного зала Борбад" active: true featured: false show_in_menu: true menu_order: 2 color: "#10B981" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Образование", null, "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Образование" slug: "education" description: "Образовательные программы и мастер-классы" image: "/assets/borbad.s5l.ru/categories/education.jpg" icon: "graduation" parent_id: null parent_path: [] level: 0 order: 3 children_count: 3 meta_title: "Образовательные программы - Кохи Борбад" meta_description: "Мастер-классы, лекции и образовательные программы" active: true featured: false show_in_menu: true menu_order: 3 color: "#F59E0B" created_at: new Date().toISOString() updated_at: new Date().toISOString() } # Подкатегории для "Мероприятия" { _id: @generateCategoryId("Концерты", "category_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" name: "Концерты" slug: "concerts" description: "Музыкальные концерты различных жанров" image: "/assets/borbad.s5l.ru/categories/concerts.jpg" icon: "music" parent_id: "category_events_borbad" parent_path: ["category_events_borbad"] level: 1 order: 1 children_count: 3 meta_title: "Концерты - Кохи Борбад" meta_description: "Музыкальные концерты в концертном зале Борбад" active: true featured: true show_in_menu: true menu_order: 1 color: "#6366F1" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Выставки", "category_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" name: "Выставки" slug: "exhibitions" description: "Художественные выставки и вернисажи" image: "/assets/borbad.s5l.ru/categories/exhibitions.jpg" icon: "palette" parent_id: "category_events_borbad" parent_path: ["category_events_borbad"] level: 1 order: 2 children_count: 0 meta_title: "Выставки - Кохи Борбад" meta_description: "Художественные выставки в галерее Борбад" active: true featured: false show_in_menu: true menu_order: 2 color: "#EC4899" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Театр", "category_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Театр" slug: "theater" description: "Театральные постановки и спектакли" image: "/assets/borbad.s5l.ru/categories/theater.jpg" icon: "drama" parent_id: "category_events_borbad" parent_path: ["category_events_borbad"] level: 1 order: 3 children_count: 0 meta_title: "Театральные постановки - Кохи Борбад" meta_description: "Спектакли и театральные представления" active: true featured: false show_in_menu: true menu_order: 3 color: "#8B5CF6" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Фестивали", "category_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Фестивали" slug: "festivals" description: "Музыкальные и культурные фестивали" image: "/assets/borbad.s5l.ru/categories/festivals.jpg" icon: "festival" parent_id: "category_events_borbad" parent_path: ["category_events_borbad"] level: 1 order: 4 children_count: 0 meta_title: "Фестивали - Кохи Борбад" meta_description: "Культурные и музыкальные фестивали" active: true featured: false show_in_menu: true menu_order: 4 color: "#F59E0B" created_at: new Date().toISOString() updated_at: new Date().toISOString() } # Подкатегории для "Концерты" { _id: @generateCategoryId("Классическая музыка", "category_concerts_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" name: "Классическая музыка" slug: "classical-music" description: "Симфонические концерты и классические произведения" image: "/assets/borbad.s5l.ru/categories/classical-music.jpg" icon: "classical" parent_id: "category_concerts_events_borbad" parent_path: ["category_events_borbad", "category_concerts_events_borbad"] level: 2 order: 1 children_count: 0 meta_title: "Классическая музыка - Кохи Борбад" meta_description: "Симфонические концерты и классические произведения" active: true featured: true show_in_menu: true menu_order: 1 color: "#3B82F6" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Джаз и блюз", "category_concerts_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Джаз и блюз" slug: "jazz-blues" description: "Джазовые концерты и блюзовые вечера" image: "/assets/borbad.s5l.ru/categories/jazz-blues.jpg" icon: "jazz" parent_id: "category_concerts_events_borbad" parent_path: ["category_events_borbad", "category_concerts_events_borbad"] level: 2 order: 2 children_count: 0 meta_title: "Джаз и блюз - Кохи Борбад" meta_description: "Джазовые концерты и блюзовые вечера" active: true featured: false show_in_menu: true menu_order: 2 color: "#8B5CF6" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Народная музыка", "category_concerts_events_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" name: "Народная музыка" slug: "folk-music" description: "Концерты народной и традиционной музыки" image: "/assets/borbad.s5l.ru/categories/folk-music.jpg" icon: "folk" parent_id: "category_concerts_events_borbad" parent_path: ["category_events_borbad", "category_concerts_events_borbad"] level: 2 order: 3 children_count: 0 meta_title: "Народная музыка - Кохи Борбад" meta_description: "Концерты народной и традиционной музыки" active: true featured: false show_in_menu: true menu_order: 3 color: "#10B981" created_at: new Date().toISOString() updated_at: new Date().toISOString() } # Подкатегории для "Образование" { _id: @generateCategoryId("Мастер-классы", "category_education_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Мастер-классы" slug: "workshops" description: "Практические занятия и мастер-классы" image: "/assets/borbad.s5l.ru/categories/workshops.jpg" icon: "workshop" parent_id: "category_education_borbad" parent_path: ["category_education_borbad"] level: 1 order: 1 children_count: 0 meta_title: "Мастер-классы - Кохи Борбад" meta_description: "Практические занятия и мастер-классы" active: true featured: false show_in_menu: true menu_order: 1 color: "#F59E0B" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Лекции", "category_education_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Лекции" slug: "lectures" description: "Образовательные лекции и семинары" image: "/assets/borbad.s5l.ru/categories/lectures.jpg" icon: "lecture" parent_id: "category_education_borbad" parent_path: ["category_education_borbad"] level: 1 order: 2 children_count: 0 meta_title: "Лекции - Кохи Борбад" meta_description: "Образовательные лекции и семинары" active: true featured: false show_in_menu: true menu_order: 2 color: "#EF4444" created_at: new Date().toISOString() updated_at: new Date().toISOString() } { _id: @generateCategoryId("Детские программы", "category_education_borbad", "borbad") type: "category" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" name: "Детские программы" slug: "children-programs" description: "Образовательные программы для детей" image: "/assets/borbad.s5l.ru/categories/children-programs.jpg" icon: "children" parent_id: "category_education_borbad" parent_path: ["category_education_borbad"] level: 1 order: 3 children_count: 0 meta_title: "Детские программы - Кохи Борбад" meta_description: "Образовательные программы для детей" active: true featured: true show_in_menu: true menu_order: 3 color: "#EC4899" created_at: new Date().toISOString() updated_at: new Date().toISOString() } ] return categories # Создание тестовых данных для сайта createSampleData: -> currentDate = new Date().toISOString() sampleData = [ # Доменные настройки { _id: "domain_settings_borbad_s5l_ru" type: "domain_settings" domain: "borbad.s5l.ru" name: "Кохи Борбад - Концертный зал Душанбе" description: "Официальный сайт концертного зала Борбад" active: true priority: 1 theme: "borbad" languages: ["ru", "en", "tj"] default_language: "ru" timezone: "Asia/Dushanbe" currency: "TJS" settings: { seo: { title_template: "{page} - Кохи Борбад" description: "Концертный зал Борбад - культурный центр Душанбе" keywords: ["концерты", "мероприятия", "Душанбе", "культура"] } social: { facebook: "https://facebook.com/borbad" instagram: "https://instagram.com/borbad" twitter: "https://twitter.com/borbad" } contact: { address: "г. Душанбе, пр. Рудаки 22" phone: "+992 37 123-45-67" email: "info@borbad.s5l.ru" } features: { online_booking: true multi_language: true ecommerce: true } } created_at: currentDate updated_at: currentDate } # Добавляем иерархические категории ...@createCategoryHierarchy() # Блог посты с привязкой к иерархическим категориям { _id: @generateBlogPostId("Открытие нового сезона 2024", "borbad") type: "blog_post" domain: ["borbad.s5l.ru", "global"] domain_priority: ["borbad.s5l.ru", "global"] language: "ru" translation_of: null translation_status: "original" title: "Открытие нового сезона 2024" content: "# Добро пожаловать в новый творческий сезон!\n\nМы рады объявить о начале нового сезона в концертном зале Борбад..." excerpt: "Новый творческий сезон 2024 года в концертном зале Борбад" image: "/assets/borbad.s5l.ru/posts/season-opening.jpg" tags: ["новости", "сезон", "анонс"] category_id: "category_news_borbad" # Привязка к категории новостей category_path: ["category_news_borbad"] # Полный путь категории author: "Администрация Борбад" status: "published" meta_title: "Открытие нового сезона 2024 - Кохи Борбад" meta_description: "Новый творческий сезон 2024 года в концертном зале Борбад в Душанбе" featured: true reading_time: 5 created_at: currentDate updated_at: currentDate published_at: currentDate views: 156 } # Мероприятия с привязкой к иерархическим категориям { _id: @generateEventId("Симфонический концерт: Бетховен и Чайковский", "2024-03-20T19:00:00.000Z", "borbad") type: "event" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" translation_of: null translation_status: "original" title: "Симфонический концерт: Бетховен и Чайковский" content: "# Великие композиторы\n\n## Программа концерта\n\n- **Л. ван Бетховен** - Симфония №5..." event_date: "2024-03-20T19:00:00.000Z" end_date: "2024-03-20T21:00:00.000Z" location: "Большой зал" price: 500 currency: "TJS" available_tickets: 45 total_tickets: 300 image: "/assets/borbad.s5l.ru/events/beethoven-concert.jpg" tags: ["концерт", "симфоническая музыка", "классика", "Бетховен", "Чайковский"] category_id: "category_classical_music_concerts_events_borbad" # Глубокая привязка category_path: ["category_events_borbad", "category_concerts_events_borbad", "category_classical_music_concerts_events_borbad"] status: "upcoming" registration_required: true created_at: currentDate updated_at: currentDate } { _id: @generateEventId("Джазовый вечер с Тимуром Якубовым", "2024-04-15T20:00:00.000Z", "borbad") type: "event" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" title: "Джазовый вечер с Тимуром Якубовым" content: "# Современный джаз в Борбаде\n\n## О исполнителе\n\nТимур Якубов - известный джазовый пианист..." event_date: "2024-04-15T20:00:00.000Z" end_date: "2024-04-15T22:00:00.000Z" location: "Малый зал" price: 350 currency: "TJS" available_tickets: 80 total_tickets: 150 image: "/assets/borbad.s5l.ru/events/jazz-evening.jpg" tags: ["джаз", "современная музыка", "импровизация"] category_id: "category_jazz_blues_concerts_events_borbad" category_path: ["category_events_borbad", "category_concerts_events_borbad", "category_jazz_blues_concerts_events_borbad"] status: "upcoming" registration_required: true created_at: currentDate updated_at: currentDate } # Мастер-класс с привязкой к образовательной категории { _id: @generateEventId("Мастер-класс: Основы вокала", "2024-03-25T15:00:00.000Z", "borbad") type: "event" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" title: "Мастер-класс: Основы вокала" content: "# Искусство пения для начинающих\n\n## О ведущем\n\nОперный певец Шариф Мухтаров..." event_date: "2024-03-25T15:00:00.000Z" end_date: "2024-03-25T18:00:00.000Z" location: "Репетиционный зал" price: 200 currency: "TJS" available_tickets: 15 total_tickets: 20 image: "/assets/borbad.s5l.ru/events/vocal-workshop.jpg" tags: ["мастер-класс", "вокал", "образование", "музыка"] category_id: "category_workshops_education_borbad" category_path: ["category_education_borbad", "category_workshops_education_borbad"] status: "upcoming" registration_required: true created_at: currentDate updated_at: currentDate } # Детская программа { _id: @generateEventId("Детская программа: Музыкальная сказка", "2024-04-10T11:00:00.000Z", "borbad") type: "event" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" title: "Детская программа: Музыкальная сказка" content: "# Волшебный мир музыки для детей\n\n## Новая постановка\n\nТеатральная студия Борбад представляет..." event_date: "2024-04-10T11:00:00.000Z" end_date: "2024-04-10T12:00:00.000Z" location: "Детский зал" price: 100 currency: "TJS" available_tickets: 95 total_tickets: 100 image: "/assets/borbad.s5l.ru/events/children-play.jpg" tags: ["дети", "театр", "образование", "семейный"] category_id: "category_children_programs_education_borbad" category_path: ["category_education_borbad", "category_children_programs_education_borbad"] status: "upcoming" registration_required: true created_at: currentDate updated_at: currentDate } ] try createdCount = 0 updatedCount = 0 for doc in sampleData try existing = await @db.get(doc._id) doc._rev = existing._rev await @db.put(doc) updatedCount++ debug.log "Обновлен документ: "+doc._id catch error if error.status is 404 await @db.put(doc) createdCount++ debug.log "Создан документ: "+doc._id else throw error debug.log "Тестовые данные успешно созданы: создано "+createdCount+", обновлено "+updatedCount catch error debug.log "Ошибка при создании тестовых данных: "+error # Основной метод инициализации initialize: -> debug.log "Начало инициализации базы данных" await @createDatabaseIfNotExists() await @cleanupOldDocuments() await @setupDesignDocuments() await @createSampleData() debug.log "Инициализация базы данных завершена" # Экспорт класса module.exports = DatabaseSeeder # Если файл запущен напрямую if require.main is module seeder = new DatabaseSeeder('borbad_events') seeder.initialize().catch (error) -> debug.log "Критическая ошибка инициализации: "+error