Gogs пре 3 недеља
родитељ
комит
51c8c22377
3 измењених фајлова са 837 додато и 639 уклоњено
  1. 69 33
      README.md
  2. 326 361
      scripts/design-documents.coffee
  3. 442 245
      scripts/seed-events.coffee

+ 69 - 33
README.md

@@ -1,6 +1,39 @@
 # Текущая ззадача
-доработай seed-events.coffee и design-documents.coffee, с  учетом что категории имеют иеархическую структуру
-приведи также структуру ихменённых типов документов.
+доработай # Структура хранимых данных ## Описание всех хранимых объектов
+взяв за основу объёкт записи блога:
+{
+    _id: "blog_post_season_opening_2024_borbad"
+    type: "blog_post"
+    domain: ["borbad.s5l.ru", "global"] # определяет приоритет доменов по порядку 
+    language: ["ru","en"]
+    title: ["Открытие нового сезона 2024","Opening of the new season 2024"]
+    content: ["# Добро пожаловать в новый творческий сезон!...","# Welcome to the new creative season!..."]
+    excerpt: ["Новый творческий сезон 2024 года в концертном зале Борбад","A new creative season in 2024 at the Borbad Concert Hall"]
+    seo: {
+            description: ["Концертный зал Борбад - культурный центр Душанбе","Borbad Concert Hall - Dushanbe Cultural Center"]
+            keywords: [["концерты", "мероприятия", "Душанбе", "культура"],["concerts", "events", "Dushanbe", "culture"]]
+        }
+    image: ["/assets/borbad.s5l.ru/events/beethoven-concert.jpg","/assets/borbad.s5l.ru/events/beethoven-concert.jpg"]
+    gallery: [[
+        "/assets/borbad.s5l.ru/gallery/concert1.jpg"
+        "/assets/borbad.s5l.ru/gallery/concert2.jpg"
+    ],[
+        "/assets/borbad.s5l.ru/gallery/concert1.jpg"
+        "/assets/borbad.s5l.ru/gallery/concert2.jpg"
+    ]]
+    tags: [["новости", "сезон", "анонс"],["news", "season", "announcement"]]
+    category_id: "category_news_borbad"                    # ID конечной категории
+    category_path: ["category_news_borbad"]                # Полный путь категории
+    author: ["Администрация Борбад","Borbad Administration"]
+    status: "published"
+    featured: true
+    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
+}
+
+Отальные оъекты переделать по данному примеру, приэтом объекты товаров событий и слайдеров, будут объектами которые хранять только дополнительные поля к документу блогу.
 
 # файл с правилами
 https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/raw/master/README.md
@@ -239,7 +272,7 @@ app/
             ├── index.styl
 
 # Структура хранимых данных
-## Описание всех хранимых объектов с мультиязычностью
+## Описание всех хранимых объектов
 
 1. Настройки домена (domain_settings)
 coffee
@@ -286,30 +319,31 @@ coffee
 {
     _id: "blog_post_season_opening_2024_borbad"
     type: "blog_post"
-    domain: ["borbad.s5l.ru", "global"]                     # Принадлежит нескольким доменам
-    domain_priority: ["borbad.s5l.ru", "global"]           # Приоритет доменов
+    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Мы рады объявить о начале..."
+    content: "# Добро пожаловать в новый творческий сезон!..."
     excerpt: "Новый творческий сезон 2024 года в концертном зале Борбад"
-    image: "/assets/borbad.s5l.ru/posts/season-opening.jpg"
+    seo: {
+            description: "Концертный зал Борбад - культурный центр Душанбе"
+            keywords: ["концерты", "мероприятия", "Душанбе", "культура"]
+        }
+    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_news_borbad"
+    category_id: "category_news_borbad"                    # ID конечной категории
+    category_path: ["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
 }
 3. Мероприятия (event) - мультидоменные
 coffee
@@ -346,7 +380,8 @@ coffee
         "/assets/borbad.s5l.ru/gallery/concert2.jpg"
     ]
     tags: ["концерт", "симфоническая музыка", "классика", "Бетховен", "Чайковский"]
-    category_id: "category_concerts_borbad"
+    category_id: "category_classical_music_concerts_events_borbad"  # ID конечной категории
+    category_path: ["category_events_borbad", "category_concerts_events_borbad", "category_classical_music_concerts_events_borbad"]  # Полный путь
     status: "upcoming"
     registration_required: true
     max_attendees: 300
@@ -440,28 +475,29 @@ coffee
 6. Категории (category) - мультидоменные
 coffee
 {
-    _id: "category_concerts_borbad"
+    _id: "category_classical_music_concerts_events_borbad"
     type: "category"
-    domain: ["borbad.s5l.ru", "concert-hall.tj"]          # Общая категория для доменов
+    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: "Музыкальные мероприятия и концерты в концертном зале Борбад"
+    name: "Классическая музыка"
+    slug: "classical-music"
+    description: "Симфонические концерты и классические произведения"
+    image: "/assets/borbad.s5l.ru/categories/classical-music.jpg"
+    icon: "classical"
+    parent_id: "category_concerts_events_borbad"           # ID родительской категории
+    parent_path: ["category_events_borbad", "category_concerts_events_borbad"]  # Полный путь от корня
+    level: 2                                               # Уровень в иерархии (0 - корень)
+    order: 1
+    children_count: 0                                      # Количество дочерних категорий
+    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"
+    menu_order: 1
+    color: "#3B82F6"
+    created_at: "2024-01-15T10:00:00.000Z"
     updated_at: "2024-01-15T10:00:00.000Z"
 }
 7. Темы (theme) - мультидоменные

