@ozdao/martyrs 0.2.568 → 0.2.569

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/martyrs/src/components/Button/{Button.vue2.js → Button.vue.js} +3 -3
  2. package/dist/martyrs/src/components/Button/Button.vue.js.map +1 -0
  3. package/dist/martyrs/src/components/EditImages/{EditImages.vue.js → EditImages.vue2.js} +2 -2
  4. package/dist/martyrs/src/components/EditImages/EditImages.vue2.js.map +1 -0
  5. package/dist/martyrs/src/components/Feed/Carousel.vue.js +1 -1
  6. package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
  7. package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
  8. package/dist/martyrs/src/components/Loader/{Loader.vue.js → Loader.vue2.js} +2 -2
  9. package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +1 -0
  10. package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue.js +1 -1
  11. package/dist/martyrs/src/components/Media/Media.vue.js +1 -1
  12. package/dist/martyrs/src/components/Select/{Select.vue.js → Select.vue2.js} +2 -2
  13. package/dist/martyrs/src/components/Select/Select.vue2.js.map +1 -0
  14. package/dist/martyrs/src/components/UploadImage/UploadImage.vue.js +1 -1
  15. package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js +1 -1
  16. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
  17. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
  18. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +1 -1
  19. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
  20. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.js +1 -1
  21. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
  22. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
  23. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
  24. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
  25. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
  26. package/dist/martyrs/src/modules/community/components/layouts/Community.vue.js +1 -1
  27. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
  28. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +1 -1
  29. package/dist/martyrs/src/modules/core/views/components/blocks/CardHeader.vue.js +1 -1
  30. package/dist/martyrs/src/modules/core/views/components/blocks/PopupAuth.vue.js +1 -1
  31. package/dist/martyrs/src/modules/core/views/components/blocks/PopupDateSelector.vue.js +2 -2
  32. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +2 -2
  33. package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js +2 -2
  34. package/dist/martyrs/src/modules/core/views/components/partials/NavigationBar.vue.js +1 -1
  35. package/dist/martyrs/src/modules/core/views/components/sections/{Filters.vue.js → Filters.vue2.js} +2 -2
  36. package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue2.js.map +1 -0
  37. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
  38. package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.js +1 -1
  39. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +3 -3
  40. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
  41. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +2 -2
  42. package/dist/martyrs/src/modules/events/components/sections/EditTickets.vue.js +1 -1
  43. package/dist/martyrs/src/modules/events/components/sections/Feed.vue.js +1 -1
  44. package/dist/martyrs/src/modules/events/components/sections/List.vue.js +1 -1
  45. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +3 -3
  46. package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +2 -2
  47. package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.js +1 -1
  48. package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js +1 -1
  49. package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +2 -2
  50. package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +2 -2
  51. package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js +1 -1
  52. package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js +1 -1
  53. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +1 -1
  54. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +1 -1
  55. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +1 -1
  56. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +1 -1
  57. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +1 -1
  58. package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +2 -2
  59. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +3 -3
  60. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +1 -1
  61. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +1 -1
  62. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +2 -2
  63. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +2 -2
  64. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +2 -2
  65. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +1 -1
  66. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +2 -2
  67. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +2 -2
  68. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +2 -2
  69. package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
  70. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +1 -1
  71. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js +1 -1
  72. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +1 -1
  73. package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +2 -2
  74. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +2 -2
  75. package/dist/martyrs/src/modules/orders/components/forms/FormSelectCustomer.vue.js +2 -2
  76. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
  77. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +1 -1
  78. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
  79. package/dist/martyrs/src/modules/orders/components/sections/ApplicationDetails.vue.js +1 -1
  80. package/dist/martyrs/src/modules/orders/components/sections/CustomerDetails.vue.js +1 -1
  81. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -2
  82. package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.js +1 -1
  83. package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js +1 -1
  84. package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js +1 -1
  85. package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +1 -1
  86. package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js +1 -1
  87. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
  88. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +2 -2
  89. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +2 -2
  90. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +2 -2
  91. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  92. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  93. package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.js +1 -1
  94. package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js +1 -1
  95. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
  96. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +4 -4
  97. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +1 -1
  98. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +3 -3
  99. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
  100. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
  101. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +2 -2
  102. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +3 -3
  103. package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.js +1 -1
  104. package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.js +1 -1
  105. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +25 -38
  106. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js.map +1 -1
  107. package/dist/martyrs/src/modules/products/products.client.js +15 -21
  108. package/dist/martyrs/src/modules/products/products.client.js.map +1 -1
  109. package/dist/martyrs/src/modules/products/router/products.router.js +0 -34
  110. package/dist/martyrs/src/modules/products/router/products.router.js.map +1 -1
  111. package/dist/martyrs/src/modules/products/store/products.js +0 -15
  112. package/dist/martyrs/src/modules/products/store/products.js.map +1 -1
  113. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +1 -1
  114. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
  115. package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +2 -2
  116. package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
  117. package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +1 -1
  118. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
  119. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +2 -2
  120. package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
  121. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +2 -2
  122. package/dist/products.server.js +1 -130
  123. package/dist/style.css +0 -23
  124. package/package.json +1 -1
  125. package/src/modules/products/components/sections/SectionProduct.vue +2 -9
  126. package/src/modules/products/controllers/products.controller.js +0 -51
  127. package/src/modules/products/experiments/product-recommendation/README.md +156 -0
  128. package/src/modules/products/experiments/product-recommendation/controllers/recommendation.controller.js +59 -0
  129. package/src/modules/products/experiments/product-recommendation/router/recommendation.router.js +43 -0
  130. package/src/modules/products/experiments/product-recommendation/routes/recommendation.routes.js +10 -0
  131. package/src/modules/products/experiments/product-recommendation/store/recommendation.store.js +38 -0
  132. package/src/modules/products/products.client.js +0 -6
  133. package/src/modules/products/products.router.js +0 -29
  134. package/src/modules/products/router/products.router.js +0 -28
  135. package/src/modules/products/routes/products.routes.js +0 -2
  136. package/src/modules/products/store/products.js +0 -16
  137. package/dist/martyrs/src/components/Button/Button.vue2.js.map +0 -1
  138. package/dist/martyrs/src/components/EditImages/EditImages.vue.js.map +0 -1
  139. package/dist/martyrs/src/components/Loader/Loader.vue.js.map +0 -1
  140. package/dist/martyrs/src/components/Select/Select.vue.js.map +0 -1
  141. package/dist/martyrs/src/components/Shader/Shader.vue.js +0 -2
  142. package/dist/martyrs/src/components/Shader/Shader.vue.js.map +0 -1
  143. package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js.map +0 -1
  144. package/dist/martyrs/src/modules/products/components/pages/ProductRecommmendation.vue.js +0 -106
  145. package/dist/martyrs/src/modules/products/components/pages/ProductRecommmendation.vue.js.map +0 -1
  146. package/dist/martyrs/src/modules/products/components/sections/HeroRecommendation.vue.js +0 -120
  147. package/dist/martyrs/src/modules/products/components/sections/HeroRecommendation.vue.js.map +0 -1
  148. /package/src/modules/products/{components/sections → experiments/product-recommendation/components}/HeroRecommendation.vue +0 -0
  149. /package/src/modules/products/{components/pages → experiments/product-recommendation/components}/ProductRecommmendation.vue +0 -0
