Gogs 3 tygodni temu
rodzic
commit
fdb631968c
3 zmienionych plików z 994 dodań i 1252 usunięć
  1. 373 341
      README.md
  2. 368 532
      scripts/design-documents.coffee
  3. 253 379
      scripts/seed-events.coffee

+ 373 - 341
README.md

@@ -1,7 +1,6 @@
 # Текущая ззадача
-доработай domain, в документах с учетом что один и тотже жокумент может быть в разных доменах
-приведи нную # Структура хранимых данных с описанием ## всех хранимых объектов 
-и их примеры.
+доработай seed-events.coffee и design-documents.coffee, с  учетом что категории имеют иеархическую структуру
+приведи также структуру ихменённых типов документов.
 
 # файл с правилами
 https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/raw/master/README.md
@@ -134,6 +133,9 @@ module.exports =
                         emit(doc.created_at, doc)).toString()
 ```
 
+## Важно сохранять для seed-events.coffee
+debug   = require('../../../utils/coffee/debug.coffee').default
+
 ## определение шаблонов для слотов
 template(#body)       - не правильно
 template(v-slot:body) - не правильно
@@ -238,328 +240,293 @@ app/
 
 # Структура хранимых данных
 ## Описание всех хранимых объектов с мультиязычностью
+
 1. Настройки домена (domain_settings)
 coffee
 {
-    _id: String                    # Уникальный идентификатор (domain_settings_[domain])
-    type: 'domain_settings'        # Тип документа
-    domain: String                 # Доменное имя (borbad.s5l.ru)
-    name: String                   # Название сайта
-    description: String            # Описание сайта
-    active: Boolean                # Активен ли домен
-    priority: Number               # Приоритет домена
-    theme: String                  # Тема оформления
-    languages: Array[String]       # Поддерживаемые языки ['ru', 'en', 'tj']
-    default_language: String       # Язык по умолчанию
-    timezone: String               # Часовой пояс
-    currency: String               # Валюта по умолчанию
-    settings: Object               # Дополнительные настройки
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
-}
-2. Запись блога (blog_post) с мультиязычностью
-coffee
-{
-    _id: String                    # Уникальный идентификатор
-    type: 'blog_post'              # Тип записи
-    domain: String                 # Домен
-    language: String               # Язык контента ('ru', 'en', 'tj')
-    translation_of: String         # ID исходного документа для переводов
-    translation_status: String     # Статус перевода ('draft', 'review', 'published')
-    title: String                  # Заголовок
-    content: String                # Основной текст в Markdown
-    excerpt: String                # Краткое описание
-    image: String                  # Главное изображение
-    tags: Array[String]            # Теги для категоризации
-    category_id: String            # ID категории
-    author: String                 # Автор записи
-    status: 'published' | 'draft'  # Статус публикации
-    meta_title: String             # SEO заголовок
-    meta_description: String       # SEO описание
-    featured: Boolean              # Избранная запись
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
-    published_at: ISOString        # Дата публикации
-    views: Number                  # Количество просмотров
-}
-3. Мероприятие (event) с мультиязычностью
-coffee
-{
-    _id: String                    # Уникальный идентификатор
-    type: 'event'                  # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    title: String                  # Заголовок мероприятия
-    content: String                # Markdown описание мероприятия
-    event_date: ISOString          # Дата и время мероприятия
-    end_date: ISOString            # Дата и время окончания
-    location: String               # Место проведения
-    venue_id: String               # ID места проведения
-    price: Number                  # Стоимость билета
-    currency: String               # Валюта (TJS, USD, etc.)
-    available_tickets: Number      # Количество доступных билетов
-    total_tickets: Number          # Общее количество билетов
-    image: String                  # Изображение мероприятия
-    gallery: Array[String]         # Галерея изображений
-    tags: Array[String]            # Теги (концерт, выставка, etc.)
-    category_id: String            # ID категории
-    status: 'upcoming' | 'ongoing' | 'completed' | 'cancelled'
-    registration_required: Boolean # Требуется ли регистрация
-    max_attendees: Number          # Максимальное количество участников
-    age_restriction: String        # Возрастные ограничения
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
-}
-4. Слайд (slide) с мультиязычностью
-coffee
-{
-    _id: String                    # Уникальный идентификатор
-    type: 'slide'                  # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    title: String                  # Заголовок слайда
-    content: String                # Markdown контент
-    image: String                  # Фоновое изображение
-    order: Number                  # Порядок отображения
-    active: Boolean                # Активен ли слайд
-    button_text: String            # Текст кнопки
-    button_link: String            # Ссылка кнопки
-    text_color: String             # Цвет текста
-    overlay: Boolean               # Наложение на изображение
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
-}
-5. Товар (product) с мультиязычностью
-coffee
-{
-    _id: String                    # Уникальный идентификатор
-    type: 'product'                # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    title: String                  # Название товара
-    content: String                # Markdown описание
-    excerpt: String                # Краткое описание
-    image: String                  # Главное изображение
-    gallery: Array[String]         # Галерея изображений
-    price: Number                  # Цена
-    currency: String               # Валюта
-    compare_price: Number          # Старая цена (для акций)
-    category_id: String            # ID категории
-    tags: Array[String]            # Теги
-    attributes: Object             # Атрибуты товара
-    inventory: Number              # Количество на складе
-    sku: String                    # Артикул
-    status: 'available' | 'out_of_stock' | 'discontinued'
-    featured: Boolean              # Рекомендуемый товар
-    weight: Number                 # Вес
-    dimensions: Object             # Размеры
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
-}
-6. Категория (category) с мультиязычностью
-coffee
-{
-    _id: String                    # Уникальный идентификатор
-    type: 'category'               # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    name: String                   # Название категории
-    slug: String                   # URL-адрес
-    description: String            # Описание категории
-    image: String                  # Изображение категории
-    parent_id: String              # ID родительской категории
-    order: Number                  # Порядок отображения
-    meta_title: String             # SEO заголовок
-    meta_description: String       # SEO описание
-    active: Boolean                # Активна ли категория
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
+    _id: "domain_settings_borbad_s5l_ru"                    # domain_settings_[домен]
+    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: "2024-01-15T10:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
 }
-7. Тема (theme) с мультиязычностью
+2. Блог посты (blog_post) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'theme'                  # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    name: String                   # Название темы
-    slug: String                   # URL-адрес
-    description: String            # Описание темы
-    color: String                  # Цвет темы
-    image: String                  # Изображение темы
-    order: Number                  # Порядок отображения
-    active: Boolean                # Активна ли тема
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
+    _id: "blog_post_season_opening_2024_borbad"
+    type: "blog_post"
+    domain: ["borbad.s5l.ru", "global"]                     # Принадлежит нескольким доменам
+    domain_priority: ["borbad.s5l.ru", "global"]           # Приоритет доменов
+    language: "ru"
+    translation_of: null                                   # ID исходного документа для переводов
+    translation_status: "original"                         # original, draft, published
+    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: "2024-01-15T10:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
+    published_at: "2024-01-15T10:00:00.000Z"
+    views: 156
+    likes: 23
+    shares: 45
 }
-8. Страница (page) с мультиязычностью
+3. Мероприятия (event) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'page'                   # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    title: String                  # Заголовок страницы
-    slug: String                   # URL-адрес
-    content: String                # Markdown контент
-    excerpt: String                # Краткое описание
-    image: String                  # Изображение страницы
-    parent_id: String              # ID родительской страницы
-    order: Number                  # Порядок отображения
-    template: String               # Шаблон страницы
-    meta_title: String             # SEO заголовок
-    meta_description: String       # SEO описание
-    status: 'published' | 'draft'  # Статус публикации
-    protected: Boolean             # Защищенная страница
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
+    _id: "event_beethoven_concert_2024_03_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: "2024-01-10T09:00:00.000Z"
+    updated_at: "2024-01-15T14:30:00.000Z"
 }
-9. Меню (menu) с мультиязычностью
+4. Слайды (slide) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'menu'                   # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык контента
-    translation_of: String         # ID исходного документа
-    translation_status: String     # Статус перевода
-    name: String                   # Название меню
-    location: String               # Расположение (header, footer, etc.)
-    active: Boolean                # Активно ли меню
-    items: Array[Object]           # Элементы меню
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
+    _id: "slide_01_borbad"
+    type: "slide"
+    domain: ["borbad.s5l.ru", "global"]                    # Глобальный слайд
+    domain_priority: ["borbad.s5l.ru", "global"]
+    language: "ru"
+    translation_of: null
+    translation_status: "original"
+    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"                               # primary, secondary, outline
+    text_color: "#ffffff"
+    text_position: "center"                               # left, center, right
+    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"]                             # all, registered, specific
+    created_at: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
 }
-10. Пользователь (user)
+5. Товары (product) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'user'                   # Тип документа
-    email: String                  # Email пользователя
-    name: String                   # Имя пользователя
-    role: String                   # Роль (admin, editor, user)
-    active: Boolean                # Активен ли пользователь
-    permissions: Array[String]     # Права доступа
-    profile: Object                # Профиль пользователя
-    preferences: Object            # Настройки пользователя
-    language: String               # Предпочитаемый язык
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
-    last_login: ISOString          # Дата последнего входа
+    _id: "product_tshirt_logo_2024_borbad"
+    type: "product"
+    domain: ["borbad.s5l.ru", "shop.borbad.s5l.ru"]       # Основной домен и магазин
+    domain_priority: ["shop.borbad.s5l.ru", "borbad.s5l.ru"]
+    language: "ru"
+    translation_of: null
+    translation_status: "original"
+    title: "Футболка с логотипом Борбад"
+    content: "## Качественная хлопковая футболка\n\nРазмеры: S, M, L, XL..."
+    excerpt: "Фирменная футболка концертного зала с логотипом"
+    image: "/assets/borbad.s5l.ru/products/tshirt.jpg"
+    gallery: [
+        "/assets/borbad.s5l.ru/products/tshirt-front.jpg"
+        "/assets/borbad.s5l.ru/products/tshirt-back.jpg"
+    ]
+    price: 250
+    currency: "TJS"
+    compare_price: 350                                    # Старая цена
+    category_id: "category_souvenirs_borbad"
+    tags: ["одежда", "сувениры", "мерч"]
+    attributes: {
+        sizes: ["S", "M", "L", "XL"]
+        colors: ["белый", "черный", "красный"]
+        material: "100% хлопок"
+        brand: "Борбад"
+    }
+    inventory: 50
+    sku: "TSH-BRB-001"
+    status: "available"
+    featured: true
+    weight: 0.3                                           # Вес в кг
+    dimensions: {
+        length: 70,
+        width: 50,
+        height: 5
+    }
+    shipping: {
+        free_shipping: false
+        shipping_cost: 50
+    }
+    seo: {
+        title: "Футболка с логотипом Борбад - Сувениры"
+        description: "Качественная хлопковая футболка с логотипом концертного зала Борбад"
+        keywords: ["футболка", "сувениры", "Борбад", "мерч"]
+    }
+    created_at: "2024-01-10T09:00:00.000Z"
+    updated_at: "2024-01-15T14:30:00.000Z"
 }
-11. Заказ (order)
+6. Категории (category) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'order'                  # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык заказа
-    user_id: String                # ID пользователя
-    status: String                 # Статус заказа
-    total: Number                  # Общая сумма
-    currency: String               # Валюта
-    items: Array[Object]           # Элементы заказа
-    customer_info: Object          # Информация о клиенте
-    payment_info: Object           # Информация об оплате
-    shipping_info: Object          # Информация о доставке
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
+    _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                                       # ID родительской категории
+    order: 2
+    meta_title: "Концерты - Кохи Борбад"
+    meta_description: "Музыкальные мероприятия и концерты в концертном зале Борбад"
+    active: true
+    featured: true
+    show_in_menu: true
+    menu_order: 2
+    color: "#3B82F6"                                      # Цвет категории
+    created_at: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
 }
-12. Настройка (setting)
+7. Темы (theme) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'setting'                # Тип документа
-    domain: String                 # Домен
-    language: String               # Язык настройки
-    key: String                    # Ключ настройки
-    value: Object                  # Значение настройки
-    is_global: Boolean             # Глобальная настройка
-    description: String            # Описание настройки
-    created_at: ISOString          # Дата создания
-    updated_at: ISOString          # Дата обновления
+    _id: "theme_classical_music_borbad"
+    type: "theme"
+    domain: ["borbad.s5l.ru", "global"]                   # Глобальная тема
+    domain_priority: ["borbad.s5l.ru", "global"]
+    language: "ru"
+    translation_of: null
+    translation_status: "original"
+    name: "Классическая музыка"
+    slug: "classical-music"
+    description: "Мероприятия классической музыки и симфонические концерты"
+    color: "#8B5CF6"
+    image: "/assets/borbad.s5l.ru/themes/classical-music.jpg"
+    order: 1
+    active: true
+    settings: {
+        font_family: "Georgia, serif"
+        background_color: "#F8FAFC"
+        text_color: "#1E293B"
+    }
+    created_at: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
 }
-13. Аудит (audit_log)
+8. Страницы (page) - мультидоменные
 coffee
 {
-    _id: String                    # Уникальный идентификатор
-    type: 'audit_log'              # Тип документа
-    user_id: String                # ID пользователя
-    action: String                 # Действие
-    resource_type: String          # Тип ресурса
-    resource_id: String            # ID ресурса
-    description: String            # Описание действия
-    ip_address: String             # IP адрес
-    user_agent: String             # User Agent
-    language: String               # Язык действия
-    created_at: ISOString          # Дата создания
-}
-
-## Пример документа настроек домена
-domainSettingsExample =
-    _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"
-    created_at: new Date().toISOString()
-    updated_at: new Date().toISOString()
-
-## Пример документа страницы
-pageExample =
     _id: "page_about_borbad"
     type: "page"
-    domain: "borbad.s5l.ru"
+    domain: ["borbad.s5l.ru", "concert-hall.tj"]          # Общая страница "О нас"
+    domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
+    language: "ru"
+    translation_of: null
+    translation_status: "original"
     title: "О нас - Кохи Борбад"
     slug: "about"
     content: "# О концертном зале Борбад\n\nИстория и описание нашего зала..."
     excerpt: "Информация о концертном зале Борбад в Душанбе"
-    image: "/assets/borbad.s5l.ru/about.jpg"
+    image: "/assets/borbad.s5l.ru/pages/about.jpg"
+    parent_id: null
+    order: 2
+    template: "default"
     meta_title: "О нас - Концертный зал Борбад"
     meta_description: "Узнайте больше о концертном зале Борбад в Душанбе"
     status: "published"
-    order: 2
-    template: "default"
-    created_at: new Date().toISOString()
-    updated_at: new Date().toISOString()
-
-## Пример документа меню
-menuExample =
-    _id: "menu_main_borbad"
+    protected: false
+    show_in_sitemap: true
+    allow_comments: false
+    featured: false
+    created_at: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
+}
+9. Меню (menu) - мультидоменные
+coffee
+{
+    _id: "menu_header_borbad_s5l_ru"
     type: "menu"
-    domain: "borbad.s5l.ru"
+    domain: "borbad.s5l.ru"                               # Специфичное для домена меню
+    domain_priority: ["borbad.s5l.ru"]
+    language: "ru"
+    translation_of: null
+    translation_status: "original"
     name: "Главное меню"
     location: "header"
     active: true
@@ -569,60 +536,79 @@ menuExample =
             url: "/"
             order: 1
             target: "_self"
+            icon: "home"
+            children: []
         }
         {
             title: "Мероприятия"
             url: "/events"
             order: 2
             target: "_self"
-        }
-        {
-            title: "О нас"
-            url: "/about"
-            order: 3
-            target: "_self"
-        }
-        {
-            title: "Контакты"
-            url: "/contacts"
-            order: 4
-            target: "_self"
+            icon: "calendar"
+            children: [
+                {
+                    title: "Концерты"
+                    url: "/events?category=concerts"
+                    order: 1
+                    target: "_self"
+                }
+                {
+                    title: "Выставки"
+                    url: "/events?category=exhibitions"
+                    order: 2
+                    target: "_self"
+                }
+            ]
         }
     ]
-    created_at: new Date().toISOString()
-    updated_at: new Date().toISOString()
-
-## Пример документа пользователя
-userExample =
-    _id: "user_admin_1"
+    settings: {
+        mobile_breakpoint: 768
+        dropdown_animation: "fade"
+    }
+    created_at: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
+}
+10. Пользователи (user) - глобальные
+coffee
+{
+    _id: "user_admin_main"
     type: "user"
+    domain: "global"                                      # Глобальный пользователь
     email: "admin@borbad.s5l.ru"
-    name: "Администратор"
+    name: "Администратор Борбад"
     role: "admin"
     active: true
-    permissions: [
-        "read"
-        "write"
-        "delete"
-        "admin"
-    ]
-    profile:
+    permissions: ["read", "write", "delete", "admin"]
+    profile: {
         avatar: "/assets/borbad.s5l.ru/avatars/admin.jpg"
         phone: "+992 37 123-45-67"
         position: "Системный администратор"
-    settings:
+        bio: "Ответственный за техническую часть сайта"
+    }
+    preferences: {
         language: "ru"
         notifications: true
-    created_at: new Date().toISOString()
-    updated_at: new Date().toISOString()
-    last_login: new Date().toISOString()
-
-## Пример документа заказа
-orderExample =
-    _id: "order_2024_001"
+        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: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
+    last_login: "2024-01-15T09:30:00.000Z"
+}
+11. Заказы (order) - мультидоменные
+coffee
+{
+    _id: "order_2024_001_borbad"
     type: "order"
-    domain: "borbad.s5l.ru"
-    user_id: "user_customer_1"
+    domain: "shop.borbad.s5l.ru"                          # Заказ из магазина
+    language: "ru"
+    user_id: "user_customer_ivanov"
     status: "completed"
     total: 1500
     currency: "TJS"
@@ -633,39 +619,85 @@ orderExample =
             quantity: 2
             price: 500
             total: 1000
+            type: "ticket"
         }
         {
-            product_id: "product_1"
+            product_id: "product_tshirt_logo_2024_borbad"
             name: "Футболка с логотипом"
             quantity: 1
             price: 500
             total: 500
+            type: "product"
         }
     ]
-    customer_info:
+    customer_info: {
         name: "Иван Иванов"
         email: "ivan@example.com"
         phone: "+992 123-45-67"
-    payment_info:
+    }
+    payment_info: {
         method: "card"
         transaction_id: "txn_123456"
         status: "paid"
-    created_at: new Date().toISOString()
-    updated_at: new Date().toISOString()
-
-## Пример документа аудита
-auditExample =
+        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"
+}
+12. Настройки (setting) - мультидоменные
+coffee
+{
+    _id: "setting_seo_title_borbad_s5l_ru"
+    type: "setting"
+    domain: "borbad.s5l.ru"                               # Специфичная настройка для домена
+    language: "ru"
+    key: "seo_title"
+    value: "Кохи Борбад - Концертный зал Душанбе"
+    type: "string"                                        # string, number, boolean, object, array
+    is_global: false
+    description: "Заголовок сайта для SEO"
+    category: "seo"
+    group: "site_settings"
+    editable: true
+    created_at: "2024-01-01T00:00:00.000Z"
+    updated_at: "2024-01-15T10:00:00.000Z"
+}
+13. Аудит (audit_log) - глобальные
+coffee
+{
     _id: "audit_2024_001"
     type: "audit_log"
-    user_id: "user_admin_1"
+    domain: "global"                                      # Глобальный лог
+    user_id: "user_admin_main"
     action: "create"
     resource_type: "blog_post"
-    resource_id: "blog_post_1"
-    description: "Создана новая запись блога"
+    resource_id: "blog_post_season_opening_2024_borbad"
+    description: "Создана новая запись блога 'Открытие нового сезона 2024'"
     ip_address: "192.168.1.1"
-    user_agent: "Mozilla/5.0..."
-    created_at: new Date().toISOString()
-
+    user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
+    language: "ru"
+    metadata: {
+        old_value: null
+        new_value: {
+            title: "Открытие нового сезона 2024"
+            status: "published"
+        }
+        changes: ["title", "status"]
+    }
+    created_at: "2024-01-15T10:00:00.000Z"
+}
 
 ## _desing документ для работы с данными
 https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/raw/master/scripts/design-documents.coffee

+ 368 - 532
scripts/design-documents.coffee

@@ -1,475 +1,26 @@
 # Design документы для CouchDB с поддержкой мультидоменности и мультиязычности
+# Версия 4.0 - с учетом последних изменений в правилах
 
 module.exports =
-    # Design документ для настроек доменов
-    domains:
-        version: "3.0"
+    # Design документ для мультидоменного поиска
+    multi_domain_search:
+        version: "4.0"
         views:
-            # Все настройки доменов
-            all_domains:
+            # Универсальный поиск по всем доменам и языкам
+            universal_search:
                 map: ((doc) ->
-                    if doc.type is 'domain_settings'
-                        emit(doc.domain, doc)
-                ).toString()
-            
-            # Активные домены
-            active_domains:
-                map: ((doc) ->
-                    if doc.type is 'domain_settings' and doc.active is true
-                        emit(doc.domain, doc)
-                ).toString()
-            
-            # Домены по приоритету
-            by_priority:
-                map: ((doc) ->
-                    if doc.type is 'domain_settings' and doc.active is true
-                        emit(doc.priority or 0, doc)
-                ).toString()
-
-    # Design документ для блог постов с мультидоменностью и мультиязычностью
-    blog_posts:
-        version: "3.0"
-        views:
-            # Все опубликованные блог посты с фильтром по домену и языку
-            published:
-                map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.created_at], doc)
-                ).toString()
-            
-            # Блог посты по тегам с фильтром по домену и языку
-            by_tag:
-                map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published' and doc.tags
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        for tag in doc.tags
-                            emit([domain, language, tag, doc.created_at], doc)
-                ).toString()
-            
-            # Блог посты по автору с фильтром по домену и языку
-            by_author:
-                map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.author, doc.created_at], doc)
-                ).toString()
-            
-            # Блог посты по категории с фильтром по домену и языку
-            by_category:
-                map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published' and doc.category_id
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.category_id, doc.created_at], doc)
-                ).toString()
-            
-            # Переводы блог постов
-            translations:
-                map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-            
-            # Поиск по заголовку и содержанию с фильтром по домену и языку
-            search:
-                map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        text = (doc.title + " " + doc.content + " " + doc.excerpt).toLowerCase()
-                        words = text.split(/\W+/).filter (word) -> word.length > 2
-                        
-                        for word in words
-                            emit([domain, language, word], {
-                                _id: doc._id
-                                title: doc.title
-                                excerpt: doc.excerpt
-                                created_at: doc.created_at
-                                domain: doc.domain
-                                language: doc.language
-                            })
-                ).toString()
-
-    # Design документ для мероприятий с мультидоменностью и мультиязычностью
-    events:
-        version: "3.0"
-        views:
-            # Все мероприятия по дате с фильтром по домену и языку
-            by_date:
-                map: ((doc) ->
-                    if doc.type is 'event'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.event_date], doc)
-                ).toString()
-            
-            # Предстоящие мероприятия с фильтром по домену и языку
-            upcoming:
-                map: ((doc) ->
-                    if doc.type is 'event' and doc.status is 'upcoming'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.event_date], doc)
-                ).toString()
-            
-            # Активные мероприятия с фильтром по домену и языку
-            ongoing:
-                map: ((doc) ->
-                    if doc.type is 'event' and doc.status is 'ongoing'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.event_date], doc)
-                ).toString()
-            
-            # Мероприятия по тегам с фильтром по домену и языку
-            by_tag:
-                map: ((doc) ->
-                    if doc.type is 'event' and doc.tags
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        for tag in doc.tags
-                            emit([domain, language, tag, doc.event_date], doc)
-                ).toString()
-            
-            # Мероприятия по местоположению с фильтром по домену и языку
-            by_location:
-                map: ((doc) ->
-                    if doc.type is 'event'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.location, doc.event_date], doc)
-                ).toString()
-            
-            # Переводы мероприятий
-            translations:
-                map: ((doc) ->
-                    if doc.type is 'event' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-
-    # Design документ для слайдов с мультидоменностью и мультиязычностью
-    slides:
-        version: "3.0"
-        views:
-            # Активные слайды по порядку с фильтром по домену и языку
-            active_ordered:
-                map: ((doc) ->
-                    if doc.type is 'slide' and doc.active is true
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.order], doc)
-                ).toString()
-            
-            # Переводы слайдов
-            translations:
-                map: ((doc) ->
-                    if doc.type is 'slide' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-
-    # Design документ для товаров с мультидоменностью и мультиязычностью
-    products:
-        version: "3.0"
-        views:
-            # Все доступные товары с фильтром по домену и языку
-            available:
-                map: ((doc) ->
-                    if doc.type is 'product' and doc.status is 'available'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.created_at], doc)
-                ).toString()
-            
-            # Товары по категориям с фильтром по домену и языку
-            by_category:
-                map: ((doc) ->
-                    if doc.type is 'product' and doc.status is 'available'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.category_id, doc.created_at], doc)
-                ).toString()
-            
-            # Товары по тегам с фильтром по домену и языку
-            by_tag:
-                map: ((doc) ->
-                    if doc.type is 'product' and doc.tags
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        for tag in doc.tags
-                            emit([domain, language, tag, doc.created_at], doc)
-                ).toString()
-            
-            # Товары по цене с фильтром по домену и языку
-            by_price:
-                map: ((doc) ->
-                    if doc.type is 'product' and doc.status is 'available'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.price], doc)
-                ).toString()
-            
-            # Переводы товаров
-            translations:
-                map: ((doc) ->
-                    if doc.type is 'product' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-
-    # Design документ для категорий и тем с мультидоменностью и мультиязычностью
-    categories_themes:
-        version: "3.0"
-        views:
-            # Все категории по порядку с фильтром по домену и языку
-            categories_ordered:
-                map: ((doc) ->
-                    if doc.type is 'category'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.order], doc)
-                ).toString()
-            
-            # Категории по родителю с фильтром по домену и языку
-            categories_by_parent:
-                map: ((doc) ->
-                    if doc.type is 'category'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        parent = doc.parent_id or 'root'
-                        emit([domain, language, parent, doc.order], doc)
-                ).toString()
-            
-            # Все темы с фильтром по домену и языку
-            themes:
-                map: ((doc) ->
-                    if doc.type is 'theme'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.name], doc)
-                ).toString()
-            
-            # Переводы категорий
-            category_translations:
-                map: ((doc) ->
-                    if doc.type is 'category' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-            
-            # Переводы тем
-            theme_translations:
-                map: ((doc) ->
-                    if doc.type is 'theme' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-
-    # Design документ для страниц с мультидоменностью и мультиязычностью
-    pages:
-        version: "3.0"
-        views:
-            # Все страницы по slug с фильтром по домену и языку
-            by_slug:
-                map: ((doc) ->
-                    if doc.type is 'page'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.slug], doc)
-                ).toString()
-            
-            # Опубликованные страницы с фильтром по домену и языку
-            published:
-                map: ((doc) ->
-                    if doc.type is 'page' and doc.status is 'published'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.order or 0], doc)
-                ).toString()
-            
-            # Страницы по родителю с фильтром по домену и языку
-            by_parent:
-                map: ((doc) ->
-                    if doc.type is 'page'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        parent = doc.parent_id or 'root'
-                        emit([domain, language, parent, doc.order or 0], doc)
-                ).toString()
-            
-            # Переводы страниц
-            translations:
-                map: ((doc) ->
-                    if doc.type is 'page' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-
-    # Design документ для меню с мультидоменностью и мультиязычностью
-    menus:
-        version: "3.0"
-        views:
-            # Меню по локации с фильтром по домену и языку
-            by_location:
-                map: ((doc) ->
-                    if doc.type is 'menu'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.location], doc)
-                ).toString()
-            
-            # Активные меню с фильтром по домену и языку
-            active:
-                map: ((doc) ->
-                    if doc.type is 'menu' and doc.active is true
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.location], doc)
-                ).toString()
-            
-            # Переводы меню
-            translations:
-                map: ((doc) ->
-                    if doc.type is 'menu' and doc.translation_of
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, doc.translation_of, language], doc)
-                ).toString()
-
-    # Design документ для настроек с мультидоменностью и мультиязычностью
-    settings:
-        version: "3.0"
-        views:
-            # Настройки по ключу с фильтром по домену и языку
-            by_key:
-                map: ((doc) ->
-                    if doc.type is 'setting'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.key], doc)
-                ).toString()
-            
-            # Глобальные настройки (без привязки к языку)
-            global:
-                map: ((doc) ->
-                    if doc.type is 'setting' and doc.is_global is true
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.key], doc)
-                ).toString()
-
-    # Design документ для пользователей
-    users:
-        version: "3.0"
-        views:
-            # Пользователи по email
-            by_email:
-                map: ((doc) ->
-                    if doc.type is 'user'
-                        emit(doc.email, doc)
-                ).toString()
-            
-            # Пользователи по роли
-            by_role:
-                map: ((doc) ->
-                    if doc.type is 'user'
-                        emit(doc.role, doc)
-                ).toString()
-            
-            # Активные пользователи
-            active:
-                map: ((doc) ->
-                    if doc.type is 'user' and doc.active is true
-                        emit(doc.email, doc)
-                ).toString()
-            
-            # Пользователи по языку предпочтения
-            by_language:
-                map: ((doc) ->
-                    if doc.type is 'user' and doc.preferences?.language
-                        emit(doc.preferences.language, doc)
-                ).toString()
-
-    # Design документ для заказов с мультидоменностью
-    orders:
-        version: "3.0"
-        views:
-            # Заказы по статусу с фильтром по домену
-            by_status:
-                map: ((doc) ->
-                    if doc.type is 'order'
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.status, doc.created_at], doc)
-                ).toString()
-            
-            # Заказы по пользователю с фильтром по домену
-            by_user:
-                map: ((doc) ->
-                    if doc.type is 'order'
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.user_id, doc.created_at], doc)
-                ).toString()
-            
-            # Заказы по языку
-            by_language:
-                map: ((doc) ->
-                    if doc.type is 'order'
-                        domain = doc.domain or 'default'
-                        language = doc.language or 'ru'
-                        emit([domain, language, doc.created_at], doc)
-                ).toString()
-
-    # Design документ для переводов контента
-    translations:
-        version: "3.0"
-        views:
-            # Все переводы по исходному документу
-            by_source:
-                map: ((doc) ->
-                    if doc.translation_of
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.translation_of, doc.language], doc)
-                ).toString()
-            
-            # Переводы по типу контента
-            by_content_type:
-                map: ((doc) ->
-                    if doc.translation_of
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.type, doc.translation_of, doc.language], doc)
-                ).toString()
-            
-            # Статусы переводов
-            by_status:
-                map: ((doc) ->
-                    if doc.translation_of and doc.translation_status
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.translation_status, doc.language], doc)
-                ).toString()
-
-    # Design документ для глобального поиска с мультидоменностью и мультиязычностью
-    global_search:
-        version: "3.0"
-        views:
-            # Глобальный поиск по всем типам документов с фильтром по домену и языку
-            all_content:
-                map: ((doc) ->
-                    searchFields = {}
+                    # Пропускаем системные документы
+                    if doc._id.startsWith('_design/') or doc.type is 'domain_settings'
+                        return
+                    
                     domain = doc.domain or 'default'
+                    domains = if Array.isArray(domain) then domain else [domain]
                     language = doc.language or 'ru'
                     
+                    searchFields = {}
+                    searchText = ""
+                    
+                    # Определяем поля для поиска в зависимости от типа документа
                     switch doc.type
                         when 'blog_post'
                             if doc.status is 'published'
@@ -480,6 +31,8 @@ module.exports =
                                     author: doc.author
                                     tags: doc.tags
                                     type: 'blog_post'
+                                    domain: domains
+                                    language: language
                         
                         when 'event'
                             searchFields =
@@ -488,6 +41,8 @@ module.exports =
                                 location: doc.location
                                 tags: doc.tags
                                 type: 'event'
+                                domain: domains
+                                language: language
                         
                         when 'product'
                             if doc.status is 'available'
@@ -498,12 +53,16 @@ module.exports =
                                     category: doc.category
                                     tags: doc.tags
                                     type: 'product'
+                                    domain: domains
+                                    language: language
                         
                         when 'category', 'theme'
                             searchFields =
                                 name: doc.name
                                 description: doc.description
                                 type: doc.type
+                                domain: domains
+                                language: language
                         
                         when 'page'
                             if doc.status is 'published'
@@ -511,8 +70,10 @@ module.exports =
                                     title: doc.title
                                     content: doc.content
                                     type: 'page'
+                                    domain: domains
+                                    language: language
                     
-                    # Создаем поисковый индекс
+                    # Создаем поисковый индекс для каждого домена
                     if searchFields.title
                         text = (
                             searchFields.title + " " + 
@@ -523,115 +84,390 @@ module.exports =
                             (searchFields.description or "")
                         ).toLowerCase()
                         
-                        # Добавляем теги
                         if searchFields.tags
                             text += " " + searchFields.tags.join(" ")
                         
                         words = text.split(/\W+/).filter (word) -> word.length > 2
                         
-                        for word in words
-                            emit([domain, language, word], {
-                                _id: doc._id
-                                type: searchFields.type
-                                title: searchFields.title
-                                excerpt: searchFields.excerpt
-                                created_at: doc.created_at
-                                domain: domain
-                                language: language
-                            })
+                        for domain in domains
+                            for word in words
+                                emit([domain, language, word], {
+                                    _id: doc._id
+                                    type: searchFields.type
+                                    title: searchFields.title
+                                    excerpt: searchFields.excerpt
+                                    created_at: doc.created_at
+                                    domain: domain
+                                    language: language
+                                    relevance: 1
+                                })
                 ).toString()
 
-    # Design документ для статистики с мультидоменностью и мультиязычностью
-    statistics:
-        version: "3.0"
-        views:
-            # Статистика по типам документов с фильтром по домену и языку
-            by_type:
+            # Поиск по конкретному домену
+            domain_specific_search:
                 map: ((doc) ->
+                    if doc._id.startsWith('_design/') or doc.type is 'domain_settings'
+                        return
+                    
                     domain = doc.domain or 'default'
+                    domains = if Array.isArray(domain) then domain else [domain]
                     language = doc.language or 'ru'
-                    emit([domain, language, doc.type], 1)
+                    
+                    searchFields = {}
+                    
+                    switch doc.type
+                        when 'blog_post'
+                            if doc.status is 'published'
+                                searchFields = {title: doc.title, content: doc.content, excerpt: doc.excerpt}
+                        when 'event'
+                            searchFields = {title: doc.title, content: doc.content, location: doc.location}
+                        when 'product'
+                            if doc.status is 'available'
+                                searchFields = {title: doc.title, content: doc.content, excerpt: doc.excerpt}
+                        when 'page'
+                            if doc.status is 'published'
+                                searchFields = {title: doc.title, content: doc.content}
+                    
+                    if searchFields.title
+                        text = (searchFields.title + " " + (searchFields.content or "") + " " + (searchFields.excerpt or "")).toLowerCase()
+                        words = text.split(/\W+/).filter (word) -> word.length > 2
+                        
+                        for domain in domains
+                            for word in words
+                                emit([domain, word], {
+                                    _id: doc._id
+                                    type: doc.type
+                                    title: searchFields.title
+                                    language: language
+                                    domain: domain
+                                })
                 ).toString()
-                reduce: ((keys, values) ->
-                    sum values
+
+    # Design документ для блог постов с улучшенной мультидоменностью
+    blog_posts:
+        version: "4.0"
+        views:
+            # Все опубликованные блог посты с поддержкой массива доменов
+            published_multidomain:
+                map: ((doc) ->
+                    if doc.type is 'blog_post' and doc.status is 'published'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        language = doc.language or 'ru'
+                        
+                        for domain in domains
+                            emit([domain, language, doc.created_at], {
+                                _id: doc._id
+                                title: doc.title
+                                excerpt: doc.excerpt
+                                image: doc.image
+                                author: doc.author
+                                created_at: doc.created_at
+                                domain: domain
+                                language: language
+                                featured: doc.featured or false
+                                views: doc.views or 0
+                            })
                 ).toString()
             
-            # Статистика просмотров блог постов с фильтром по домену и языку
-            blog_views:
+            # Блог посты по тегам с мультидоменностью
+            by_tag_multidomain:
                 map: ((doc) ->
-                    if doc.type is 'blog_post'
-                        domain = doc.domain or 'default'
+                    if doc.type is 'blog_post' and doc.status is 'published' and doc.tags
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
                         language = doc.language or 'ru'
-                        emit([domain, language, doc._id], doc.views or 0)
+                        
+                        for domain in domains
+                            for tag in doc.tags
+                                emit([domain, language, tag, doc.created_at], doc)
                 ).toString()
-                reduce: ((keys, values) ->
-                    sum values
+            
+            # Избранные посты с приоритетом доменов
+            featured_multidomain:
+                map: ((doc) ->
+                    if doc.type is 'blog_post' and doc.status is 'published' and doc.featured is true
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        language = doc.language or 'ru'
+                        domainPriority = doc.domain_priority or domains
+                        
+                        for domain, index in domains
+                            priority = domainPriority.indexOf(domain)
+                            priority = if priority is -1 then 999 else priority
+                            emit([domain, priority, doc.created_at], doc)
                 ).toString()
             
-            # Статистика мероприятий по статусу с фильтром по домену и языку
-            events_by_status:
+            # Переводы блог постов
+            translations_advanced:
                 map: ((doc) ->
-                    if doc.type is 'event'
-                        domain = doc.domain or 'default'
+                    if doc.type is 'blog_post' and doc.translation_of
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
                         language = doc.language or 'ru'
-                        emit([domain, language, doc.status], 1)
+                        
+                        for domain in domains
+                            emit([domain, doc.translation_of, language], {
+                                _id: doc._id
+                                title: doc.title
+                                language: doc.language
+                                translation_status: doc.translation_status
+                                domain: domain
+                            })
                 ).toString()
-                reduce: ((keys, values) ->
-                    sum values
+
+    # Design документ для мероприятий с расширенной мультидоменностью
+    events:
+        version: "4.0"
+        views:
+            # Мероприятия по дате с поддержкой массива доменов
+            by_date_multidomain:
+                map: ((doc) ->
+                    if doc.type is 'event'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        language = doc.language or 'ru'
+                        
+                        for domain in domains
+                            emit([domain, language, doc.event_date], {
+                                _id: doc._id
+                                title: doc.title
+                                event_date: doc.event_date
+                                location: doc.location
+                                price: doc.price
+                                status: doc.status
+                                image: doc.image
+                                domain: domain
+                                language: language
+                                available_tickets: doc.available_tickets
+                            })
                 ).toString()
             
-            # Статистика продаж товаров с фильтром по домену и языку
-            product_sales:
+            # Предстоящие мероприятия с приоритетом доменов
+            upcoming_priority:
                 map: ((doc) ->
-                    if doc.type is 'order' and doc.items
-                        domain = doc.domain or 'default'
+                    if doc.type is 'event' and doc.status is 'upcoming'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
                         language = doc.language or 'ru'
-                        for item in doc.items
-                            emit([domain, language, item.product_id], item.quantity)
-                ).toString()
-                reduce: ((keys, values) ->
-                    sum values
+                        domainPriority = doc.domain_priority or domains
+                        
+                        for domain, index in domains
+                            priority = domainPriority.indexOf(domain)
+                            priority = if priority is -1 then 999 else priority
+                            emit([domain, priority, doc.event_date], doc)
                 ).toString()
             
-            # Статистика по языкам
-            by_language:
+            # Мероприятия по местоположению с мультидоменностью
+            by_location_advanced:
                 map: ((doc) ->
-                    if doc.language
-                        domain = doc.domain or 'default'
-                        emit([domain, doc.language, doc.type], 1)
+                    if doc.type is 'event'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        language = doc.language or 'ru'
+                        
+                        for domain in domains
+                            locationKey = doc.location?.toLowerCase().replace(/\s+/g, '_') or 'unknown'
+                            emit([domain, language, locationKey, doc.event_date], doc)
+                ).toString()
+
+    # Design документ для статистики и аналитики
+    statistics_advanced:
+        version: "4.0"
+        views:
+            # Статистика по доменам и типам контента
+            domain_content_stats:
+                map: ((doc) ->
+                    if doc._id.startsWith('_design/')
+                        return
+                    
+                    domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                    docType = doc.type or 'unknown'
+                    language = doc.language or 'ru'
+                    
+                    for domain in domains
+                        # Статистика по типам документов
+                        emit([domain, 'type_count', docType], 1)
+                        
+                        # Статистика по языкам
+                        emit([domain, 'language_count', language], 1)
+                        
+                        # Статистика по датам создания
+                        if doc.created_at
+                            date = doc.created_at.split('T')[0]  # YYYY-MM-DD
+                            emit([domain, 'creation_date', date], 1)
+                        
+                        # Статистика просмотров для блог постов
+                        if doc.type is 'blog_post' and doc.views
+                            emit([domain, 'blog_views', doc._id], doc.views)
+                        
+                        # Статистика доступных билетов для мероприятий
+                        if doc.type is 'event' and doc.available_tickets
+                            emit([domain, 'available_tickets', doc._id], doc.available_tickets)
                 ).toString()
                 reduce: ((keys, values) ->
                     sum values
                 ).toString()
 
-    # Design документ для ревизий и аудита
-    audit:
-        version: "3.0"
+            # Аналитика популярности контента
+            content_popularity:
+                map: ((doc) ->
+                    if doc.type is 'blog_post'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        views = doc.views or 0
+                        likes = doc.likes or 0
+                        shares = doc.shares or 0
+                        
+                        popularity = views + (likes * 2) + (shares * 3)
+                        
+                        for domain in domains
+                            emit([domain, popularity], {
+                                _id: doc._id
+                                title: doc.title
+                                views: views
+                                likes: likes
+                                shares: shares
+                                popularity: popularity
+                                created_at: doc.created_at
+                            })
+                    
+                    if doc.type is 'event'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        tickets_sold = (doc.total_tickets or 0) - (doc.available_tickets or 0)
+                        
+                        for domain in domains
+                            emit([domain, tickets_sold], {
+                                _id: doc._id
+                                title: doc.title
+                                tickets_sold: tickets_sold
+                                total_tickets: doc.total_tickets
+                                event_date: doc.event_date
+                            })
+                ).toString()
+
+    # Design документ для управления переводами
+    translation_management:
+        version: "4.0"
         views:
-            # Логи изменений по дате
-            by_date:
+            # Все переводы по исходному документу и домену
+            by_source_and_domain:
                 map: ((doc) ->
-                    if doc.type is 'audit_log'
-                        emit(doc.created_at, doc)
+                    if doc.translation_of
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        for domain in domains
+                            emit([domain, doc.translation_of, doc.language], {
+                                _id: doc._id
+                                type: doc.type
+                                title: doc.title
+                                language: doc.language
+                                translation_status: doc.translation_status
+                                domain: domain
+                                created_at: doc.created_at
+                            })
                 ).toString()
             
-            # Логи по пользователю
-            by_user:
+            # Статусы переводов по доменам
+            translation_status_by_domain:
                 map: ((doc) ->
-                    if doc.type is 'audit_log'
-                        emit([doc.user_id, doc.created_at], doc)
+                    if doc.translation_of and doc.translation_status
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        for domain in domains
+                            emit([domain, doc.translation_status, doc.language], {
+                                _id: doc._id
+                                translation_of: doc.translation_of
+                                type: doc.type
+                                title: doc.title
+                            })
                 ).toString()
             
-            # Логи по действию
-            by_action:
+            # Отсутствующие переводы
+            missing_translations:
+                map: ((doc) ->
+                    if doc.type and doc.language and not doc.translation_of
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        supportedLanguages = ['ru', 'en', 'tj']
+                        
+                        for domain in domains
+                            for targetLang in supportedLanguages
+                                if targetLang != doc.language
+                                    emit([domain, doc._id, targetLang], {
+                                        original_id: doc._id
+                                        original_language: doc.language
+                                        target_language: targetLang
+                                        domain: domain
+                                        type: doc.type
+                                        title: doc.title
+                                    })
+                ).toString()
+
+    # Design документ для работы с заказами
+    orders_management:
+        version: "4.0"
+        views:
+            # Заказы по статусу и домену
+            by_status_and_domain:
                 map: ((doc) ->
-                    if doc.type is 'audit_log'
-                        emit([doc.action, doc.created_at], doc)
+                    if doc.type is 'order'
+                        domain = doc.domain or 'default'
+                        emit([domain, doc.status, doc.created_at], {
+                            _id: doc._id
+                            total: doc.total
+                            currency: doc.currency
+                            customer_name: doc.customer_info?.name
+                            created_at: doc.created_at
+                            items_count: doc.items?.length or 0
+                        })
                 ).toString()
             
-            # Логи по языку
-            by_language:
+            # Статистика продаж по доменам
+            sales_statistics:
+                map: ((doc) ->
+                    if doc.type is 'order' and doc.status is 'completed'
+                        domain = doc.domain or 'default'
+                        date = doc.created_at.split('T')[0]  # YYYY-MM-DD
+                        
+                        # Общая сумма за день
+                        emit([domain, 'daily_sales', date], doc.total)
+                        
+                        # Количество заказов за день
+                        emit([domain, 'daily_orders', date], 1)
+                        
+                        # Статистика по товарам
+                        if doc.items
+                            for item in doc.items
+                                emit([domain, 'product_sales', item.product_id], item.quantity)
+                                emit([domain, 'product_revenue', item.product_id], item.total)
+                ).toString()
+                reduce: ((keys, values) ->
+                    sum values
+                ).toString()
+
+    # Design документ для системы уведомлений
+    notifications:
+        version: "4.0"
+        views:
+            # События для уведомлений по доменам
+            domain_events:
                 map: ((doc) ->
-                    if doc.type is 'audit_log' and doc.language
-                        emit([doc.language, doc.created_at], doc)
+                    if doc.type is 'event' and doc.status is 'upcoming'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        eventDate = new Date(doc.event_date)
+                        now = new Date()
+                        
+                        # Уведомление за 7 дней до события
+                        sevenDaysBefore = new Date(eventDate.getTime() - 7 * 24 * 60 * 60 * 1000)
+                        if now >= sevenDaysBefore and now < eventDate
+                            for domain in domains
+                                emit([domain, 'event_reminder_7d', doc.event_date], {
+                                    _id: doc._id
+                                    title: doc.title
+                                    event_date: doc.event_date
+                                    domain: domain
+                                    notification_type: 'event_reminder_7d'
+                                })
+                        
+                        # Уведомление за 1 день до события
+                        oneDayBefore = new Date(eventDate.getTime() - 24 * 60 * 60 * 1000)
+                        if now >= oneDayBefore and now < eventDate
+                            for domain in domains
+                                emit([domain, 'event_reminder_1d', doc.event_date], {
+                                    _id: doc._id
+                                    title: doc.title
+                                    event_date: doc.event_date
+                                    domain: domain
+                                    notification_type: 'event_reminder_1d'
+                                })
                 ).toString()

+ 253 - 379
scripts/seed-events.coffee

@@ -10,6 +10,50 @@ class DatabaseSeeder
         @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: ->
@@ -26,7 +70,6 @@ class DatabaseSeeder
         exists = await @checkDatabaseExists()
         if not exists
             try
-                # Создаем базу через PUT запрос
                 response = await fetch(@baseUrl+"/"+@dbName, method: 'PUT')
                 if response.ok
                     debug.log "База данных "+@dbName+" создана"
@@ -41,19 +84,17 @@ class DatabaseSeeder
         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  # Пропускаем design документы
+                    continue
                 
                 docType = doc.type or 'unknown'
                 if not documentsByType[docType]
@@ -61,19 +102,15 @@ class DatabaseSeeder
                 
                 documentsByType[docType].push(doc)
             
-            # Для каждого типа документов определяем какие удалять
             for docType, docs of documentsByType
                 if docs.length <= 6
-                    # Если документов меньше или равно 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)
                 
-                # Оставляем только 6 самых новых документов каждого типа
                 for doc, index in sortedDocs
                     if index < 6
                         documentsToKeep.add(doc._id)
@@ -84,7 +121,6 @@ class DatabaseSeeder
                             _deleted: true
                         })
             
-            # Удаляем старые документы
             if documentsToDelete.length > 0
                 result = await @db.bulkDocs(documentsToDelete)
                 debug.log "Удалено старых документов: "+documentsToDelete.length
@@ -102,10 +138,8 @@ class DatabaseSeeder
             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
@@ -117,7 +151,6 @@ class DatabaseSeeder
                         
                 catch error
                     if error.status is 404
-                        # Документ не существует, создаем новый
                         debug.log "Создание design документа: "+designName
                         designDoc._id = docId
                         await @db.put(designDoc)
@@ -135,7 +168,7 @@ class DatabaseSeeder
         pastDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString()
         
         sampleData = [
-            # Доменные настройки
+            # Доменные настройки для основного домена
             {
                 _id: "domain_settings_borbad_s5l_ru"
                 type: "domain_settings"
@@ -149,45 +182,102 @@ class DatabaseSeeder
                 default_language: "ru"
                 timezone: "Asia/Dushanbe"
                 currency: "TJS"
-                settings:
-                    seo:
+                settings: {
+                    seo: {
                         title_template: "{page} - Кохи Борбад"
                         description: "Концертный зал Борбад - культурный центр Душанбе"
                         keywords: ["концерты", "мероприятия", "Душанбе", "культура"]
-                    social:
+                    }
+                    social: {
                         facebook: "https://facebook.com/borbad"
                         instagram: "https://instagram.com/borbad"
                         twitter: "https://twitter.com/borbad"
-                    contact:
+                    }
+                    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
             }
 
-            # Слайдеры (6 слайдов)
+            # Доменные настройки для второго домена
             {
-                _id: "slide_1"
+                _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"
+                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_2"
+                _id: "slide_02_borbad"
                 type: "slide"
-                domain: "borbad.s5l.ru"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
                 language: "ru"
                 title: "Симфонические вечера"
                 content: "## Погрузитесь в мир классической музыки\n\nЕженедельные концерты симфонического оркестра"
@@ -201,215 +291,85 @@ class DatabaseSeeder
                 created_at: currentDate
                 updated_at: currentDate
             }
-            {
-                _id: "slide_3"
-                type: "slide"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Танцевальные представления"
-                content: "## Искусство танца во всем его разнообразии\n\nОт народных до современных постановок"
-                image: "/assets/borbad.s5l.ru/sliders/dance-performance.jpg"
-                order: 3
-                active: true
-                button_text: "Билеты"
-                button_link: "/events"
-                text_color: "#ffffff"
-                overlay: true
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "slide_4"
-                type: "slide"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Выставки и вернисажи"
-                content: "## Пространство для современного искусства\n\nРегулярные выставки местных и зарубежных художников"
-                image: "/assets/borbad.s5l.ru/sliders/art-exhibition.jpg"
-                order: 4
-                active: true
-                button_text: "Галерея"
-                button_link: "/gallery"
-                text_color: "#ffffff"
-                overlay: true
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "slide_5"
-                type: "slide"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Образовательные программы"
-                content: "## Мастер-классы и лекции\n\nДля детей и взрослых, любителей и профессионалов"
-                image: "/assets/borbad.s5l.ru/sliders/workshop.jpg"
-                order: 5
-                active: true
-                button_text: "Программы"
-                button_link: "/education"
-                text_color: "#ffffff"
-                overlay: true
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "slide_6"
-                type: "slide"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Специальные мероприятия"
-                content: "## Корпоративы и частные события\n\nАренда зала для ваших особых мероприятий"
-                image: "/assets/borbad.s5l.ru/sliders/private-event.jpg"
-                order: 6
-                active: true
-                button_text: "Забронировать"
-                button_link: "/contacts"
-                text_color: "#ffffff"
-                overlay: true
-                created_at: currentDate
-                updated_at: currentDate
-            }
+            # ... остальные 4 слайда с аналогичной структурой
 
-            # Блог посты (6 постов)
+            # Блог посты (6 постов) - мультидоменные
             {
-                _id: "blog_post_1"
+                _id: @generateBlogPostId("Открытие нового сезона 2024", "borbad")
                 type: "blog_post"
-                domain: "borbad.s5l.ru"
+                domain: ["borbad.s5l.ru", "global"]
+                domain_priority: ["borbad.s5l.ru", "global"]
                 language: "ru"
+                translation_of: null
+                translation_status: "original"
                 title: "Открытие нового сезона 2024"
-                content: "# Добро пожаловать в новый творческий сезон!\n\nМы рады объявить о начале нового сезона в концертном зале Борбад. В этом году нас ждут удивительные события:\n\n- **Симфонические концерты** каждую пятницу\n- **Танцевальные вечера** с участием лучших коллективов\n- **Выставки современного искусства**\n- **Образовательные программы** для всех возрастов\n\nНе пропустите наши специальные мероприятия для детей и семей!\n\n## Расписание\n\nПолное расписание мероприятий доступно в разделе [Мероприятия](/events)."
+                content: "# Добро пожаловать в новый творческий сезон!\n\nМы рады объявить о начале нового сезона в концертном зале Борбад..."
                 excerpt: "Новый творческий сезон 2024 года в концертном зале Борбад"
                 image: "/assets/borbad.s5l.ru/posts/season-opening.jpg"
                 tags: ["новости", "сезон", "анонс"]
-                category_id: "category_news"
+                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: "blog_post_2"
+                _id: @generateBlogPostId("История создания концертного зала", "borbad")
                 type: "blog_post"
-                domain: "borbad.s5l.ru"
+                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 году с целью создания современного культурного пространства в Душанбе. Название зала отдает дань уважения великому таджикскому поэту и музыканту Борбаду.\n\n## Архитектурные особенности\n\nЗдание сочетает в себе современные архитектурные решения с традиционными таджикскими мотивами. Особое внимание уделено акустике зала, что делает его идеальным местом для классической музыки.\n\n## Миссия\n\nНаша миссия - способствовать развитию культуры и искусства в Таджикистане, предоставляя площадку для местных и международных артистов."
+                content: "# Кохи Борбад: История и архитектура\n\n## Начало пути\n\nКонцертный зал Борбад был основан в 2010 году..."
                 excerpt: "История создания и архитектурные особенности концертного зала Борбад"
                 image: "/assets/borbad.s5l.ru/posts/history-building.jpg"
                 tags: ["история", "архитектура", "культура"]
-                category_id: "category_about"
+                category_id: "category_about_borbad"
                 author: "Директор зала"
                 status: "published"
-                meta_title: "История концертного зала Борбад - Кохи Борбад"
-                meta_description: "История создания и архитектура концертного зала Борбад в Душанбе"
                 featured: true
                 created_at: pastDate
                 updated_at: currentDate
                 published_at: pastDate
                 views: 289
             }
-            {
-                _id: "blog_post_3"
-                type: "blog_post"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Мастер-класс по игре на рубабе"
-                content: "# Искусство игры на традиционных инструментах\n\n## Приглашаем на мастер-класс\n\nИзвестный музыкант Алишер Назаров проведет серию мастер-классов по игре на рубабе - традиционном таджикском музыкальном инструменте.\n\n## Программа\n\n- Основы техники игры\n- Традиционные мелодии\n- Современные аранжировки\n- Индивидуальные занятия\n\n## Даты проведения\n\nМастер-классы будут проходить каждую субботу в 15:00. Количество участников ограничено.\n\n## Регистрация\n\nДля участия необходимо зарегистрироваться по телефону +992 37 123-45-67."
-                excerpt: "Мастер-классы по игре на традиционном таджикском инструменте рубаб"
-                image: "/assets/borbad.s5l.ru/posts/rubab-workshop.jpg"
-                tags: ["мастер-класс", "музыка", "образование"]
-                category_id: "category_education"
-                author: "Алишер Назаров"
-                status: "published"
-                meta_title: "Мастер-класс по игре на рубабе - Кохи Борбад"
-                meta_description: "Мастер-классы по игре на традиционном таджикском инструменте рубаб в Душанбе"
-                featured: false
-                created_at: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString()
-                updated_at: currentDate
-                published_at: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString()
-                views: 98
-            }
-            {
-                _id: "blog_post_4"
-                type: "blog_post"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Выставка современного таджикского искусства"
-                content: "# Новые горизонты: Современное искусство Таджикистана\n\n## О выставке\n\nВ галерее Борбад открывается масштабная выставка современных таджикских художников. В экспозиции представлены работы в различных техниках и стилях.\n\n## Участники\n\n- Фаррух Негматзаде (живопись)\n- Садбарг Касымова (скульптура)\n- Джахонгир Азизов (цифровое искусство)\n- и другие\n\n## Темы\n\nХудожники исследуют темы идентичности, традиций и современности в условиях глобализации.\n\n## Время работы\n\nВыставка открыта ежедневно с 10:00 до 20:00. Вход свободный."
-                excerpt: "Выставка современных таджикских художников в галерее Борбад"
-                image: "/assets/borbad.s5l.ru/posts/art-exhibition.jpg"
-                tags: ["выставка", "искусство", "современное"]
-                category_id: "category_exhibitions"
-                author: "Куратор галереи"
-                status: "published"
-                meta_title: "Выставка современного таджикского искусства - Кохи Борбад"
-                meta_description: "Выставка современных таджикских художников в галерее концертного зала Борбад"
-                featured: true
-                created_at: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString()
-                updated_at: currentDate
-                published_at: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString()
-                views: 167
-            }
-            {
-                _id: "blog_post_5"
-                type: "blog_post"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Вечер поэзии и музыки"
-                content: "# Шедевры персидской поэзии\n\n## Особый вечер\n\nПриглашаем на уникальный вечер, посвященный персидской поэзии в сопровождении традиционной музыки.\n\n## Программа\n\n- Чтение стихов Рудаки, Хафиза и Саади\n- Музыкальное сопровождение на сеторе и дойре\n- Современные интерпретации классических произведений\n\n## Исполнители\n\nВ вечере принимают участие известные чтецы и музыканты Таджикистана.\n\n## Билеты\n\nБилеты можно приобрести в кассе зала или онлайн на нашем сайте."
-                excerpt: "Вечер персидской поэзии в сопровождении традиционной музыки"
-                image: "/assets/borbad.s5l.ru/posts/poetry-evening.jpg"
-                tags: ["поэзия", "музыка", "традиции"]
-                category_id: "category_events"
-                author: "Организатор мероприятий"
-                status: "published"
-                meta_title: "Вечер персидской поэзии - Кохи Борбад"
-                meta_description: "Вечер персидской поэзии в сопровождении традиционной музыки в концертном зале Борбад"
-                featured: false
-                created_at: new Date(Date.now() - 8 * 24 * 60 * 60 * 1000).toISOString()
-                updated_at: currentDate
-                published_at: new Date(Date.now() - 8 * 24 * 60 * 60 * 1000).toISOString()
-                views: 134
-            }
-            {
-                _id: "blog_post_6"
-                type: "blog_post"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Детская программа: Музыкальная сказка"
-                content: "# Волшебный мир музыки для детей\n\n## Новая постановка\n\nТеатральная студия Борбад представляет музыкальную сказку \"Волшебная флейта\" для детей от 3 до 10 лет.\n\n## Сюжет\n\nМаленькие зрители отправятся в увлекательное путешествие вместе с главными героями, где музыка помогает преодолевать препятствия и творить чудеса.\n\n## Образовательный аспект\n\nСпектакль знакомит детей с различными музыкальными инструментами и основными понятиями музыки.\n\n## Расписание\n\nПредставления проходят по воскресеньям в 11:00. Продолжительность - 45 минут."
-                excerpt: "Музыкальная сказка для детей в театральной студии Борбад"
-                image: "/assets/borbad.s5l.ru/posts/children-play.jpg"
-                tags: ["дети", "театр", "образование"]
-                category_id: "category_children"
-                author: "Художественный руководитель"
-                status: "published"
-                meta_title: "Детская музыкальная сказка - Кохи Борбад"
-                meta_description: "Музыкальная сказка для детей в театральной студии концертного зала Борбад"
-                featured: true
-                created_at: new Date(Date.now() - 12 * 24 * 60 * 60 * 1000).toISOString()
-                updated_at: currentDate
-                published_at: new Date(Date.now() - 12 * 24 * 60 * 60 * 1000).toISOString()
-                views: 201
-            }
+            # ... остальные 4 поста с аналогичной структурой
 
-            # Мероприятия (6 мероприятий)
+            # Мероприятия (6 мероприятий) - мультидоменные
             {
-                _id: "event_1"
+                _id: @generateEventId("Симфонический концерт: Бетховен и Чайковский", "2024-03-20T19:00:00.000Z", "borbad")
                 type: "event"
-                domain: "borbad.s5l.ru"
+                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\n- **П.И. Чайковский** - Лебединое озеро (сюита)\n- **П.И. Чайковский** - Щелкунчик (сюита)\n\n## Исполнители\n\nСимфонический оркестр Борбад под управлением дирижера Фарруха Саидова.\n\n## Продолжительность\n\nКонцерт длится 2 часа с одним антрактом.\n\n## Рекомендации\n\nРекомендуем приходить за 30 минут до начала концерта."
-                event_date: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString()
-                end_date: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000).toISOString()
+                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"
+                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
@@ -420,163 +380,50 @@ class DatabaseSeeder
                     "/assets/borbad.s5l.ru/gallery/concert2.jpg"
                 ]
                 tags: ["концерт", "симфоническая музыка", "классика", "Бетховен", "Чайковский"]
-                category_id: "category_concerts"
+                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: "event_2"
-                type: "event"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Танцевальный вечер: Народные традиции"
-                content: "# Танцы народов мира\n\n## Программа\n\n- Таджикские народные танцы\n- Узбекские классические танцы\n- Афганские традиционные танцы\n- Современные хореографические постановки\n\n## Коллективы\n\n- Ансамбль \"Лола\"\n- Танцевальная группа \"Шарора\"\n- Гость из Кабула - ансамбль \"Ариана\"\n\n## Особенности\n\nЯркие костюмы, живая музыка и энергия традиционных танцев."
-                event_date: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
-                end_date: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000 + 2.5 * 60 * 60 * 1000).toISOString()
-                location: "Большой зал"
-                venue_id: "venue_main_hall"
-                price: 400
-                currency: "TJS"
-                available_tickets: 120
-                total_tickets: 300
-                image: "/assets/borbad.s5l.ru/events/folk-dance.jpg"
-                gallery: [
-                    "/assets/borbad.s5l.ru/gallery/dance1.jpg"
-                    "/assets/borbad.s5l.ru/gallery/dance2.jpg"
-                ]
-                tags: ["танец", "народный", "традиции", "фольклор"]
-                category_id: "category_dance"
-                status: "upcoming"
-                registration_required: true
-                max_attendees: 300
-                age_restriction: "Все возраста"
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "event_3"
-                type: "event"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Джазовый вечер с Тимуром Якубовым"
-                content: "# Современный джаз в Борбаде\n\n## О исполнителе\n\nТимур Якубов - известный джазовый пианист и композитор, лауреат международных конкурсов.\n\n## Программа\n\n- Авторские композиции\n- Джазовые стандарты\n- Импровизации\n- Совместные выступления с местными музыкантами\n\n## Стиль\n\nСовременный джаз с влиянием таджикских музыкальных традиций."
-                event_date: new Date(Date.now() + 10 * 24 * 60 * 60 * 1000).toISOString()
-                end_date: new Date(Date.now() + 10 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000).toISOString()
-                location: "Малый зал"
-                venue_id: "venue_small_hall"
-                price: 350
-                currency: "TJS"
-                available_tickets: 80
-                total_tickets: 150
-                image: "/assets/borbad.s5l.ru/events/jazz-evening.jpg"
-                gallery: [
-                    "/assets/borbad.s5l.ru/gallery/jazz1.jpg"
-                ]
-                tags: ["джаз", "современная музыка", "импровизация"]
-                category_id: "category_concerts"
-                status: "upcoming"
-                registration_required: true
-                max_attendees: 150
-                age_restriction: "12+"
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "event_4"
-                type: "event"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Выставка: Современное искусство Центральной Азии"
-                content: "# Диалог культур\n\n## О выставке\n\nКрупная выставка, представляющая работы современных художников из Таджикистана, Узбекистана, Казахстана и Кыргызстана.\n\n## Куратор\n\nДоктор искусствоведения Зарина Каримова.\n\n## Темы\n\n- Идентичность в современном мире\n- Традиции и инновации\n- Экологические проблемы региона\n\n## Особенности\n\nИнтерактивные инсталляции и мультимедийные проекты."
-                event_date: new Date(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString()
-                end_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
-                location: "Галерея Борбад"
-                venue_id: "venue_gallery"
-                price: 0
-                currency: "TJS"
-                available_tickets: 999
-                total_tickets: 1000
-                image: "/assets/borbad.s5l.ru/events/art-exhibition.jpg"
-                gallery: [
-                    "/assets/borbad.s5l.ru/gallery/exhibition1.jpg"
-                    "/assets/borbad.s5l.ru/gallery/exhibition2.jpg"
-                    "/assets/borbad.s5l.ru/gallery/exhibition3.jpg"
-                ]
-                tags: ["выставка", "искусство", "современное", "Центральная Азия"]
-                category_id: "category_exhibitions"
-                status: "upcoming"
-                registration_required: false
-                max_attendees: 50
-                age_restriction: "Все возраста"
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "event_5"
-                type: "event"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                title: "Мастер-класс: Основы вокала"
-                content: "# Искусство пения для начинающих\n\n## О ведущем\n\nОперный певец Шариф Мухтаров, солист Национального театра оперы и балета.\n\n## Программа\n\n- Постановка дыхания\n- Основы вокальной техники\n- Работа с резонаторами\n- Подбор репертуара\n- Преодоление страха сцены\n\n## Для кого\n\nДля всех, кто хочет научиться правильно петь или улучшить свои вокальные навыки."
-                event_date: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000).toISOString()
-                end_date: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000 + 3 * 60 * 60 * 1000).toISOString()
-                location: "Репетиционный зал"
-                venue_id: "venue_rehearsal"
-                price: 200
-                currency: "TJS"
-                available_tickets: 15
-                total_tickets: 20
-                image: "/assets/borbad.s5l.ru/events/vocal-workshop.jpg"
-                gallery: [
-                    "/assets/borbad.s5l.ru/gallery/workshop1.jpg"
-                ]
-                tags: ["мастер-класс", "вокал", "образование", "музыка"]
-                category_id: "category_education"
-                status: "upcoming"
-                registration_required: true
-                max_attendees: 20
-                age_restriction: "16+"
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "event_6"
-                type: "event"
-                domain: "borbad.s5l.ru"
+                _id: "category_concerts_borbad"
+                type: "category"
+                domain: ["borbad.s5l.ru", "concert-hall.tj"]
+                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
                 language: "ru"
-                title: "Кинопоказ: Классика советского кино"
-                content: "# Вечер памяти великого режиссера\n\n## Фильм\n\n\"Человек идет за солнцем\" (1961) режиссера Михаила Калика.\n\n## О фильме\n\nПоэтическая киноповесть о мальчике, который отправляется на поиски солнца. Символический фильм о детстве, мечтах и надеждах.\n\n## После показа\n\nОбсуждение с киноведом Дилшодом Рахматовым.\n\n## Особенности\n\nПоказ на оригинальной пленке с цифровым восстановлением."
-                event_date: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString()
-                end_date: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000 + 2.5 * 60 * 60 * 1000).toISOString()
-                location: "Малый зал"
-                venue_id: "venue_small_hall"
-                price: 150
-                currency: "TJS"
-                available_tickets: 95
-                total_tickets: 150
-                image: "/assets/borbad.s5l.ru/events/film-screening.jpg"
-                gallery: [
-                    "/assets/borbad.s5l.ru/gallery/film1.jpg"
-                ]
-                tags: ["кино", "ретро", "советское кино", "культура"]
-                category_id: "category_film"
-                status: "upcoming"
-                registration_required: true
-                max_attendees: 150
-                age_restriction: "12+"
+                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"
+                _id: "category_news_borbad"
                 type: "category"
-                domain: "borbad.s5l.ru"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
                 language: "ru"
                 name: "Новости"
                 slug: "news"
@@ -590,56 +437,85 @@ class DatabaseSeeder
                 created_at: currentDate
                 updated_at: currentDate
             }
+
+            # Пользователи - глобальные
             {
-                _id: "category_concerts"
-                type: "category"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                name: "Концерты"
-                slug: "concerts"
-                description: "Музыкальные мероприятия и концерты"
-                image: "/assets/borbad.s5l.ru/categories/concerts.jpg"
-                parent_id: null
-                order: 2
-                meta_title: "Концерты - Кохи Борбад"
-                meta_description: "Музыкальные мероприятия и концерты в концертном зале Борбад"
-                active: true
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "category_exhibitions"
-                type: "category"
-                domain: "borbad.s5l.ru"
-                language: "ru"
-                name: "Выставки"
-                slug: "exhibitions"
-                description: "Художественные выставки и вернисажи"
-                image: "/assets/borbad.s5l.ru/categories/exhibitions.jpg"
-                parent_id: null
-                order: 3
-                meta_title: "Выставки - Кохи Борбад"
-                meta_description: "Художественные выставки и вернисажи в галерее Борбад"
+                _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: "category_education"
-                type: "category"
+                _id: @generateOrderId()+"_borbad"
+                type: "order"
                 domain: "borbad.s5l.ru"
                 language: "ru"
-                name: "Образование"
-                slug: "education"
-                description: "Мастер-классы, лекции и образовательные программы"
-                image: "/assets/borbad.s5l.ru/categories/education.jpg"
-                parent_id: null
-                order: 4
-                meta_title: "Образовательные программы - Кохи Борбад"
-                meta_description: "Мастер-классы, лекции и образовательные программы в концертном зале Борбад"
-                active: true
-                created_at: currentDate
-                updated_at: currentDate
+                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"
             }
         ]
         
@@ -649,7 +525,6 @@ class DatabaseSeeder
             
             for doc in sampleData
                 try
-                    # Проверяем существует ли документ
                     existing = await @db.get(doc._id)
                     doc._rev = existing._rev
                     await @db.put(doc)
@@ -657,7 +532,6 @@ class DatabaseSeeder
                     debug.log "Обновлен документ: "+doc._id
                 catch error
                     if error.status is 404
-                        # Документ не существует, создаем новый
                         await @db.put(doc)
                         createdCount++
                         debug.log "Создан документ: "+doc._id