+ 326 - 361
scripts/design-documents.coffee

@@ -1,473 +1,438 @@
-# Design документы для CouchDB с поддержкой мультидоменности и мультиязычности
-# Версия 4.0 - с учетом последних изменений в правилах
+# Design документы для CouchDB с поддержкой иерархических категорий
+# Версия 5.0 - с иерархической структурой категорий
 
 module.exports =
-    # Design документ для мультидоменного поиска
-    multi_domain_search:
-        version: "4.0"
+    # Design документ для работы с иерархическими категориями
+    categories_hierarchical:
+        version: "5.0"
         views:
-            # Универсальный поиск по всем доменам и языкам
-            universal_search:
+            # Все категории по уровню иерархии
+            by_level:
                 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'
-                    
-                    searchFields = {}
-                    searchText = ""
-                    
-                    # Определяем поля для поиска в зависимости от типа документа
-                    switch doc.type
-                        when 'blog_post'
-                            if doc.status is 'published'
-                                searchFields =
-                                    title: doc.title
-                                    content: doc.content
-                                    excerpt: doc.excerpt
-                                    author: doc.author
-                                    tags: doc.tags
-                                    type: 'blog_post'
-                                    domain: domains
-                                    language: language
-                        
-                        when 'event'
-                            searchFields =
-                                title: doc.title
-                                content: doc.content
-                                location: doc.location
-                                tags: doc.tags
-                                type: 'event'
-                                domain: domains
-                                language: language
-                        
-                        when 'product'
-                            if doc.status is 'available'
-                                searchFields =
-                                    title: doc.title
-                                    content: doc.content
-                                    excerpt: doc.excerpt
-                                    category: doc.category
-                                    tags: doc.tags
-                                    type: 'product'
-                                    domain: domains
-                                    language: language
+                    if doc.type is 'category'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        level = doc.level or 0
                         
-                        when 'category', 'theme'
-                            searchFields =
+                        for domain in domains
+                            emit([domain, level, doc.order], {
+                                _id: doc._id
                                 name: doc.name
-                                description: doc.description
-                                type: doc.type
-                                domain: domains
-                                language: language
-                        
-                        when 'page'
-                            if doc.status is 'published'
-                                searchFields =
-                                    title: doc.title
-                                    content: doc.content
-                                    type: 'page'
-                                    domain: domains
-                                    language: language
-                    
-                    # Создаем поисковый индекс для каждого домена
-                    if searchFields.title
-                        text = (
-                            searchFields.title + " " + 
-                            (searchFields.content or "") + " " +
-                            (searchFields.excerpt or "") + " " +
-                            (searchFields.author or "") + " " +
-                            (searchFields.location or "") + " " +
-                            (searchFields.description or "")
-                        ).toLowerCase()
-                        
-                        if searchFields.tags
-                            text += " " + searchFields.tags.join(" ")
-                        
-                        words = text.split(/\W+/).filter (word) -> word.length > 2
+                                slug: doc.slug
+                                parent_id: doc.parent_id
+                                level: level
+                                order: doc.order
+                                active: doc.active
+                                featured: doc.featured
+                                show_in_menu: doc.show_in_menu
+                            })
+                ).toString()
+            
+            # Категории по родителю (для построения дерева)
+            by_parent:
+                map: ((doc) ->
+                    if doc.type is 'category'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        parent_id = doc.parent_id or 'root'
                         
                         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
-                                })
+                            emit([domain, parent_id, doc.order], {
+                                _id: doc._id
+                                name: doc.name
+                                slug: doc.slug
+                                level: doc.level
+                                children_count: doc.children_count
+                                order: doc.order
+                                active: doc.active
+                            })
                 ).toString()
-
-            # Поиск по конкретному домену
-            domain_specific_search:
+            
+            # Полное дерево категорий с путями
+            by_path:
                 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'
-                    
-                    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
+                    if doc.type is 'category'
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        parent_path = doc.parent_path or []
                         
                         for domain in domains
-                            for word in words
-                                emit([domain, word], {
-                                    _id: doc._id
-                                    type: doc.type
-                                    title: searchFields.title
-                                    language: language
-                                    domain: domain
-                                })
+                            # Эмитим каждый сегмент пути для быстрого поиска
+                            for path_segment, index in parent_path
+                                emit([domain, path_segment, doc.level, doc.order], doc)
+                            
+                            # Эмитим саму категорию
+                            emit([domain, doc._id, doc.level, doc.order], doc)
                 ).toString()
-
-    # Design документ для блог постов с улучшенной мультидоменностью
-    blog_posts:
-        version: "4.0"
-        views:
-            # Все опубликованные блог посты с поддержкой массива доменов
-            published_multidomain:
+            
+            # Корневые категории
+            root_categories:
                 map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published'
+                    if doc.type is 'category' and (not doc.parent_id or doc.parent_id is null)
                         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], {
+                            emit([domain, doc.order], {
                                 _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
+                                name: doc.name
+                                slug: doc.slug
+                                level: 0
+                                children_count: doc.children_count
+                                order: doc.order
+                                active: doc.active
+                                featured: doc.featured
                             })
                 ).toString()
             
-            # Блог посты по тегам с мультидоменностью
-            by_tag_multidomain:
+            # Категории для меню
+            menu_categories:
                 map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published' and doc.tags
+                    if doc.type is 'category' and doc.show_in_menu is true
                         domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
-                        language = doc.language or 'ru'
+                        level = doc.level or 0
                         
                         for domain in domains