@@ -1,7 +1,7 @@
1
1
  import { computed, ref, watch, createElementBlock, openBlock, createElementVNode, createVNode, withCtx, createTextVNode } from "vue";
2
2
  import dayjs from "../../../../../../../../_virtual/dayjs.min.js";
3
3
  import _sfc_main$2 from "../../../../../../components/Tab/Tab.vue2.js";
4
- import _sfc_main$3 from "../../../../../../components/Button/Button.vue2.js";
4
+ import _sfc_main$3 from "../../../../../../components/Button/Button.vue.js";
5
5
  import _sfc_main$4 from "../../../../../../components/Dropdown/Dropdown.vue.js";
6
6
  import Calendar from "../../../../../../components/Calendar/Calendar.vue2.js";
7
7
  import _sfc_main$1 from "./DateLabel.vue.js";
@@ -1,6 +1,6 @@
1
1
  import { ref, computed, onMounted, createElementBlock, openBlock, createElementVNode, createVNode, toDisplayString, unref, withCtx, Fragment, renderList, createBlock, createCommentVNode, createTextVNode } from "vue";
2
2
  import _sfc_main$4 from "../../../../../components/Block/Block.vue.js";
3
- import _sfc_main$5 from "../../../../../components/Button/Button.vue2.js";
3
+ import _sfc_main$5 from "../../../../../components/Button/Button.vue.js";
4
4
  import Field from "../../../../../components/Field/Field.vue.js";
5
5
  import _sfc_main$2 from "../../../../../components/Feed/Feed.vue.js";
6
6
  import _sfc_main$1 from "../../../../../components/Popup/Popup.vue.js";
