| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- # app/design/site.coffee
- class SiteDesignDocuments
- constructor: ->
- @designDocs = {
- products: @getProductsDesignDoc()
- categories: @getCategoriesDesignDoc()
- orders: @getOrdersDesignDoc()
- validation: @getValidationDesignDoc()
- domains: @getDomainsDesignDoc()
- }
- getProductsDesignDoc: ->
- {
- _id: '_design/products'
- views:
- # Все активные товары
- all_active:
- map: """
- function(doc) {
- if (doc.type === 'product' && doc.active !== false) {
- emit(doc._id, null);
- }
- }
- """
- # Товары по категориям
- by_category:
- map: """
- function(doc) {
- if (doc.type === 'product' && doc.active !== false && doc.category) {
- emit([doc.category, doc.name], {
- name: doc.name,
- price: doc.price,
- brand: doc.brand,
- inStock: doc.inStock,
- images: doc.images
- });
- }
- }
- """
- # Товары по брендам
- by_brand:
- map: """
- function(doc) {
- if (doc.type === 'product' && doc.active !== false && doc.brand) {
- emit([doc.brand, doc.name], null);
- }
- }
- """
- # Поиск по SKU
- by_sku:
- map: """
- function(doc) {
- if (doc.type === 'product' && doc.sku) {
- emit(doc.sku, null);
- }
- }
- """
- # Товары по доменам
- by_domain:
- map: """
- function(doc) {
- if (doc.type === 'product' && doc.active !== false && doc.domains) {
- doc.domains.forEach(function(domain) {
- emit(domain, null);
- });
- }
- }
- """
- language: "javascript"
- }
- getCategoriesDesignDoc: ->
- {
- _id: '_design/categories'
- views:
- # Все активные категории
- all_active:
- map: """
- function(doc) {
- if (doc.type === 'category' && doc.active !== false) {
- emit(doc._id, null);
- }
- }
- """
- # Категории по slug
- by_slug:
- map: """
- function(doc) {
- if (doc.type === 'category' && doc.slug) {
- emit(doc.slug, null);
- }
- }
- """
- # Иерархия категорий
- hierarchical:
- map: """
- function(doc) {
- if (doc.type === 'category' && doc.active !== false) {
- var path = doc.parent ? [doc.parent, doc._id] : [doc._id];
- emit(path, {
- name: doc.name,
- parent: doc.parent,
- order: doc.order
- });
- }
- }
- """
- # Категории по доменам
- by_domain:
- map: """
- function(doc) {
- if (doc.type === 'category' && doc.active !== false && doc.domains) {
- doc.domains.forEach(function(domain) {
- emit(domain, null);
- });
- }
- }
- """
- language: "javascript"
- }
- getOrdersDesignDoc: ->
- {
- _id: '_design/orders'
- views:
- # Заказы по пользователю
- by_user:
- map: """
- function(doc) {
- if (doc.type === 'order' && doc.userId) {
- emit([doc.userId, doc.createdAt], null);
- }
- }
- """
- # Заказы по статусу
- by_status:
- map: """
- function(doc) {
- if (doc.type === 'order' && doc.status) {
- emit([doc.status, doc.createdAt], null);
- }
- }
- """
- language: "javascript"
- }
- getDomainsDesignDoc: ->
- {
- _id: '_design/domains'
- views:
- # Настройки по доменам
- settings_by_domain:
- map: """
- function(doc) {
- if (doc.type === 'domain_settings' && doc.domain) {
- emit(doc.domain, null);
- }
- }
- """
- language: "javascript"
- }
- getValidationDesignDoc: ->
- {
- _id: '_design/validation'
- validate_doc_update: """
- function(newDoc, oldDoc, userCtx, secObj) {
- // Функция проверки документов при сохранении
-
- // Разрешаем удаление (помечание как удаленного)
- if (newDoc._deleted || newDoc.deleted) {
- // Проверяем права пользователя на удаление
- if (userCtx.roles.indexOf('_admin') === -1) {
- throw({forbidden: 'Only admins can delete documents'});
- }
- return; // Разрешаем удаление
- }
-
- // Проверка типа документа
- if (newDoc.type) {
- var validTypes = [
- 'product', 'category', 'order', 'user',
- 'domain_settings', 'hero_slide', 'blog_article'
- ];
-
- if (validTypes.indexOf(newDoc.type) === -1) {
- throw({forbidden: 'Invalid document type: ' + newDoc.type});
- }
- }
-
- // Проверка обязательных полей для товаров
- if (newDoc.type === 'product') {
- if (!newDoc.name) {
- throw({forbidden: 'Product must have a name'});
- }
- if (!newDoc.sku) {
- throw({forbidden: 'Product must have SKU'});
- }
- if (typeof newDoc.price !== 'number' || newDoc.price < 0) {
- throw({forbidden: 'Product must have valid price'});
- }
- }
-
- // Проверка категорий
- if (newDoc.type === 'category') {
- if (!newDoc.name && !newDoc.deleted) {
- throw({forbidden: 'Category must have a name'});
- }
- }
-
- // Проверка неизменяемых полей
- if (oldDoc) {
- if (oldDoc.type !== newDoc.type) {
- throw({forbidden: 'Document type cannot be changed'});
- }
- if (oldDoc.createdAt !== newDoc.createdAt) {
- throw({forbidden: 'Creation date cannot be changed'});
- }
- }
- }
- """
- language: "javascript"
- }
- module.exports = new SiteDesignDocuments()
|