-                            for tag in doc.tags
-                                emit([domain, language, tag, doc.created_at], doc)
+                            emit([domain, level, doc.menu_order or doc.order], {
+                                _id: doc._id
+                                name: doc.name
+                                slug: doc.slug
+                                parent_id: doc.parent_id
+                                level: level
+                                menu_order: doc.menu_order
+                                icon: doc.icon
+                                color: doc.color
+                            })
                 ).toString()
-            
-            # Избранные посты с приоритетом доменов
-            featured_multidomain:
+
+    # Design документ для контента с иерархическими категориями
+    content_with_hierarchical_categories:
+        version: "5.0"
+        views:
+            # Контент по полному пути категории
+            by_category_path:
                 map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.status is 'published' and doc.featured is true
+                    if (doc.type is 'blog_post' or doc.type is 'event') and doc.category_path
                         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)
+                        for domain in domains
+                            # Эмитим для каждого сегмента пути категории
+                            for category_id in doc.category_path
+                                emit([domain, category_id, doc.created_at], {
+                                    _id: doc._id
+                                    type: doc.type
+                                    title: doc.title
+                                    category_id: doc.category_id
+                                    category_path: doc.category_path
+                                    created_at: doc.created_at
+                                    status: doc.status
+                                    featured: doc.featured
+                                })
                 ).toString()
             
-            # Переводы блог постов
-            translations_advanced:
+            # Контент по конечной категории (самой глубокой)
+            by_leaf_category:
                 map: ((doc) ->
-                    if doc.type is 'blog_post' and doc.translation_of
+                    if (doc.type is 'blog_post' or doc.type is 'event') and doc.category_path
                         domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
-                        language = doc.language or 'ru'
+                        leaf_category = doc.category_path[doc.category_path.length - 1]
                         
                         for domain in domains
-                            emit([domain, doc.translation_of, language], {
+                            emit([domain, leaf_category, doc.created_at], {
                                 _id: doc._id
+                                type: doc.type
                                 title: doc.title
-                                language: doc.language
-                                translation_status: doc.translation_status
-                                domain: domain
+                                category_id: doc.category_id
+                                created_at: doc.created_at
+                                status: doc.status
                             })
                 ).toString()
-
-    # Design документ для мероприятий с расширенной мультидоменностью
-    events:
-        version: "4.0"
-        views:
-            # Мероприятия по дате с поддержкой массива доменов
-            by_date_multidomain:
+            
+            # Контент по корневой категории
+            by_root_category:
                 map: ((doc) ->
-                    if doc.type is 'event'
+                    if (doc.type is 'blog_post' or doc.type is 'event') and doc.category_path
                         domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
-                        language = doc.language or 'ru'
+                        root_category = doc.category_path[0]
                         
                         for domain in domains
-                            emit([domain, language, doc.event_date], {
+                            emit([domain, root_category, doc.created_at], {
                                 _id: doc._id
+                                type: doc.type
                                 title: doc.title
-                                event_date: doc.event_date
-                                location: doc.location
-                                price: doc.price
+                                root_category: root_category
+                                created_at: doc.created_at
                                 status: doc.status
-                                image: doc.image
-                                domain: domain
-                                language: language
-                                available_tickets: doc.available_tickets
                             })
                 ).toString()
-            
-            # Предстоящие мероприятия с приоритетом доменов
-            upcoming_priority:
+
+    # Design документ для поиска с учетом иерархии категорий
+    search_with_category_hierarchy:
+        version: "5.0"
+        views:
+            # Поиск по контенту с информацией о категории
+            content_with_category_info:
                 map: ((doc) ->
-                    if doc.type is 'event' and doc.status is 'upcoming'
+                    if (doc.type is 'blog_post' and doc.status is 'published') or doc.type is 'event'
                         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.event_date], doc)
+                        search_text = (doc.title + " " + (doc.content or "") + " " + (doc.excerpt or "")).toLowerCase()
+                        words = search_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: doc.title
+                                    excerpt: doc.excerpt
+                                    category_id: doc.category_id
+                                    category_path: doc.category_path
+                                    created_at: doc.created_at
+                                    domain: domain
+                                })
                 ).toString()
             
-            # Мероприятия по местоположению с мультидоменностью
-            by_location_advanced:
+            # Поиск по категориям и тегам
+            by_category_and_tags:
                 map: ((doc) ->
-                    if doc.type is 'event'
+                    if (doc.type is 'blog_post' and doc.status is 'published') or 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)
+                            # По категории
+                            if doc.category_id
+                                emit([domain, 'category', doc.category_id, doc.created_at], {
+                                    _id: doc._id
+                                    type: doc.type
+                                    title: doc.title
+                                })
+                            
+                            # По тегам
+                            if doc.tags
+                                for tag in doc.tags
+                                    emit([domain, 'tag', tag, doc.created_at], {
+                                        _id: doc._id
+                                        type: doc.type
+                                        title: doc.title
+                                    })
                 ).toString()
 
-    # Design документ для статистики и аналитики
-    statistics_advanced:
-        version: "4.0"
+    # Design документ для статистики иерархических категорий
+    category_statistics:
+        version: "5.0"
         views:
-            # Статистика по доменам и типам контента
-            domain_content_stats:
+            # Статистика контента по категориям
+            content_count_by_category:
                 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 'blog_post' or doc.type is 'event') and doc.category_id
+                        domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
                         
-                        # Статистика доступных билетов для мероприятий
-                        if doc.type is 'event' and doc.available_tickets
-                            emit([domain, 'available_tickets', doc._id], doc.available_tickets)
+                        for domain in domains
+                            # По конечной категории
+                            emit([domain, 'leaf_category', doc.category_id, doc.type], 1)
+                            
+                            # По всем категориям в пути
+                            if doc.category_path
+                                for category_id in doc.category_path
+                                    emit([domain, 'path_category', category_id, doc.type], 1)
                 ).toString()
                 reduce: ((keys, values) ->
                     sum values
                 ).toString()