@@ -1,7 +1,7 @@
1
1
  import { reactive, ref, createElementBlock, openBlock, renderSlot, createVNode, withCtx, createElementVNode, createTextVNode } from "vue";
2
2
  import _sfc_main$1 from "../../../../components/Popup/Popup.vue.js";
3
- import _sfc_main$2 from "../../../../components/Button/Button.vue2.js";
4
- import Select from "../../../../components/Select/Select.vue.js";
3
+ import _sfc_main$2 from "../../../../components/Button/Button.vue.js";
4
+ import Select from "../../../../components/Select/Select.vue2.js";
5
5
  import { actions } from "../../store/reports.js";
6
6
  const _sfc_main = {
7
7
  __name: "FormReport",
@@ -1,7 +1,7 @@
1
1
  import { ref, computed, resolveComponent, createElementBlock, openBlock, createElementVNode, createCommentVNode, createBlock, toDisplayString } from "vue";
2
2
  /* empty css */
3
3
  import _export_sfc from "../../../../../../_virtual/_plugin-vue_export-helper.js";
4
- /* empty css */
4
+ /* empty css */
5
5
  /* empty css */
6
6
  const _hoisted_1 = { class: "br-grey-transp-25 radius-small mn-b-small" };
7
7
  const _hoisted_2 = {
@@ -1,7 +1,7 @@
1
1
  import { ref, onMounted, createElementBlock, openBlock, createElementVNode, createVNode, withCtx, createTextVNode } from "vue";
2
2
  import { useRouter, useRoute } from "vue-router";
3
3
  import { Loader } from "../../../../../../node_modules/.pnpm/@googlemaps_js-api-loader@1.16.8/node_modules/@googlemaps/js-api-loader/dist/index.js";
4
- import _sfc_main$1 from "../../../../components/Button/Button.vue2.js";
4
+ import _sfc_main$1 from "../../../../components/Button/Button.vue.js";
5
5
  import { actions, state as state$1 } from "../../../organizations/store/organizations.js";
6
6
  import { useStore } from "../../../core/views/store/core.store.js";
7
7
  import { state } from "../../../marketplace/views/store/marketplace.js";
@@ -4,11 +4,11 @@ import _sfc_main$1 from "../../../../components/Block/Block.vue.js";
4
4
  import UploadImage from "../../../../components/UploadImage/UploadImage.vue.js";
5
5
  /* empty css */
6
6
  import Field from "../../../../components/Field/Field.vue.js";
7
- import Select from "../../../../components/Select/Select.vue.js";
7
+ import Select from "../../../../components/Select/Select.vue2.js";
8
8
  import _sfc_main$3 from "../../../../components/Checkbox/Checkbox.vue.js";
9
9
  import _sfc_main$4 from "../../../../components/Address/Address.vue.js";
10
10
  import _sfc_main$5 from "../../../../components/LocationMarker/LocationMarker.vue.js";
11
- import _sfc_main$2 from "../../../../components/Button/Button.vue2.js";
11
+ import _sfc_main$2 from "../../../../components/Button/Button.vue.js";
12
12
  /* empty css */
13
13
  import WorktimeEdit from "../sections/WorktimeEdit.vue.js";
14
14
  import { actions, state } from "../../store/spots.js";
@@ -1,8 +1,8 @@
1
1
  import { mergeModels, useModel, ref, computed, onMounted, createElementBlock, openBlock, createElementVNode, createVNode, toDisplayString, unref, withCtx, createTextVNode, Fragment, renderList, normalizeClass, createCommentVNode, createBlock } from "vue";
2
2
  import { useI18n } from "vue-i18n";
3
- import _sfc_main$1 from "../../../../components/Button/Button.vue2.js";
3
+ import _sfc_main$1 from "../../../../components/Button/Button.vue.js";
4
4
  import Field from "../../../../components/Field/Field.vue.js";
5
- import Select from "../../../../components/Select/Select.vue.js";
5
+ import Select from "../../../../components/Select/Select.vue2.js";
6
6
  import _sfc_main$3 from "../../../../components/Checkbox/Checkbox.vue.js";
7
7
  import _sfc_main$2 from "../../../../components/Popup/Popup.vue.js";
8
8
  /* empty css */
@@ -4,7 +4,7 @@ import { BigNumber } from "../../../../../../node_modules/.pnpm/bignumber.js@9.1
4
4
  import { state, actions } from "../../store/wallet.store.js";
5
5
  import text from "../../localization/wallet.json.js";
6
6
  import Field from "../../../../../components/Field/Field.vue.js";
7
- import Select from "../../../../../components/Select/Select.vue.js";
7
+ import Select from "../../../../../components/Select/Select.vue2.js";
8
8
  const _hoisted_1 = { class: "mn-b-small t-center t-bold" };
9
9
  const _hoisted_2 = { class: "t-semi" };
10
10
  const _hoisted_3 = ["disabled"];
@@ -4,11 +4,11 @@ import Web3 from "web3";
4
4
  import { state, actions } from "../../store/wallet.store.js";
5
5
  import text from "../../localization/wallet.json.js";
6
6
  import _sfc_main$3 from "../../../../../components/Popup/Popup.vue.js";
7
- import _sfc_main$1 from "../../../../../components/Button/Button.vue2.js";
7
+ import _sfc_main$1 from "../../../../../components/Button/Button.vue.js";
8
8
  import "vue-router";
9
9
  /* empty css */
10
10
  /* empty css */
11
- /* empty css */
11
+ /* empty css */
12
12
  import _sfc_main$2 from "../elements/ConnectMetamask.vue.js";
13
13
  import _sfc_main$4 from "../blocks/CashDeposit.vue.js";
14
14
  import _sfc_main$5 from "../blocks/CardDeposit.vue.js";
@@ -1,7 +1,6 @@
1
1
  import { C as CacheNamespaced } from "./core.cache-DALYFDdy.js";
2
2
  import { L as LoggerNamespaced, c as coreabac } from "./abac-BPl9Bmf9.js";
3
3
  import { q as queryProcessorCore } from "./queryProcessor-C_5Iipam.js";
4
- import OpenAI from "openai";
5
4
  import { Types } from "mongoose";
6
5
  import { a as applyCommonSchema } from "./common.schema-DswiUXKB.js";
7
6
  import { a as applyEngagementSchema } from "./engagement.schema-fh6W1fb_.js";
@@ -344,92 +343,6 @@ const controllerFactory$1 = (db) => {
344
343
  }
345
344
  };
346
345
  };
