# Текущая ззадача
доработай domain, в документах с учетом что один и тотже жокумент может быть в разных доменах
приведи нную # Структура хранимых данных с описанием ## всех хранимых объектов
и их примеры.
# файл с правилами
https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/raw/master/README.md
# применяй правила:
## оформление ссылок
a(href="[ссылка]") - не правильно
router-link(to="[ссылка]") - не правильно
app-link(to="[ссылка]") - правильно (должен быть подключен компанент: 'app-link': require 'app/shared/AppLink')
## Корневой каталог и мета данные
Важно: мета данные добавляются через app/temp.coffe
базовым тегоьм для vuejs является body, app/index.pug начинается с div,
теги html, head, body ЗАПРЕЩЕНО использовать.
### пример кода app/temp.coffee
```
# обязательно подключение глобальных массивов
globalThis.renderFns = require 'pug.json'
globalThis.stylFns = require 'styl.json'
# подключение мета информации (строго в данном фиде)
document.head.insertAdjacentHTML 'beforeend',''
document.head.insertAdjacentHTML 'beforeend',''
document.head.insertAdjacentHTML('beforeend','
Кохи Борбад - Концертный зал Душанбе')
# Настройка tailwind
tailwind.config = require 'tailwind.config.js'
# подключение основных стилей
## tailwind
document.head.insertAdjacentHTML('beforeend','')
## базовой стиль приложения
document.head.insertAdjacentHTML('beforeend','')
# Маршруты
routes = [
{ path: '/', component: require 'app/pages/Home' }
{ path: '/events', component: require 'app/pages/Events' }
{ path: '/about', component: require 'app/pages/About' }
{ path: '/contacts', component: require 'app/pages/Contacts' }
]
# Глобальное определение vuejs приложения
app = Vue.createApp
name: 'app'
data: ()->
return {
appState:
events: []
featuredEvents: []
sliderEvents: []
loading: true
error: null
modalState: #управление модальными окнами
isVisible: false
component: null
props: {}
couchDBService: new CouchDBService()
}
beforeMount: ()->
debug.log "start beforeMount"
# определение контекста vuejs приложения как глобальной переменной _
globalThis._ = @
# все глобальные переменные необходимые для работы определяем в data
# и получаем доступ через _.*
render: (new Function '_ctx', '_cache', renderFns['app/temp.pug'])()
mounted: ->{}
methods: {}
components:
'themetoggle': require 'app/shared/ThemeToggle'
'multilevelmenu': require 'app/shared/MultiLevelMenu'
'imageslider': require 'app/shared/ImageSlider'
app.use(VueRouter.createRouter({
routes: routes
history: VueRouter.createWebHistory()
scrollBehavior: (to, from, savedPosition) ->
if savedPosition
return savedPosition
else
return { x: 0, y: 0 }
}))
# подключаем в body ОБЯЗАТЕЛЬНО!!!
app.mount('body')
```
### Привер кода index.coffee для компанентов/страниц
```
# Важно загрузка стилей компонента/страницы
document.head.insertAdjacentHTML('beforeend','')
module.exports =
name: 'BlogPage'
# ВАЖНО загрузка шаблона через рендер функцию
render: (new Function '_ctx', '_cache', renderFns['app/pages/Blog/index.pug'])()
data: ->
posts: []
loading: true
error: null
beforeMount: ->
@loadBlogPosts()
methods:
loadBlogPosts: ->
try
@loading = true
@posts = await AppDB.getBlogPosts(limit: 10)
@loading = false
catch error
@error = "Ошибка загрузки постов: "+error
@loading = false
```
## определение функций в _deing документе
при обновлении документа учитывай версионность
```
# Design документ для блог постов
blog_posts:
version: "1.1"
views:
# Все опубликованные блог посты
published:
map: ((doc) ->
if doc.type is 'blog_post' and doc.status is 'published'
emit(doc.created_at, doc)).toString()
```
## определение шаблонов для слотов
template(#body) - не правильно
template(v-slot:body) - не правильно
template([body]) - правильно
## async в методах
async loadData: -> - не правильно
loadData: -> - правильно
## Радота с кодом
всегда приводи полный листинг файлов
при форматировании кода для отделения логических блоков используй 4 пробела (" ")
следи за строгим соблюдением синтаксиса используемых языков (coffeescript, pug, stylus)
в pug не используй многострочные вычисляемые атрибуты
## работа с консолью и текстовыми константами/переменными используй конкатенацию (СТРОГО! ВАЖНО!)
используй для вывода в консоль debug.log
console.log "переменная temp = #{temp}" - не правильно
debug.log "переменная temp = "+temp - правильно
shareUrl = "https://twitter.com/intent/tweet?text=#{text}" - не правильно
shareUrl = "https://twitter.com/intent/tweet?text="+text - правильно
"#{@baseUrl}/#{@dbName}/_all_docs?include_docs=true" - не правильно
@baseUrl+"/"+@dbName+"/_all_docs?include_docs=true" - правильно
## Цвета и управление темами
во всех *.styl файлах используй цвета в виде переменных, определённых в файле tailwind.config.js
## Стили
все глобальный настройки стилей, пиши в app/temp.styl в остальных файлах, строго стили необходимые только для данного компаонента
## Расположение статических файлов/изображений
img(src="/images/hall-interior.jpg") - не правильно
img(src="/assets/[domenName]/hall-interior.jpg") - правильно
## стиль написания классов
.container.mx-auto.px-4 - не правильно
div(class="container.mx-auto px-4") - правильно
## *не используй вызовы*
Vue = require 'vue'
VueRouter = require 'vue-router'
* Подключение осуществлено глобально через файл doc.json
## git ВАЖНО
для анализа кода бери версии файлов СТРОГО из репозитария:
https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/src/master
, корневой каталог vue/
от него идут пути к файлам пример: в коде -> app/temp.coffee, в репозитарии -> vue/app/temp.coffee
# Общее описание
Универсаньная CMS для работы с couchdb как бекендом.
CMS мультидоменная и мультиязычная.
мультидоменность во все view через поле domain
# общая структура проекта
app/
├── tailwind.config.js (настройка тем и Tailwind CSS)
├── temp.pug (основной layout)
├── temp.coffee (инициализация Vue и роутера)
├── temp.styl (стили которые сложно или не удобно сделать на Tailwind CSS или стили к однотипным элементам на stylus)
├── core/ - Каталог для хранения coffee файлов частей ядра системы, для улучшения чтения temp.coffee
| ├── CouchdbClass.coffee
| ...
├── page/
| ├── Home/ (главная страница)
| | ├── index.coffee
| | ├── index.pug
| | ├── index.styl
| ├── [другие_страницы]/
| ├── index.coffee
| ├── index.pug
| ├── index.styl
└── shared/
├── ThemeToggle/
| ├── index.coffee
| ├── index.pug
| ├── index.styl
├── MultiLevelMenu/
| ├── index.coffee
| ├── index.pug
| ├── index.styl
├── ImageSlider/
| ├── index.coffee
| ├── index.pug
| ├── index.styl
├── ModalWindow/
| ├── index.coffee
| ├── index.pug
| ├── index.styl
├── FormValidator/
| ├── index.coffee
| ├── index.pug
| ├── index.styl
├── FilterSort/
├── index.coffee
├── index.pug
├── index.styl
# Структура хранимых данных
## Описание всех хранимых объектов с мультиязычностью
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 # Дата обновления
}
7. Тема (theme) с мультиязычностью
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 # Дата обновления
}
8. Страница (page) с мультиязычностью
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 # Дата обновления
}
9. Меню (menu) с мультиязычностью
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 # Дата обновления
}
10. Пользователь (user)
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 # Дата последнего входа
}
11. Заказ (order)
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 # Дата обновления
}
12. Настройка (setting)
coffee
{
_id: String # Уникальный идентификатор
type: 'setting' # Тип документа
domain: String # Домен
language: String # Язык настройки
key: String # Ключ настройки
value: Object # Значение настройки
is_global: Boolean # Глобальная настройка
description: String # Описание настройки
created_at: ISOString # Дата создания
updated_at: ISOString # Дата обновления
}
13. Аудит (audit_log)
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"
title: "О нас - Кохи Борбад"
slug: "about"
content: "# О концертном зале Борбад\n\nИстория и описание нашего зала..."
excerpt: "Информация о концертном зале Борбад в Душанбе"
image: "/assets/borbad.s5l.ru/about.jpg"
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"
type: "menu"
domain: "borbad.s5l.ru"
name: "Главное меню"
location: "header"
active: true
items: [
{
title: "Главная"
url: "/"
order: 1
target: "_self"
}
{
title: "Мероприятия"
url: "/events"
order: 2
target: "_self"
}
{
title: "О нас"
url: "/about"
order: 3
target: "_self"
}
{
title: "Контакты"
url: "/contacts"
order: 4
target: "_self"
}
]
created_at: new Date().toISOString()
updated_at: new Date().toISOString()
## Пример документа пользователя
userExample =
_id: "user_admin_1"
type: "user"
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: "Системный администратор"
settings:
language: "ru"
notifications: true
created_at: new Date().toISOString()
updated_at: new Date().toISOString()
last_login: new Date().toISOString()
## Пример документа заказа
orderExample =
_id: "order_2024_001"
type: "order"
domain: "borbad.s5l.ru"
user_id: "user_customer_1"
status: "completed"
total: 1500
currency: "TJS"
items: [
{
product_id: "event_ticket_1"
name: "Билет на симфонический концерт"
quantity: 2
price: 500
total: 1000
}
{
product_id: "product_1"
name: "Футболка с логотипом"
quantity: 1
price: 500
total: 500
}
]
customer_info:
name: "Иван Иванов"
email: "ivan@example.com"
phone: "+992 123-45-67"
payment_info:
method: "card"
transaction_id: "txn_123456"
status: "paid"
created_at: new Date().toISOString()
updated_at: new Date().toISOString()
## Пример документа аудита
auditExample =
_id: "audit_2024_001"
type: "audit_log"
user_id: "user_admin_1"
action: "create"
resource_type: "blog_post"
resource_id: "blog_post_1"
description: "Создана новая запись блога"
ip_address: "192.168.1.1"
user_agent: "Mozilla/5.0..."
created_at: new Date().toISOString()
## _desing документ для работы с данными
https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/raw/master/scripts/design-documents.coffee