-
-            # Аналитика популярности контента
-            content_popularity:
+            
+            # Статистика популярности категорий
+            category_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'
+                            if doc.category_id
+                                emit([domain, doc.category_id], views)
+                            
+                            if doc.category_path
+                                for category_id in doc.category_path
+                                    emit([domain, category_id], views)
+                    else 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
-                            })
+                            if doc.category_id
+                                emit([domain, doc.category_id], tickets_sold)
+                ).toString()
+                reduce: ((keys, values) ->
+                    sum values
                 ).toString()
 
-    # Design документ для управления переводами
-    translation_management:
-        version: "4.0"
+    # Design документ для навигации по иерархии
+    category_navigation:
+        version: "5.0"
         views:
-            # Все переводы по исходному документу и домену
-            by_source_and_domain:
+            # Соседние категории (одного уровня)
+            siblings_categories:
                 map: ((doc) ->
-                    if doc.translation_of
+                    if doc.type is 'category'
                         domains = if Array.isArray(doc.domain) then doc.domain else [doc.domain or 'default']
+                        parent_id = doc.parent_id or 'root'
+                        
                         for domain in domains
-                            emit([domain, doc.translation_of, doc.language], {
+                            emit([domain, parent_id, doc.order], {
                                 _id: doc._id
-                                type: doc.type
-                                title: doc.title
-                                language: doc.language
-                                translation_status: doc.translation_status
-                                domain: domain
-                                created_at: doc.created_at
+                                name: doc.name
+                                slug: doc.slug
+                                order: doc.order
+                                level: doc.level
                             })
                 ).toString()
             
-            # Статусы переводов по доменам
-            translation_status_by_domain:
+            # Дочерние категории
+            children_categories:
                 map: ((doc) ->
-                    if doc.translation_of and doc.translation_status
+                    if doc.type is 'category'
                         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], {
+                            emit([domain, doc._id, 'children'], {
                                 _id: doc._id
-                                translation_of: doc.translation_of
-                                type: doc.type
-                                title: doc.title
+                                name: doc.name
+                                children_count: doc.children_count
+                                has_children: doc.children_count > 0
                             })
                 ).toString()
             
-            # Отсутствующие переводы
-            missing_translations:
+            # Хлебные крошки для категорий
+            breadcrumbs:
                 map: ((doc) ->
-                    if doc.type and doc.language and not doc.translation_of
+                    if doc.type is 'category' and doc.parent_path
                         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
-                                    })
+                            # Эмитим для каждого родителя в пути
+                            for parent_id, index in doc.parent_path
+                                emit([domain, doc._id, 'parent', index], {
+                                    parent_id: parent_id
+                                    position: index
+                                    current_category: doc._id
+                                })
                 ).toString()
 
-    # Design документ для работы с заказами
-    orders_management:
-        version: "4.0"
+    # Design документ для мультидоменного поиска (обновленный)
+    multi_domain_search:
+        version: "5.0"
         views:
-            # Заказы по статусу и домену
-            by_status_and_domain:
+            # Универсальный поиск с учетом иерархии категорий
+            universal_search_with_categories:
                 map: ((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()
-            
-            # Статистика продаж по доменам
-            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
+                    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'
+                                searchFields =
+                                    title: doc.title
+                                    content: doc.content
+                                    excerpt: doc.excerpt
+                                    author: doc.author
+                                    tags: doc.tags
+                                    category_path: doc.category_path
+                                    type: 'blog_post'
                         
-                        # Общая сумма за день
-                        emit([domain, 'daily_sales', date], doc.total)
+                        when 'event'
+                            searchFields =
+                                title: doc.title
+                                content: doc.content
+                                location: doc.location
+                                tags: doc.tags
+                                category_path: doc.category_path
+                                type: 'event'
+                    
+                    if searchFields.title
+                        text = (
+                            searchFields.title + " " + 
+                            (searchFields.content or "") + " " +
+                            (searchFields.excerpt or "") + " " +
+                            (searchFields.author or "") + " " +
+                            (searchFields.location or "")
+                        ).toLowerCase()
                         
-                        # Количество заказов за день
-                        emit([domain, 'daily_orders', date], 1)
+                        if searchFields.tags
+                            text += " " + searchFields.tags.join(" ")
                         
-                        # Статистика по товарам
-                        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
+                        words = text.split(/\W+/).filter (word) -> word.length > 2
+                        
+                        for domain in domains
+                            for word in words
+                                emit([domain, language, word], {
+                                    _id: doc._id
+                                    type: searchFields.type
+                                    title: searchFields.title
+                                    excerpt: searchFields.excerpt
+                                    category_path: searchFields.category_path
+                                    created_at: doc.created_at
+                                    domain: domain
+                                    language: language
+                                })
                 ).toString()
 
-    # Design документ для системы уведомлений
-    notifications:
-        version: "4.0"
+    # Design документ для блог постов (обновленный)
+    blog_posts:
+        version: "5.0"
         views:
-            # События для уведомлений по доменам
-            domain_events:
+            # Блог посты с информацией о категориях
+            published_with_categories:
                 map: ((doc) ->
-                    if doc.type is 'event' and doc.status is 'upcoming'
+                    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']
-                        eventDate = new Date(doc.event_date)
-                        now = new Date()
+                        language = doc.language or 'ru'
                         
-                        # Уведомление за 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'
-                                })
+                        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
+                                category_id: doc.category_id
+                                category_path: doc.category_path
+                                created_at: doc.created_at
+                                domain: domain
+                                language: language
+                                featured: doc.featured or false
+                                views: doc.views or 0
+                            })
+                ).toString()
+
+    # Design документ для мероприятий (обновленный)
+    events:
+        version: "5.0"
+        views:
+            # Мероприятия с информацией о категориях
+            by_date_with_categories:
+                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'
                         