347
- class OpenAIGlobal {
348
- constructor() {
349
- if (OpenAIGlobal.instance) {
350
- return OpenAIGlobal.instance;
351
- }
352
- this.client = new OpenAI({
353
- organization: process.env.OPENAI_ORG_KEY,
354
- apiKey: process.env.OPENAI_API_KEY
355
- });
356
- this.models = {
357
- chat: "gpt-3.5-turbo",
358
- vision: "gpt-4-vision-preview",
359
- embedding: "text-embedding-ada-002"
360
- };
361
- OpenAIGlobal.instance = this;
362
- }
363
- /**
364
- * Generate completions with retry logic for handling JSON parsing errors
365
- * @param {string} prompt - The prompt text
366
- * @param {Object} options - Additional options
367
- * @returns {Promise<Object|string>} - Parsed JSON response or raw content
368
- */
369
- async createChatCompletion(prompt, options = {}) {
370
- const {
371
- model = this.models.chat,
372
- maxRetries = 3,
373
- temperature = 0.7,
374
- parseJSON = true,
375
- systemPrompt = ""
376
- } = options;
377
- let attempt = 0;
378
- while (attempt < maxRetries) {
379
- try {
380
- const messages = [];
381
- if (systemPrompt) {
382
- messages.push({ role: "system", content: systemPrompt });
383
- }
384
- messages.push({ role: "user", content: prompt });
385
- const response = await this.client.chat.completions.create({
386
- model,
387
- messages,
388
- temperature,
389
- response_format: parseJSON ? { type: "json_object" } : void 0
390
- });
391
- const content = response.choices[0].message.content;
392
- if (parseJSON) {
393
- return JSON.parse(content);
394
- }
395
- return content;
396
- } catch (err) {
397
- attempt++;
398
- if (err instanceof SyntaxError && attempt < maxRetries) {
399
- console.error(`Invalid JSON in OpenAI response (attempt ${attempt}/${maxRetries}): ${err.message}`);
400
- } else if (attempt >= maxRetries) {
401
- console.error(`Max retries (${maxRetries}) reached for OpenAI completion: ${err.message}`);
402
- throw err;
403
- } else {
404
- console.error(`OpenAI API error (attempt ${attempt}/${maxRetries}): ${err.message}`);
405
- if (err.status === 429) {
406
- const waitTime = Math.pow(2, attempt) * 1e3;
407
- await new Promise((resolve) => setTimeout(resolve, waitTime));
408
- }
409
- }
410
- await new Promise((resolve) => setTimeout(resolve, 1e3 * attempt));
411
- }
412
- }
413
- }
414
- /**
415
- * Get direct access to OpenAI client instance
416
- * @returns {OpenAI} - OpenAI client instance
417
- */
418
- getClient() {
419
- return this.client;
420
- }
421
- /**
422
- * Set default model for specific API
423
- * @param {string} type - API type ('chat', 'vision', 'embedding')
424
- * @param {string} modelId - Model identifier
425
- */
426
- setDefaultModel(type, modelId) {
427
- if (this.models[type]) {
428
- this.models[type] = modelId;
429
- }
430
- }
431
- }
432
- const openaiGlobal = new OpenAIGlobal();
433
346
  const ObjectId = Types.ObjectId;
