# Подключение 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 для заказов 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 # Создание тестовых данных для сайта createSampleData: -> currentDate = new Date().toISOString() futureDate = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString() pastDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).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 } # Доменные настройки для второго домена { _id: "domain_settings_concert_hall_tj" type: "domain_settings" domain: "concert-hall.tj" name: "Концертный зал Борбад - Таджикистан" description: "Культурная площадка для мероприятий и концертов" active: true priority: 2 theme: "borbad_light" languages: ["tj", "ru"] default_language: "tj" timezone: "Asia/Dushanbe" currency: "TJS" settings: { seo: { title_template: "{page} - Борбад" description: "Концерты и мероприятия в Душанбе" keywords: ["концерты", "Борбад", "Душанбе", "мероприятия"] } social: { facebook: "https://facebook.com/borbad.tj" instagram: "https://instagram.com/borbad.tj" } contact: { address: "г. Душанбе, пр. Рудаки 22" phone: "+992 37 123-45-68" email: "info@concert-hall.tj" } features: { online_booking: true multi_language: true ecommerce: false } } created_at: currentDate updated_at: currentDate } # Слайдеры (6 слайдов) - мультидоменные { _id: "slide_01_borbad" type: "slide" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" title: "Добро пожаловать в Кохи Борбад" content: "## Современный концертный зал в сердце Душанбе\n\nМесто, где встречаются искусство и культура" image: "/assets/borbad.s5l.ru/sliders/main-hall.jpg" mobile_image: "/assets/borbad.s5l.ru/sliders/main-hall-mobile.jpg" order: 1 active: true button_text: "Узнать больше" button_link: "/about" button_style: "primary" text_color: "#ffffff" text_position: "center" overlay: true overlay_opacity: 0.4 start_date: "2024-01-01T00:00:00.000Z" end_date: "2024-12-31T23:59:59.000Z" target_audience: ["all"] created_at: currentDate updated_at: currentDate } { _id: "slide_02_borbad" type: "slide" domain: ["borbad.s5l.ru"] domain_priority: ["borbad.s5l.ru"] language: "ru" title: "Симфонические вечера" content: "## Погрузитесь в мир классической музыки\n\nЕженедельные концерты симфонического оркестра" image: "/assets/borbad.s5l.ru/sliders/orchestra.jpg" order: 2 active: true button_text: "Расписание" button_link: "/events" text_color: "#ffffff" overlay: true created_at: currentDate updated_at: currentDate } # ... остальные 4 слайда с аналогичной структурой # Блог посты (6 постов) - мультидоменные { _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" author: "Администрация Борбад" status: "published" meta_title: "Открытие нового сезона 2024 - Кохи Борбад" meta_description: "Новый творческий сезон 2024 года в концертном зале Борбад в Душанбе" featured: true featured_image: "/assets/borbad.s5l.ru/posts/season-opening-featured.jpg" reading_time: 5 created_at: currentDate updated_at: currentDate published_at: currentDate views: 156 likes: 23 shares: 45 } { _id: @generateBlogPostId("История создания концертного зала", "borbad") type: "blog_post" 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Концертный зал Борбад был основан в 2010 году..." excerpt: "История создания и архитектурные особенности концертного зала Борбад" image: "/assets/borbad.s5l.ru/posts/history-building.jpg" tags: ["история", "архитектура", "культура"] category_id: "category_about_borbad" author: "Директор зала" status: "published" featured: true created_at: pastDate updated_at: currentDate published_at: pastDate views: 289 } # ... остальные 4 поста с аналогичной структурой # Мероприятия (6 мероприятий) - мультидоменные { _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: "Большой зал" venue_id: "venue_main_hall_borbad" address: { street: "пр. Рудаки 22" city: "Душанбе" country: "Таджикистан" } coordinates: { lat: 38.5732 lng: 68.7734 } price: 500 currency: "TJS" available_tickets: 45 total_tickets: 300 image: "/assets/borbad.s5l.ru/events/beethoven-concert.jpg" gallery: [ "/assets/borbad.s5l.ru/gallery/concert1.jpg" "/assets/borbad.s5l.ru/gallery/concert2.jpg" ] tags: ["концерт", "симфоническая музыка", "классика", "Бетховен", "Чайковский"] category_id: "category_concerts_borbad" status: "upcoming" registration_required: true max_attendees: 300 age_restriction: "6+" organizer: "Симфонический оркестр Борбад" performers: ["Фаррух Саидов (дирижер)", "Солисты оркестра"] duration: 120 created_at: currentDate updated_at: currentDate } # ... остальные 5 мероприятий с аналогичной структурой # Категории - мультидоменные { _id: "category_concerts_borbad" type: "category" domain: ["borbad.s5l.ru", "concert-hall.tj"] domain_priority: ["borbad.s5l.ru", "concert-hall.tj"] language: "ru" translation_of: null translation_status: "original" name: "Концерты" slug: "concerts" description: "Музыкальные мероприятия и концерты различных жанров" image: "/assets/borbad.s5l.ru/categories/concerts.jpg" icon: "music" parent_id: null order: 2 meta_title: "Концерты - Кохи Борбад" meta_description: "Музыкальные мероприятия и концерты в концертном зале Борбад" active: true featured: true show_in_menu: true menu_order: 2 color: "#3B82F6" created_at: currentDate updated_at: currentDate } { _id: "category_news_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" parent_id: null order: 1 meta_title: "Новости - Кохи Борбад" meta_description: "Последние новости и анонсы концертного зала Борбад" active: true created_at: currentDate updated_at: currentDate } # Пользователи - глобальные { _id: "user_admin_main" type: "user" domain: "global" email: "admin@borbad.s5l.ru" name: "Администратор Борбад" role: "admin" active: true permissions: ["read", "write", "delete", "admin"] profile: { avatar: "/assets/borbad.s5l.ru/avatars/admin.jpg" phone: "+992 37 123-45-67" position: "Системный администратор" bio: "Ответственный за техническую часть сайта" } preferences: { language: "ru" notifications: true theme: "dark" timezone: "Asia/Dushanbe" } security: { last_password_change: "2024-01-01T00:00:00.000Z" two_factor_enabled: true login_attempts: 0 } domains_access: ["borbad.s5l.ru", "concert-hall.tj"] created_at: currentDate updated_at: currentDate last_login: "2024-01-15T09:30:00.000Z" } # Заказы - специфичные для домена { _id: @generateOrderId()+"_borbad" type: "order" domain: "borbad.s5l.ru" language: "ru" user_id: "user_customer_ivanov" status: "completed" total: 1500 currency: "TJS" items: [ { product_id: "event_ticket_1" name: "Билет на симфонический концерт" quantity: 2 price: 500 total: 1000 type: "ticket" } ] customer_info: { name: "Иван Иванов" email: "ivan@example.com" phone: "+992 123-45-67" } payment_info: { method: "card" transaction_id: "txn_123456" status: "paid" amount: 1500 currency: "TJS" payment_date: "2024-01-15T14:00:00.000Z" } shipping_info: { method: "pickup" address: null tracking_number: null } metadata: { ip_address: "192.168.1.100" user_agent: "Mozilla/5.0..." source: "website" } created_at: "2024-01-15T13:45:00.000Z" updated_at: "2024-01-15T14:00:00.000Z" } ] 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