-                        # Уведомление за 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'
-                                })
+                        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
+                                category_id: doc.category_id
+                                category_path: doc.category_path
+                                domain: domain
+                                language: language
+                                available_tickets: doc.available_tickets
+                            })
                 ).toString()

+ 442 - 245
scripts/seed-events.coffee

@@ -4,6 +4,7 @@ PouchDB = require 'pouchdb'
 debug   = require('../../../utils/coffee/debug.coffee').default
 
 
+
 class DatabaseSeeder
     constructor: (dbName, baseUrl = 'http://oleg:631074@localhost:5984') ->
         @dbName = dbName
@@ -13,6 +14,26 @@ class DatabaseSeeder
         @orderCounter = 0
         @currentYear = new Date().getFullYear()
 
+    # Генератор ID для категорий
+    generateCategoryId: (name, parentId = null, domain = null) ->
+        slug = name
+            .toLowerCase()
+            .replace(/[^a-z0-9а-яё]/g, '_')
+            .replace(/_+/g, '_')
+            .replace(/^_|_$/g, '')
+        
+        id = "category_"+slug
+        
+        if parentId
+            parentSlug = parentId.replace(/^category_/, '')
+            id += "_"+parentSlug
+        
+        if domain
+            domainPart = domain.replace(/\./g, '_')
+            id += "_"+domainPart
+        
+        return id
+
     # Генератор ID для заказов
     generateOrderId: ->
         @orderCounter++
@@ -161,14 +182,364 @@ class DatabaseSeeder
         catch error
             debug.log "Ошибка при настройке design документов: "+error
 