434
347
  function getCategoriesFilterStage(categories) {
435
348
  if (!categories) return [];
@@ -883,52 +796,11 @@ const controllerFactory = (db) => {
883
796
  res.status(500).send({ message: err.message });
884
797
  }
885
798
  };
886
- const getProductRecommendation = async (req, res) => {
887
- const { mood } = req.body;
888
- try {
889
- const products = await Product.find({
890
- status: "published"
891
- }).limit(40);
892
- if (!products) {
893
- console.log("no products");
894
- return res.status(404).send({ message: "Products not found." });
895
- }
896
- const productsList = products.map((p) => {
897
- const info = p.attributes || [];
898
- const value0 = info[0] ? info[0].value : "";
899
- const value1 = info[1] ? `(${info[1].value}%)` : "";
900
- const value2 = info[2] ? `(${info[2].value})` : "";
901
- return `${p._id}: ${p.name} (${value0}) ${value1} ${value2}`;
902
- }).join(", ");
903
- const prompt = `
904
- 1. When asked how the client wants to feel, they responded "${mood}".
905
- 2. Here is a list of products in our store: ${productsList}.
906
- 3. Based on the attributes about the products (strain, THC content) and the user's desires, choose 1 product to recommend to the user.
907
- 4. The response should be in the language that the user used in mood (${mood}).
908
- 5. Please format your response as a JSON object '{"_id": "ID of the recommended product (it must correspond to one of the product IDs I sent)", "recommendationText": "Text explaining why this particular product"'. Write only the JSON object without any other text outside of it.
909
- `;
910
- const result = await openaiGlobal.createChatCompletion(prompt, {
911
- model: "gpt-4",
912
- temperature: 0.8,
913
- systemPrompt: "You are a product recommendation specialist with expertise in matching customer needs to product attributes."
914
- });
915
- const recommendedProduct = await Product.findById(result._id);
916
- if (!recommendedProduct) {
917
- console.log(`No product found with _id: ${result._id}`);
918
- return res.status(404).send({ message: "Recommended product not found." });
919
- }
920
- res.status(200).json({ product: recommendedProduct, recommendationText: result.recommendationText });
921
- } catch (err) {
922
- console.log(err);
923
- res.status(500).send({ message: err });
924
- }
925
- };
926
799
  return {
927
800
  Create,
928
801
  Read,
929
802
  Update,
930
- Delete,
931
- getProductRecommendation
803
+ Delete
932
804
  };
933
805
  };
