design-documents.coffee 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. # Design документы для CouchDB с поддержкой мультидоменности
  2. module.exports =
  3. # Design документ для настроек доменов
  4. domains:
  5. version: "2.0"
  6. views:
  7. # Все настройки доменов
  8. all_domains:
  9. map: ((doc) ->
  10. if doc.type is 'domain_settings'
  11. emit(doc.domain, doc)
  12. ).toString()
  13. # Активные домены
  14. active_domains:
  15. map: ((doc) ->
  16. if doc.type is 'domain_settings' and doc.active is true
  17. emit(doc.domain, doc)
  18. ).toString()
  19. # Домены по приоритету
  20. by_priority:
  21. map: ((doc) ->
  22. if doc.type is 'domain_settings' and doc.active is true
  23. emit(doc.priority or 0, doc)
  24. ).toString()
  25. # Design документ для блог постов с мультидоменностью
  26. blog_posts:
  27. version: "2.0"
  28. views:
  29. # Все опубликованные блог посты с фильтром по домену
  30. published:
  31. map: ((doc) ->
  32. if doc.type is 'blog_post' and doc.status is 'published'
  33. domain = doc.domain or 'default'
  34. emit([domain, doc.created_at], doc)
  35. ).toString()
  36. # Блог посты по тегам с фильтром по домену
  37. by_tag:
  38. map: ((doc) ->
  39. if doc.type is 'blog_post' and doc.status is 'published' and doc.tags
  40. domain = doc.domain or 'default'
  41. for tag in doc.tags
  42. emit([domain, tag, doc.created_at], doc)
  43. ).toString()
  44. # Блог посты по автору с фильтром по домену
  45. by_author:
  46. map: ((doc) ->
  47. if doc.type is 'blog_post' and doc.status is 'published'
  48. domain = doc.domain or 'default'
  49. emit([domain, doc.author, doc.created_at], doc)
  50. ).toString()
  51. # Поиск по заголовку и содержанию с фильтром по домену
  52. search:
  53. map: ((doc) ->
  54. if doc.type is 'blog_post' and doc.status is 'published'
  55. domain = doc.domain or 'default'
  56. text = (doc.title + " " + doc.content + " " + doc.excerpt).toLowerCase()
  57. words = text.split(/\W+/).filter (word) -> word.length > 2
  58. for word in words
  59. emit([domain, word], {
  60. _id: doc._id
  61. title: doc.title
  62. excerpt: doc.excerpt
  63. created_at: doc.created_at
  64. domain: doc.domain
  65. })
  66. ).toString()
  67. # Design документ для мероприятий с мультидоменностью
  68. events:
  69. version: "2.0"
  70. views:
  71. # Все мероприятия по дате с фильтром по домену
  72. by_date:
  73. map: ((doc) ->
  74. if doc.type is 'event'
  75. domain = doc.domain or 'default'
  76. emit([domain, doc.event_date], doc)
  77. ).toString()
  78. # Предстоящие мероприятия с фильтром по домену
  79. upcoming:
  80. map: ((doc) ->
  81. if doc.type is 'event' and doc.status is 'upcoming'
  82. domain = doc.domain or 'default'
  83. emit([domain, doc.event_date], doc)
  84. ).toString()
  85. # Активные мероприятия с фильтром по домену
  86. ongoing:
  87. map: ((doc) ->
  88. if doc.type is 'event' and doc.status is 'ongoing'
  89. domain = doc.domain or 'default'
  90. emit([domain, doc.event_date], doc)
  91. ).toString()
  92. # Мероприятия по тегам с фильтром по домену
  93. by_tag:
  94. map: ((doc) ->
  95. if doc.type is 'event' and doc.tags
  96. domain = doc.domain or 'default'
  97. for tag in doc.tags
  98. emit([domain, tag, doc.event_date], doc)
  99. ).toString()
  100. # Мероприятия по местоположению с фильтром по домену
  101. by_location:
  102. map: ((doc) ->
  103. if doc.type is 'event'
  104. domain = doc.domain or 'default'
  105. emit([domain, doc.location, doc.event_date], doc)
  106. ).toString()
  107. # Design документ для слайдов с мультидоменностью
  108. slides:
  109. version: "2.0"
  110. views:
  111. # Активные слайды по порядку с фильтром по домену
  112. active_ordered:
  113. map: ((doc) ->
  114. if doc.type is 'slide' and doc.active is true
  115. domain = doc.domain or 'default'
  116. emit([domain, doc.order], doc)
  117. ).toString()
  118. # Design документ для товаров с мультидоменностью
  119. products:
  120. version: "2.0"
  121. views:
  122. # Все доступные товары с фильтром по домену
  123. available:
  124. map: ((doc) ->
  125. if doc.type is 'product' and doc.status is 'available'
  126. domain = doc.domain or 'default'
  127. emit([domain, doc.created_at], doc)
  128. ).toString()
  129. # Товары по категориям с фильтром по домену
  130. by_category:
  131. map: ((doc) ->
  132. if doc.type is 'product' and doc.status is 'available'
  133. domain = doc.domain or 'default'
  134. emit([domain, doc.category, doc.created_at], doc)
  135. ).toString()
  136. # Товары по тегам с фильтром по домену
  137. by_tag:
  138. map: ((doc) ->
  139. if doc.type is 'product' and doc.tags
  140. domain = doc.domain or 'default'
  141. for tag in doc.tags
  142. emit([domain, tag, doc.created_at], doc)
  143. ).toString()
  144. # Товары по цене с фильтром по домену
  145. by_price:
  146. map: ((doc) ->
  147. if doc.type is 'product' and doc.status is 'available'
  148. domain = doc.domain or 'default'
  149. emit([domain, doc.price], doc)
  150. ).toString()
  151. # Design документ для категорий и тем с мультидоменностью
  152. categories_themes:
  153. version: "2.0"
  154. views:
  155. # Все категории по порядку с фильтром по домену
  156. categories_ordered:
  157. map: ((doc) ->
  158. if doc.type is 'category'
  159. domain = doc.domain or 'default'
  160. emit([domain, doc.order], doc)
  161. ).toString()
  162. # Категории по родителю с фильтром по домену
  163. categories_by_parent:
  164. map: ((doc) ->
  165. if doc.type is 'category'
  166. domain = doc.domain or 'default'
  167. parent = doc.parent or 'root'
  168. emit([domain, parent, doc.order], doc)
  169. ).toString()
  170. # Все темы с фильтром по домену
  171. themes:
  172. map: ((doc) ->
  173. if doc.type is 'theme'
  174. domain = doc.domain or 'default'
  175. emit([domain, doc.name], doc)
  176. ).toString()
  177. # Design документ для страниц с мультидоменностью
  178. pages:
  179. version: "2.0"
  180. views:
  181. # Все страницы по slug с фильтром по домену
  182. by_slug:
  183. map: ((doc) ->
  184. if doc.type is 'page'
  185. domain = doc.domain or 'default'
  186. emit([domain, doc.slug], doc)
  187. ).toString()
  188. # Опубликованные страницы с фильтром по домену
  189. published:
  190. map: ((doc) ->
  191. if doc.type is 'page' and doc.status is 'published'
  192. domain = doc.domain or 'default'
  193. emit([domain, doc.order or 0], doc)
  194. ).toString()
  195. # Design документ для меню с мультидоменностью
  196. menus:
  197. version: "2.0"
  198. views:
  199. # Меню по локации с фильтром по домену
  200. by_location:
  201. map: ((doc) ->
  202. if doc.type is 'menu'
  203. domain = doc.domain or 'default'
  204. emit([domain, doc.location], doc)
  205. ).toString()
  206. # Активные меню с фильтром по домену
  207. active:
  208. map: ((doc) ->
  209. if doc.type is 'menu' and doc.active is true
  210. domain = doc.domain or 'default'
  211. emit([domain, doc.location], doc)
  212. ).toString()
  213. # Design документ для настроек с мультидоменностью
  214. settings:
  215. version: "2.0"
  216. views:
  217. # Настройки по ключу с фильтром по домену
  218. by_key:
  219. map: ((doc) ->
  220. if doc.type is 'setting'
  221. domain = doc.domain or 'default'
  222. emit([domain, doc.key], doc)
  223. ).toString()
  224. # Design документ для пользователей
  225. users:
  226. version: "2.0"
  227. views:
  228. # Пользователи по email
  229. by_email:
  230. map: ((doc) ->
  231. if doc.type is 'user'
  232. emit(doc.email, doc)
  233. ).toString()
  234. # Пользователи по роли
  235. by_role:
  236. map: ((doc) ->
  237. if doc.type is 'user'
  238. emit(doc.role, doc)
  239. ).toString()
  240. # Активные пользователи
  241. active:
  242. map: ((doc) ->
  243. if doc.type is 'user' and doc.active is true
  244. emit(doc.email, doc)
  245. ).toString()
  246. # Design документ для заказов с мультидоменностью
  247. orders:
  248. version: "2.0"
  249. views:
  250. # Заказы по статусу с фильтром по домену
  251. by_status:
  252. map: ((doc) ->
  253. if doc.type is 'order'
  254. domain = doc.domain or 'default'
  255. emit([domain, doc.status, doc.created_at], doc)
  256. ).toString()
  257. # Заказы по пользователю с фильтром по домену
  258. by_user:
  259. map: ((doc) ->
  260. if doc.type is 'order'
  261. domain = doc.domain or 'default'
  262. emit([domain, doc.user_id, doc.created_at], doc)
  263. ).toString()
  264. # Design документ для глобального поиска с мультидоменностью
  265. global_search:
  266. version: "2.0"
  267. views:
  268. # Глобальный поиск по всем типам документов с фильтром по домену
  269. all_content:
  270. map: ((doc) ->
  271. searchFields = {}
  272. domain = doc.domain or 'default'
  273. switch doc.type
  274. when 'blog_post'
  275. if doc.status is 'published'
  276. searchFields =
  277. title: doc.title
  278. content: doc.content
  279. excerpt: doc.excerpt
  280. author: doc.author
  281. tags: doc.tags
  282. type: 'blog_post'
  283. when 'event'
  284. searchFields =
  285. title: doc.title
  286. content: doc.content
  287. location: doc.location
  288. tags: doc.tags
  289. type: 'event'
  290. when 'product'
  291. if doc.status is 'available'
  292. searchFields =
  293. title: doc.title
  294. content: doc.content
  295. excerpt: doc.excerpt
  296. category: doc.category
  297. tags: doc.tags
  298. type: 'product'
  299. when 'category', 'theme'
  300. searchFields =
  301. name: doc.name
  302. description: doc.description
  303. type: doc.type
  304. when 'page'
  305. if doc.status is 'published'
  306. searchFields =
  307. title: doc.title
  308. content: doc.content
  309. type: 'page'
  310. # Создаем поисковый индекс
  311. if searchFields.title
  312. text = (
  313. searchFields.title + " " +
  314. (searchFields.content or "") + " " +
  315. (searchFields.excerpt or "") + " " +
  316. (searchFields.author or "") + " " +
  317. (searchFields.location or "") + " " +
  318. (searchFields.description or "")
  319. ).toLowerCase()
  320. # Добавляем теги
  321. if searchFields.tags
  322. text += " " + searchFields.tags.join(" ")
  323. words = text.split(/\W+/).filter (word) -> word.length > 2
  324. for word in words
  325. emit([domain, word], {
  326. _id: doc._id
  327. type: searchFields.type
  328. title: searchFields.title
  329. excerpt: searchFields.excerpt
  330. created_at: doc.created_at
  331. domain: domain
  332. })
  333. ).toString()
  334. # Design документ для статистики с мультидоменностью
  335. statistics:
  336. version: "2.0"
  337. views:
  338. # Статистика по типам документов с фильтром по домену
  339. by_type:
  340. map: ((doc) ->
  341. domain = doc.domain or 'default'
  342. emit([domain, doc.type], 1)
  343. ).toString()
  344. reduce: ((keys, values) ->
  345. sum values
  346. ).toString()
  347. # Статистика просмотров блог постов с фильтром по домену
  348. blog_views:
  349. map: ((doc) ->
  350. if doc.type is 'blog_post'
  351. domain = doc.domain or 'default'
  352. emit([domain, doc._id], doc.views or 0)
  353. ).toString()
  354. reduce: ((keys, values) ->
  355. sum values
  356. ).toString()
  357. # Статистика мероприятий по статусу с фильтром по домену
  358. events_by_status:
  359. map: ((doc) ->
  360. if doc.type is 'event'
  361. domain = doc.domain or 'default'
  362. emit([domain, doc.status], 1)
  363. ).toString()
  364. reduce: ((keys, values) ->
  365. sum values
  366. ).toString()
  367. # Статистика продаж товаров с фильтром по домену
  368. product_sales:
  369. map: ((doc) ->
  370. if doc.type is 'order' and doc.items
  371. domain = doc.domain or 'default'
  372. for item in doc.items
  373. emit([domain, item.product_id], item.quantity)
  374. ).toString()
  375. reduce: ((keys, values) ->
  376. sum values
  377. ).toString()
  378. # Design документ для ревизий и аудита
  379. audit:
  380. version: "2.0"
  381. views:
  382. # Логи изменений по дате
  383. by_date:
  384. map: ((doc) ->
  385. if doc.type is 'audit_log'
  386. emit(doc.created_at, doc)
  387. ).toString()
  388. # Логи по пользователю
  389. by_user:
  390. map: ((doc) ->
  391. if doc.type is 'audit_log'
  392. emit([doc.user_id, doc.created_at], doc)
  393. ).toString()
  394. # Логи по действию
  395. by_action:
  396. map: ((doc) ->
  397. if doc.type is 'audit_log'
  398. emit([doc.action, doc.created_at], doc)
  399. ).toString()