+    # Создание иерархической структуры категорий
+    createCategoryHierarchy: ->
+        categories = [
+            # Корневые категории
+            {
+                _id: @generateCategoryId("Мероприятия", null, "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru", "concert-hall.tj"]
+                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
+                language: "ru"
+                name: "Мероприятия"
+                slug: "events"
+                description: "Все мероприятия концертного зала"
+                image: "/assets/borbad.s5l.ru/categories/events.jpg"
+                icon: "calendar"
+                parent_id: null
+                parent_path: []  # Путь от корня
+                level: 0         # Уровень в иерархии (0 - корень)
+                order: 1
+                children_count: 4
+                meta_title: "Мероприятия - Кохи Борбад"
+                meta_description: "Концерты, выставки и другие мероприятия в концертном зале Борбад"
+                active: true
+                featured: true
+                show_in_menu: true
+                menu_order: 1
+                color: "#3B82F6"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Новости", null, "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Новости"
+                slug: "news"
+                description: "Новости и анонсы концертного зала"
+                image: "/assets/borbad.s5l.ru/categories/news.jpg"
+                icon: "news"
+                parent_id: null
+                parent_path: []
+                level: 0
+                order: 2
+                children_count: 0
+                meta_title: "Новости - Кохи Борбад"
+                meta_description: "Последние новости и анонсы концертного зала Борбад"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 2
+                color: "#10B981"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Образование", null, "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Образование"
+                slug: "education"
+                description: "Образовательные программы и мастер-классы"
+                image: "/assets/borbad.s5l.ru/categories/education.jpg"
+                icon: "graduation"
+                parent_id: null
+                parent_path: []
+                level: 0
+                order: 3
+                children_count: 3
+                meta_title: "Образовательные программы - Кохи Борбад"
+                meta_description: "Мастер-классы, лекции и образовательные программы"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 3
+                color: "#F59E0B"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+
+            # Подкатегории для "Мероприятия"
+            {
+                _id: @generateCategoryId("Концерты", "category_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru", "concert-hall.tj"]
+                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
+                language: "ru"
+                name: "Концерты"
+                slug: "concerts"
+                description: "Музыкальные концерты различных жанров"
+                image: "/assets/borbad.s5l.ru/categories/concerts.jpg"
+                icon: "music"
+                parent_id: "category_events_borbad"
+                parent_path: ["category_events_borbad"]
+                level: 1
+                order: 1
+                children_count: 3
+                meta_title: "Концерты - Кохи Борбад"
+                meta_description: "Музыкальные концерты в концертном зале Борбад"
+                active: true
+                featured: true
+                show_in_menu: true
+                menu_order: 1
+                color: "#6366F1"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Выставки", "category_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru", "concert-hall.tj"]
+                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
+                language: "ru"
+                name: "Выставки"
+                slug: "exhibitions"
+                description: "Художественные выставки и вернисажи"
+                image: "/assets/borbad.s5l.ru/categories/exhibitions.jpg"
+                icon: "palette"
+                parent_id: "category_events_borbad"
+                parent_path: ["category_events_borbad"]
+                level: 1
+                order: 2
+                children_count: 0
+                meta_title: "Выставки - Кохи Борбад"
+                meta_description: "Художественные выставки в галерее Борбад"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 2
+                color: "#EC4899"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Театр", "category_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Театр"
+                slug: "theater"
+                description: "Театральные постановки и спектакли"
+                image: "/assets/borbad.s5l.ru/categories/theater.jpg"
+                icon: "drama"
+                parent_id: "category_events_borbad"
+                parent_path: ["category_events_borbad"]
+                level: 1
+                order: 3
+                children_count: 0
+                meta_title: "Театральные постановки - Кохи Борбад"
+                meta_description: "Спектакли и театральные представления"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 3
+                color: "#8B5CF6"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Фестивали", "category_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Фестивали"
+                slug: "festivals"
+                description: "Музыкальные и культурные фестивали"
+                image: "/assets/borbad.s5l.ru/categories/festivals.jpg"
+                icon: "festival"
+                parent_id: "category_events_borbad"
+                parent_path: ["category_events_borbad"]
+                level: 1
+                order: 4
+                children_count: 0
+                meta_title: "Фестивали - Кохи Борбад"
+                meta_description: "Культурные и музыкальные фестивали"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 4
+                color: "#F59E0B"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+
+            # Подкатегории для "Концерты"
+            {
+                _id: @generateCategoryId("Классическая музыка", "category_concerts_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru", "concert-hall.tj"]
+                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
+                language: "ru"
+                name: "Классическая музыка"
+                slug: "classical-music"
+                description: "Симфонические концерты и классические произведения"
+                image: "/assets/borbad.s5l.ru/categories/classical-music.jpg"
+                icon: "classical"
+                parent_id: "category_concerts_events_borbad"
+                parent_path: ["category_events_borbad", "category_concerts_events_borbad"]
+                level: 2
+                order: 1
+                children_count: 0
+                meta_title: "Классическая музыка - Кохи Борбад"
+                meta_description: "Симфонические концерты и классические произведения"
+                active: true
+                featured: true
+                show_in_menu: true
+                menu_order: 1
+                color: "#3B82F6"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Джаз и блюз", "category_concerts_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Джаз и блюз"
+                slug: "jazz-blues"
+                description: "Джазовые концерты и блюзовые вечера"
+                image: "/assets/borbad.s5l.ru/categories/jazz-blues.jpg"
+                icon: "jazz"
+                parent_id: "category_concerts_events_borbad"
+                parent_path: ["category_events_borbad", "category_concerts_events_borbad"]
+                level: 2
+                order: 2
+                children_count: 0
+                meta_title: "Джаз и блюз - Кохи Борбад"
+                meta_description: "Джазовые концерты и блюзовые вечера"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 2
+                color: "#8B5CF6"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Народная музыка", "category_concerts_events_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru", "concert-hall.tj"]
+                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
+                language: "ru"
+                name: "Народная музыка"
+                slug: "folk-music"
+                description: "Концерты народной и традиционной музыки"
+                image: "/assets/borbad.s5l.ru/categories/folk-music.jpg"
+                icon: "folk"
+                parent_id: "category_concerts_events_borbad"
+                parent_path: ["category_events_borbad", "category_concerts_events_borbad"]
+                level: 2
+                order: 3
+                children_count: 0
+                meta_title: "Народная музыка - Кохи Борбад"
+                meta_description: "Концерты народной и традиционной музыки"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 3
+                color: "#10B981"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+
+            # Подкатегории для "Образование"
+            {
+                _id: @generateCategoryId("Мастер-классы", "category_education_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Мастер-классы"
+                slug: "workshops"
+                description: "Практические занятия и мастер-классы"
+                image: "/assets/borbad.s5l.ru/categories/workshops.jpg"
+                icon: "workshop"
+                parent_id: "category_education_borbad"
+                parent_path: ["category_education_borbad"]
+                level: 1
+                order: 1
+                children_count: 0
+                meta_title: "Мастер-классы - Кохи Борбад"
+                meta_description: "Практические занятия и мастер-классы"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 1
+                color: "#F59E0B"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Лекции", "category_education_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Лекции"
+                slug: "lectures"
+                description: "Образовательные лекции и семинары"
+                image: "/assets/borbad.s5l.ru/categories/lectures.jpg"
+                icon: "lecture"
+                parent_id: "category_education_borbad"
+                parent_path: ["category_education_borbad"]
+                level: 1
+                order: 2
+                children_count: 0
+                meta_title: "Лекции - Кохи Борбад"
+                meta_description: "Образовательные лекции и семинары"
+                active: true
+                featured: false
+                show_in_menu: true
+                menu_order: 2
+                color: "#EF4444"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+            {
+                _id: @generateCategoryId("Детские программы", "category_education_borbad", "borbad")
+                type: "category"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                name: "Детские программы"
+                slug: "children-programs"
+                description: "Образовательные программы для детей"
+                image: "/assets/borbad.s5l.ru/categories/children-programs.jpg"
+                icon: "children"
+                parent_id: "category_education_borbad"
+                parent_path: ["category_education_borbad"]
+                level: 1
+                order: 3
+                children_count: 0
+                meta_title: "Детские программы - Кохи Борбад"
+                meta_description: "Образовательные программы для детей"
+                active: true
+                featured: true
+                show_in_menu: true
+                menu_order: 3
+                color: "#EC4899"
+                created_at: new Date().toISOString()
+                updated_at: new Date().toISOString()
+            }
+        ]
+        
+        return categories
+
     # Создание тестовых данных для сайта
     createSampleData: ->
         currentDate = new Date().toISOString()
-        futureDate = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
-        pastDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString()
         
         sampleData = [
-            # Доменные настройки для основного домена
+            # Доменные настройки
             {
                 _id: "domain_settings_borbad_s5l_ru"
                 type: "domain_settings"
@@ -208,92 +579,10 @@ class DatabaseSeeder
                 updated_at: currentDate
             }
 
-            # Доменные настройки для второго домена
-            {
-                _id: "domain_settings_concert_hall_tj"
-                type: "domain_settings"
-                domain: "concert-hall.tj"
-                name: "Концертный зал Борбад - Таджикистан"
-                description: "Культурная площадка для мероприятий и концертов"
-                active: true
-                priority: 2
-                theme: "borbad_light"
-                languages: ["tj", "ru"]
-                default_language: "tj"
-                timezone: "Asia/Dushanbe"
-                currency: "TJS"
-                settings: {
-                    seo: {
-                        title_template: "{page} - Борбад"
-                        description: "Концерты и мероприятия в Душанбе"
-                        keywords: ["концерты", "Борбад", "Душанбе", "мероприятия"]
-                    }
-                    social: {
-                        facebook: "https://facebook.com/borbad.tj"
-                        instagram: "https://instagram.com/borbad.tj"
-                    }
-                    contact: {
-                        address: "г. Душанбе, пр. Рудаки 22"
-                        phone: "+992 37 123-45-68"
-                        email: "info@concert-hall.tj"
-                    }
-                    features: {
-                        online_booking: true
-                        multi_language: true
-                        ecommerce: false
-                    }
-                }
-                created_at: currentDate
-                updated_at: currentDate
-            }
+            # Добавляем иерархические категории
+            ...@createCategoryHierarchy()
 
-            # Слайдеры (6 слайдов) - мультидоменные
-            {
-                _id: "slide_01_borbad"
-                type: "slide"
-                domain: ["borbad.s5l.ru", "concert-hall.tj"]
-                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
-                language: "ru"
-                title: "Добро пожаловать в Кохи Борбад"
-                content: "## Современный концертный зал в сердце Душанбе\n\nМесто, где встречаются искусство и культура"
-                image: "/assets/borbad.s5l.ru/sliders/main-hall.jpg"
-                mobile_image: "/assets/borbad.s5l.ru/sliders/main-hall-mobile.jpg"
-                order: 1
-                active: true
-                button_text: "Узнать больше"
-                button_link: "/about"
-                button_style: "primary"
-                text_color: "#ffffff"
-                text_position: "center"
-                overlay: true
-                overlay_opacity: 0.4
-                start_date: "2024-01-01T00:00:00.000Z"
-                end_date: "2024-12-31T23:59:59.000Z"
-                target_audience: ["all"]
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            {
-                _id: "slide_02_borbad"
-                type: "slide"
-                domain: ["borbad.s5l.ru"]
-                domain_priority: ["borbad.s5l.ru"]
-                language: "ru"
-                title: "Симфонические вечера"
-                content: "## Погрузитесь в мир классической музыки\n\nЕженедельные концерты симфонического оркестра"
-                image: "/assets/borbad.s5l.ru/sliders/orchestra.jpg"
-                order: 2
-                active: true
-                button_text: "Расписание"
-                button_link: "/events"
-                text_color: "#ffffff"
-                overlay: true
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            # ... остальные 4 слайда с аналогичной структурой
-
-            # Блог посты (6 постов) - мультидоменные
+            # Блог посты с привязкой к иерархическим категориям
             {
                 _id: @generateBlogPostId("Открытие нового сезона 2024", "borbad")
                 type: "blog_post"
@@ -307,46 +596,21 @@ class DatabaseSeeder
                 excerpt: "Новый творческий сезон 2024 года в концертном зале Борбад"
                 image: "/assets/borbad.s5l.ru/posts/season-opening.jpg"
                 tags: ["новости", "сезон", "анонс"]
-                category_id: "category_news_borbad"
+                category_id: "category_news_borbad"  # Привязка к категории новостей
+                category_path: ["category_news_borbad"]  # Полный путь категории
                 author: "Администрация Борбад"
                 status: "published"
                 meta_title: "Открытие нового сезона 2024 - Кохи Борбад"
                 meta_description: "Новый творческий сезон 2024 года в концертном зале Борбад в Душанбе"
                 featured: true
-                featured_image: "/assets/borbad.s5l.ru/posts/season-opening-featured.jpg"
                 reading_time: 5
                 created_at: currentDate
                 updated_at: currentDate
                 published_at: currentDate
                 views: 156
-                likes: 23
-                shares: 45
-            }
-            {
-                _id: @generateBlogPostId("История создания концертного зала", "borbad")
-                type: "blog_post"
-                domain: ["borbad.s5l.ru", "concert-hall.tj"]
-                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
-                language: "ru"
-                translation_of: null
-                translation_status: "original"
-                title: "История создания концертного зала"
-                content: "# Кохи Борбад: История и архитектура\n\n## Начало пути\n\nКонцертный зал Борбад был основан в 2010 году..."
-                excerpt: "История создания и архитектурные особенности концертного зала Борбад"
-                image: "/assets/borbad.s5l.ru/posts/history-building.jpg"
-                tags: ["история", "архитектура", "культура"]
-                category_id: "category_about_borbad"
-                author: "Директор зала"
-                status: "published"
-                featured: true
-                created_at: pastDate
-                updated_at: currentDate
-                published_at: pastDate
-                views: 289
             }
-            # ... остальные 4 поста с аналогичной структурой
 
-            # Мероприятия (6 мероприятий) - мультидоменные
+            # Мероприятия с привязкой к иерархическим категориям
             {
                 _id: @generateEventId("Симфонический концерт: Бетховен и Чайковский", "2024-03-20T19:00:00.000Z", "borbad")
                 type: "event"
@@ -360,162 +624,94 @@ class DatabaseSeeder
                 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"
+                category_id: "category_classical_music_concerts_events_borbad"  # Глубокая привязка
+                category_path: ["category_events_borbad", "category_concerts_events_borbad", "category_classical_music_concerts_events_borbad"]
                 status: "upcoming"
                 registration_required: true
-                max_attendees: 300
-                age_restriction: "6+"
-                organizer: "Симфонический оркестр Борбад"
-                performers: ["Фаррух Саидов (дирижер)", "Солисты оркестра"]
-                duration: 120
-                created_at: currentDate
-                updated_at: currentDate
-            }
-            # ... остальные 5 мероприятий с аналогичной структурой
-
-            # Категории - мультидоменные
-            {
-                _id: "category_concerts_borbad"
-                type: "category"
-                domain: ["borbad.s5l.ru", "concert-hall.tj"]
-                domain_priority: ["borbad.s5l.ru", "concert-hall.tj"]
-                language: "ru"
-                translation_of: null
-                translation_status: "original"
-                name: "Концерты"
-                slug: "concerts"
-                description: "Музыкальные мероприятия и концерты различных жанров"
-                image: "/assets/borbad.s5l.ru/categories/concerts.jpg"
-                icon: "music"
-                parent_id: null
-                order: 2
-                meta_title: "Концерты - Кохи Борбад"
-                meta_description: "Музыкальные мероприятия и концерты в концертном зале Борбад"
-                active: true
-                featured: true
-                show_in_menu: true
-                menu_order: 2
-                color: "#3B82F6"
                 created_at: currentDate
                 updated_at: currentDate
             }
             {
-                _id: "category_news_borbad"
-                type: "category"
+                _id: @generateEventId("Джазовый вечер с Тимуром Якубовым", "2024-04-15T20:00:00.000Z", "borbad")
+                type: "event"
                 domain: ["borbad.s5l.ru"]
                 domain_priority: ["borbad.s5l.ru"]
                 language: "ru"
-                name: "Новости"
-                slug: "news"
-                description: "Последние новости и анонсы концертного зала"
-                image: "/assets/borbad.s5l.ru/categories/news.jpg"
-                parent_id: null
-                order: 1
-                meta_title: "Новости - Кохи Борбад"
-                meta_description: "Последние новости и анонсы концертного зала Борбад"
-                active: true
+                title: "Джазовый вечер с Тимуром Якубовым"
+                content: "# Современный джаз в Борбаде\n\n## О исполнителе\n\nТимур Якубов - известный джазовый пианист..."
+                event_date: "2024-04-15T20:00:00.000Z"
+                end_date: "2024-04-15T22:00:00.000Z"
+                location: "Малый зал"
+                price: 350
+                currency: "TJS"
+                available_tickets: 80
+                total_tickets: 150
+                image: "/assets/borbad.s5l.ru/events/jazz-evening.jpg"
+                tags: ["джаз", "современная музыка", "импровизация"]
+                category_id: "category_jazz_blues_concerts_events_borbad"
+                category_path: ["category_events_borbad", "category_concerts_events_borbad", "category_jazz_blues_concerts_events_borbad"]
+                status: "upcoming"
+                registration_required: true
                 created_at: currentDate
                 updated_at: currentDate
             }
 
-            # Пользователи - глобальные
+            # Мастер-класс с привязкой к образовательной категории
             {
-                _id: "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"]
+                _id: @generateEventId("Мастер-класс: Основы вокала", "2024-03-25T15:00:00.000Z", "borbad")
+                type: "event"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
+                language: "ru"
+                title: "Мастер-класс: Основы вокала"
+                content: "# Искусство пения для начинающих\n\n## О ведущем\n\nОперный певец Шариф Мухтаров..."
+                event_date: "2024-03-25T15:00:00.000Z"
+                end_date: "2024-03-25T18:00:00.000Z"
+                location: "Репетиционный зал"
+                price: 200
+                currency: "TJS"
+                available_tickets: 15
+                total_tickets: 20
+                image: "/assets/borbad.s5l.ru/events/vocal-workshop.jpg"
+                tags: ["мастер-класс", "вокал", "образование", "музыка"]
+                category_id: "category_workshops_education_borbad"
+                category_path: ["category_education_borbad", "category_workshops_education_borbad"]
+                status: "upcoming"
+                registration_required: true
                 created_at: currentDate
                 updated_at: currentDate
-                last_login: "2024-01-15T09:30:00.000Z"
             }
 
-            # Заказы - специфичные для домена
+            # Детская программа
             {
-                _id: @generateOrderId()+"_borbad"
-                type: "order"
-                domain: "borbad.s5l.ru"
+                _id: @generateEventId("Детская программа: Музыкальная сказка", "2024-04-10T11:00:00.000Z", "borbad")
+                type: "event"
+                domain: ["borbad.s5l.ru"]
+                domain_priority: ["borbad.s5l.ru"]
                 language: "ru"
-                user_id: "user_customer_ivanov"
-                status: "completed"
-                total: 1500
+                title: "Детская программа: Музыкальная сказка"
+                content: "# Волшебный мир музыки для детей\n\n## Новая постановка\n\nТеатральная студия Борбад представляет..."
+                event_date: "2024-04-10T11:00:00.000Z"
+                end_date: "2024-04-10T12:00:00.000Z"
+                location: "Детский зал"
+                price: 100
                 currency: "TJS"
-                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"
+                available_tickets: 95
+                total_tickets: 100
+                image: "/assets/borbad.s5l.ru/events/children-play.jpg"
+                tags: ["дети", "театр", "образование", "семейный"]
+                category_id: "category_children_programs_education_borbad"
+                category_path: ["category_education_borbad", "category_children_programs_education_borbad"]
+                status: "upcoming"
+                registration_required: true
+                created_at: currentDate
+                updated_at: currentDate
             }
         ]
         
@@ -561,3 +757,4 @@ if require.main is module
     seeder = new DatabaseSeeder('borbad_events')
     seeder.initialize().catch (error) ->
         debug.log "Критическая ошибка инициализации: "+error
+