934
806
  const CategoryModel = (db) => {
@@ -1447,7 +1319,6 @@ const productsRoutes = (function(app, db, allowedOrigins) {
1447
1319
  app.get("/api/products/read", controller.Read);
1448
1320
  app.post("/api/products/:_id", controller.Update);
1449
1321
  app.delete("/api/products/:_id", controller.Delete);
1450
- app.post("/api/product/recommended", controller.getProductRecommendation);
1451
1322
  });
1452
1323
  const verifierFactory = (function(db) {
1453
1324
  const createVerifier = new Verifier({
package/dist/style.css CHANGED
@@ -2604,27 +2604,6 @@ to { opacity: 1; transform: translateY(0);
2604
2604
  .thumbnail.active[data-v-eddb4b2b] {
2605
2605
  border: 1px solid rgb(var(--second));
2606
2606
  }
2607
-
2608
- .spiral {
2609
- object-fit: cover;
2610
- width: 100rem;
2611
- height: 100rem;
2612
- position: absolute;
2613
- top: 50%;
2614
- left: 50%;
2615
- opacity: 0.066;
2616
- transform: translate(-50%, -50%) rotate(0deg);
2617
- transform-origin: center center;
2618
- animation: spin 5s linear infinite;
2619
- }
2620
- @keyframes spin {
2621
- 0% {
2622
- transform: translate(-50%, -50%) rotate(0deg);
2623
- }
2624
- 100% {
2625
- transform: translate(-50%, -50%) rotate(360deg);
2626
- }
2627
- }
2628
2607
  .popupar_products .carousel__slide {
2629
2608
  flex: 0 0 25%;
2630
2609
  min-width: 0;
@@ -2651,8 +2630,6 @@ to { opacity: 1; transform: translateY(0);
2651
2630
  .text-muted[data-v-a5eb77c9] {
2652
2631
  color: #6c757d;
2653
2632
  }
2654
-
2655
- /* Add your styles here */
2656
2633
  .custom-table[data-v-b85cde7e] {
2657
2634
  border-collapse: collapse;
2658
2635
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozdao/martyrs",
3
- "version": "0.2.568",
3
+ "version": "0.2.569",
4
4
  "description": "Fullstack framework focused on user experience and ease of development.",
5
5
  "author": "OZ DAO <hello@ozdao.dev>",
6
6
  "license": "GPL-3.0-or-later",
@@ -41,7 +41,6 @@
41
41
  class="pos-absolute pos-t-regular pos-r-regular i-medium t-transp"
42
42
  />
43
43
 
44
- <h2 v-if="recommendation" class="t-main t-semi p-medium">{{t('airecommend')}}</h2>
45
44
  <!-- Name -->
46
45
  <h1 class="w-100 h1-product mn-b-small">{{ product.name }}</h1>
47
46
  <!-- Price -->
@@ -51,9 +50,6 @@
51
50
  <SelectElement v-if="sizes2.length > 0" :elements="sizes2" :selected="product.selectedSize" class="mn-r-medium" />
52
51
  </div> -->
53
52
  <!-- Description -->
54
- <h3 v-if="recommendation" class="mn-b-semi">
55
- {{ recommendation }}
56
- </h3>
57
53
 
58
54
  <Tab
59
55
  v-model:selected="tabProduct"
@@ -69,11 +65,11 @@
69
65
  <transition name="slide-fade">
70
66
 
71
67
  <div v-if="tabProduct === 'description'" class="pd-medium radius-medium bg-light ">
72
- <p v-if="product.description && !product.translations < 1 && !recommendation" class="w-100 t-transp">
68
+ <p v-if="product.description && !product.translations < 1" class="w-100 t-transp">
73
69
  {{ product.description }}
74
70
  </p>
75
71
 
76
- <p v-if="product.translations && product.translations.length > 1 && !recommendation" class="w-100 t-transp">
72
+ <p v-if="product.translations && product.translations.length > 1" class="w-100 t-transp">
77
73
  {{ t('description') }}
78
74
  </p>
79
75
  </div>
@@ -161,9 +157,6 @@ const props = defineProps({
161
157
  accesses: {
162
158
  type: Object,
163
159
  default: null
164
- },
165
- recommendation: {
166
- type: String
167
160
  }
168
161
  })
169
162
 
@@ -1,5 +1,3 @@
1
- import ChatGPT from '@martyrs/src/modules/integrations/openai/openai.globals.js';
2
-
3
1
  import queryProcessorCore from '@martyrs/src/modules/core/controllers/utils/queryProcessor.js';
4
2
  import queryProcessorProducts from '@martyrs/src/modules/products/controllers/queries/products.queries.js';
5
3
 
@@ -158,61 +156,12 @@ const controllerFactory = db => {
158
156
  res.status(500).send({ message: err.message });
159
157
  }
160
158
  };
161
-
162
- const getProductRecommendation = async (req, res) => {
163
- const { mood } = req.body;
164
- try {
165
- const products = await Product.find({
166
- status: 'published',
167
- }).limit(40);
168
- if (!products) {
169
- console.log('no products');
170
- return res.status(404).send({ message: 'Products not found.' });
171
- }
172
- const productsList = products
173
- .map(p => {
174
- const info = p.attributes || [];
175
- const value0 = info[0] ? info[0].value : '';
176
- const value1 = info[1] ? `(${info[1].value}%)` : '';
177
- const value2 = info[2] ? `(${info[2].value})` : '';
178
- return `${p._id}: ${p.name} (${value0}) ${value1} ${value2}`;
179
- })
180
- .join(', ');
181
-
182
- const prompt = `
183
- 1. When asked how the client wants to feel, they responded "${mood}".
184
- 2. Here is a list of products in our store: ${productsList}.
185
- 3. Based on the attributes about the products (strain, THC content) and the user's desires, choose 1 product to recommend to the user.
186
- 4. The response should be in the language that the user used in mood (${mood}).
187
- 5. Please format your response as a JSON object '{"_id": "ID of the recommended product (it must correspond to one of the product IDs I sent)", "recommendationText": "Text explaining why this particular product"'. Write only the JSON object without any other text outside of it.
188
- `;
189
-
190
- // Specify a model explicitly
191
- const result = await ChatGPT.createChatCompletion(prompt, {
192
- model: 'gpt-4',
193
- temperature: 0.8,
194
- systemPrompt: 'You are a product recommendation specialist with expertise in matching customer needs to product attributes.'
195
- });
196
-
197
- const recommendedProduct = await Product.findById(result._id);
198
-
199
- if (!recommendedProduct) {
200
- console.log(`No product found with _id: ${result._id}`);
201
- return res.status(404).send({ message: 'Recommended product not found.' });
202
- }
203
- res.status(200).json({ product: recommendedProduct, recommendationText: result.recommendationText });
204
- } catch (err) {
205
- console.log(err);
206
- res.status(500).send({ message: err });
207
- }
208
- };
209
159
 
210
160
  return {
211
161
  Create,
212
162
  Read,
213
163
  Update,
214
164
  Delete,
215
- getProductRecommendation,
216
165
  };
217
166
  };
218
167
  export default controllerFactory;
@@ -0,0 +1,156 @@
1
+ # Product Recommendation (Experiment)
2
+
3
+ AI-powered product recommendation feature using OpenAI GPT-4.
4
+
5
+ ## Overview
6
+
7
+ This experiment provides personalized product recommendations based on user mood/preferences using ChatGPT.
8
+
9
+ ## Features
10
+
11
+ - AI-powered product selection based on user mood
12
+ - Integration with OpenAI GPT-4
13
+ - Custom recommendation page with mood input
14
+ - Recommendation display in product details
15
+
16
+ ## Structure
17
+
18
+ ```
19
+ experiments/product-recommendation/
20
+ ├── components/
21
+ │ ├── ProductRecommmendation.vue # Main recommendation page
22
+ │ └── HeroRecommendation.vue # Mood input component
23
+ ├── store/
24
+ │ └── recommendation.store.js # Store for recommendation state
25
+ ├── controllers/
26
+ │ └── recommendation.controller.js # Backend recommendation logic
27
+ ├── routes/
28
+ │ └── recommendation.routes.js # API endpoint
29
+ ├── router/
30
+ │ └── recommendation.router.js # Frontend routes
31
+ └── README.md
32
+ ```
33
+
34
+ ## Requirements
35
+
36
+ To use this experiment, you need:
37
+
38
+ 1. **OpenAI API Key** in your `.env` file:
39
+ ```
40
+ OPENAI_API_KEY=your-api-key-here
41
+ ```
42
+
43
+ 2. **OpenAI integration** at `/martyrs/src/modules/integrations/openai/openai.globals.js`
44
+
45
+ ## How to Enable
46
+
47
+ ### 1. Backend Setup
48
+
49
+ Add to your `products.server.js`:
50
+
51
+ ```javascript
52
+ import recommendationRoutes from './experiments/product-recommendation/routes/recommendation.routes.js';
53
+
54
+ // In initialize function:
55
+ recommendationRoutes(app, db);
56
+ ```
57
+
58
+ ### 2. Frontend Store
59
+
60
+ Add to your `products.client.js`:
61
+
62
+ ```javascript
63
+ import * as storeRecommendation from './experiments/product-recommendation/store/recommendation.store.js';
64
+
65
+ // In initialize function:
66
+ store.addStore('recommendation', storeRecommendation);
67
+ ```
68
+
69
+ ### 3. Frontend Routes
70
+
71
+ Import and add routes from `./experiments/product-recommendation/router/recommendation.router.js`:
72
+
73
+ ```javascript
74
+ import { recommendationRoutes } from './experiments/product-recommendation/router/recommendation.router.js';
75
+
76
+ // Add to your routes:
77
+ ...recommendationRoutes.homeRoutes,
78
+ ...recommendationRoutes.organizationRoutes,
79
+ ```
80
+
81
+ ### 4. Component Exports
82
+
83
+ Add to `products.client.js` exports:
84
+
85
+ ```javascript
86
+ import HeroRecommendation from './experiments/product-recommendation/components/HeroRecommendation.vue';
87
+ import ProductRecommendation from './experiments/product-recommendation/components/ProductRecommmendation.vue';
88
+
89
+ export {
90
+ // ... other exports
91
+ HeroRecommendation,
92
+ ProductRecommendation,
93
+ };
94
+ ```
95
+
96
+ ### 5. SectionProduct Integration (Optional)
97
+
98
+ To show recommendations in product details, add to `SectionProduct.vue`:
99
+
100
+ ```vue
101
+ <template>
102
+ <SectionProduct
103
+ :product="product"
104
+ :recommendation="recommendation.state.current.recommendation"
105
+ />
106
+ </template>
107
+
108
+ <script>
109
+ import * as recommendation from '../experiments/product-recommendation/store/recommendation.store.js';
110
+ </script>
111
+ ```
112
+
113
+ And add prop to `SectionProduct.vue`:
114
+
115
+ ```javascript
116
+ defineProps({
117
+ // ... other props
118
+ recommendation: {
119
+ type: String
120
+ }
121
+ })
122
+ ```
123
+
124
+ ## Usage
125
+
126
+ 1. Navigate to `/products/recommendation`
127
+ 2. Enter your mood/preference
128
+ 3. Get AI-powered product recommendation
129
+ 4. View recommended product details
130
+
131
+ ## API Endpoint
132
+
133
+ ```
134
+ POST /api/product/recommended
135
+ Body: { mood: "your mood here" }
136
+ Response: { product: {...}, recommendationText: "..." }
137
+ ```
138
+
139
+ ## Notes
140
+
141
+ - Requires OpenAI API key and valid subscription
142
+ - Uses GPT-4 model for better recommendations
143
+ - Customize prompt in `recommendation.controller.js`
144
+ - Product attributes (strain, THC content) are used for matching
145
+
146
+ ## Removed from Core
147
+
148
+ This feature was moved to experiments to:
149
+ - Remove OpenAI dependency from core products module
150
+ - Make it optional for projects that don't need AI recommendations
151
+ - Allow easier customization and experimentation
152
+ - Reduce bundle size for projects without AI features
153
+
154
+ ## License
155
+
156
+ Part of @ozdao/martyrs framework.
@@ -0,0 +1,59 @@
1
+ import ChatGPT from '@martyrs/src/modules/integrations/openai/openai.globals.js';
2
+
3
+ const controllerFactory = db => {
4
+ const Product = db.product;
5
+
6
+ const getProductRecommendation = async (req, res) => {
7
+ const { mood } = req.body;
8
+ try {
9
+ const products = await Product.find({
10
+ status: 'published',
11
+ }).limit(40);
12
+ if (!products) {
13
+ console.log('no products');
14
+ return res.status(404).send({ message: 'Products not found.' });
15
+ }
16
+ const productsList = products
17
+ .map(p => {
18
+ const info = p.attributes || [];
19
+ const value0 = info[0] ? info[0].value : '';
20
+ const value1 = info[1] ? `(${info[1].value}%)` : '';
21
+ const value2 = info[2] ? `(${info[2].value})` : '';
22
+ return `${p._id}: ${p.name} (${value0}) ${value1} ${value2}`;
23
+ })
24
+ .join(', ');
25
+
26
+ const prompt = `
27
+ 1. When asked how the client wants to feel, they responded "${mood}".
28
+ 2. Here is a list of products in our store: ${productsList}.
29
+ 3. Based on the attributes about the products (strain, THC content) and the user's desires, choose 1 product to recommend to the user.
30
+ 4. The response should be in the language that the user used in mood (${mood}).
31
+ 5. Please format your response as a JSON object '{"_id": "ID of the recommended product (it must correspond to one of the product IDs I sent)", "recommendationText": "Text explaining why this particular product"'. Write only the JSON object without any other text outside of it.
32
+ `;
33
+
34
+ // Specify a model explicitly
35
+ const result = await ChatGPT.createChatCompletion(prompt, {
36
+ model: 'gpt-4',
37
+ temperature: 0.8,
38
+ systemPrompt: 'You are a product recommendation specialist with expertise in matching customer needs to product attributes.'
39
+ });
40
+
41
+ const recommendedProduct = await Product.findById(result._id);
42
+
43
+ if (!recommendedProduct) {
44
+ console.log(`No product found with _id: ${result._id}`);
45
+ return res.status(404).send({ message: 'Recommended product not found.' });
46
+ }
47
+ res.status(200).json({ product: recommendedProduct, recommendationText: result.recommendationText });
48
+ } catch (err) {
49
+ console.log(err);
50
+ res.status(500).send({ message: err });
51
+ }
52
+ };
53
+
54
+ return {
55
+ getProductRecommendation,
56
+ };
57
+ };
58
+
59
+ export default controllerFactory;