@open-mercato/core 0.6.6-develop.6094.1.28b081ea16 → 0.6.6-develop.6126.1.0b9392fdae

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 (317) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/catalog_product/index.js +52 -0
  3. package/dist/generated/entities/catalog_product/index.js.map +2 -2
  4. package/dist/generated/entities/catalog_product_variant/index.js +4 -0
  5. package/dist/generated/entities/catalog_product_variant/index.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +28 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/modules/catalog/api/products/route.js +103 -33
  9. package/dist/modules/catalog/api/products/route.js.map +2 -2
  10. package/dist/modules/catalog/api/variants/route.js +4 -0
  11. package/dist/modules/catalog/api/variants/route.js.map +2 -2
  12. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +46 -2
  13. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  14. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +4 -0
  15. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  16. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +2 -0
  17. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
  18. package/dist/modules/catalog/backend/catalog/products/create/page.js +42 -2
  19. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  20. package/dist/modules/catalog/commands/products.js +251 -14
  21. package/dist/modules/catalog/commands/products.js.map +2 -2
  22. package/dist/modules/catalog/commands/variants.js +72 -1
  23. package/dist/modules/catalog/commands/variants.js.map +2 -2
  24. package/dist/modules/catalog/components/products/ProductComplianceSection.js +500 -0
  25. package/dist/modules/catalog/components/products/ProductComplianceSection.js.map +7 -0
  26. package/dist/modules/catalog/components/products/VariantBuilder.js +39 -1
  27. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  28. package/dist/modules/catalog/components/products/productForm.js +164 -2
  29. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  30. package/dist/modules/catalog/components/products/variantForm.js +2 -0
  31. package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
  32. package/dist/modules/catalog/data/entities.js +93 -0
  33. package/dist/modules/catalog/data/entities.js.map +2 -2
  34. package/dist/modules/catalog/data/types.js +28 -0
  35. package/dist/modules/catalog/data/types.js.map +2 -2
  36. package/dist/modules/catalog/data/validators.js +100 -5
  37. package/dist/modules/catalog/data/validators.js.map +2 -2
  38. package/dist/modules/catalog/lib/gtin.js +61 -0
  39. package/dist/modules/catalog/lib/gtin.js.map +7 -0
  40. package/dist/modules/catalog/migrations/Migration20260611090000.js +17 -0
  41. package/dist/modules/catalog/migrations/Migration20260611090000.js.map +7 -0
  42. package/dist/modules/catalog/translations.js +1 -1
  43. package/dist/modules/catalog/translations.js.map +2 -2
  44. package/dist/modules/configs/api/cache/route.js +60 -10
  45. package/dist/modules/configs/api/cache/route.js.map +3 -3
  46. package/dist/modules/configs/components/CachePanel.js +52 -29
  47. package/dist/modules/configs/components/CachePanel.js.map +2 -2
  48. package/dist/modules/currencies/api/currencies/options/route.js +18 -4
  49. package/dist/modules/currencies/api/currencies/options/route.js.map +2 -2
  50. package/dist/modules/currencies/services/rateFetchingService.js +35 -18
  51. package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
  52. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +16 -16
  53. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  54. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +1 -1
  55. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  56. package/dist/modules/customers/backend/calendar/page.js +10 -0
  57. package/dist/modules/customers/backend/calendar/page.js.map +7 -0
  58. package/dist/modules/customers/backend/calendar/page.meta.js +25 -0
  59. package/dist/modules/customers/backend/calendar/page.meta.js.map +7 -0
  60. package/dist/modules/customers/cli.js +1 -0
  61. package/dist/modules/customers/cli.js.map +2 -2
  62. package/dist/modules/customers/components/calendar/AgendaList.js +182 -0
  63. package/dist/modules/customers/components/calendar/AgendaList.js.map +7 -0
  64. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +331 -0
  65. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +7 -0
  66. package/dist/modules/customers/components/calendar/CalendarFooter.js +48 -0
  67. package/dist/modules/customers/components/calendar/CalendarFooter.js.map +7 -0
  68. package/dist/modules/customers/components/calendar/CalendarHeader.js +36 -0
  69. package/dist/modules/customers/components/calendar/CalendarHeader.js.map +7 -0
  70. package/dist/modules/customers/components/calendar/CalendarScreen.js +516 -0
  71. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +7 -0
  72. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +163 -0
  73. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +7 -0
  74. package/dist/modules/customers/components/calendar/CalendarTabs.js +60 -0
  75. package/dist/modules/customers/components/calendar/CalendarTabs.js.map +7 -0
  76. package/dist/modules/customers/components/calendar/CalendarToolbar.js +262 -0
  77. package/dist/modules/customers/components/calendar/CalendarToolbar.js.map +7 -0
  78. package/dist/modules/customers/components/calendar/EventBlock.js +149 -0
  79. package/dist/modules/customers/components/calendar/EventBlock.js.map +7 -0
  80. package/dist/modules/customers/components/calendar/EventPeekPopover.js +72 -0
  81. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +7 -0
  82. package/dist/modules/customers/components/calendar/MonthGrid.js +214 -0
  83. package/dist/modules/customers/components/calendar/MonthGrid.js.map +7 -0
  84. package/dist/modules/customers/components/calendar/ShortcutsDialog.js +44 -0
  85. package/dist/modules/customers/components/calendar/ShortcutsDialog.js.map +7 -0
  86. package/dist/modules/customers/components/calendar/TimeGrid.js +410 -0
  87. package/dist/modules/customers/components/calendar/TimeGrid.js.map +7 -0
  88. package/dist/modules/customers/components/calendar/UpcomingCards.js +175 -0
  89. package/dist/modules/customers/components/calendar/UpcomingCards.js.map +7 -0
  90. package/dist/modules/customers/components/calendar/editor/CategoryField.js +75 -0
  91. package/dist/modules/customers/components/calendar/editor/CategoryField.js.map +7 -0
  92. package/dist/modules/customers/components/calendar/editor/LocationField.js +30 -0
  93. package/dist/modules/customers/components/calendar/editor/LocationField.js.map +7 -0
  94. package/dist/modules/customers/components/calendar/editor/PeopleField.js +135 -0
  95. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +7 -0
  96. package/dist/modules/customers/components/calendar/editor/RelatedToField.js +218 -0
  97. package/dist/modules/customers/components/calendar/editor/RelatedToField.js.map +7 -0
  98. package/dist/modules/customers/components/calendar/editor/RepeatField.js +119 -0
  99. package/dist/modules/customers/components/calendar/editor/RepeatField.js.map +7 -0
  100. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js +83 -0
  101. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js.map +7 -0
  102. package/dist/modules/customers/components/calendar/editor/SegmentGroup.js +44 -0
  103. package/dist/modules/customers/components/calendar/editor/SegmentGroup.js.map +7 -0
  104. package/dist/modules/customers/components/calendar/editor/hooks.js +132 -0
  105. package/dist/modules/customers/components/calendar/editor/hooks.js.map +7 -0
  106. package/dist/modules/customers/components/calendar/editor/inputs.js +160 -0
  107. package/dist/modules/customers/components/calendar/editor/inputs.js.map +7 -0
  108. package/dist/modules/customers/components/calendar/editor/lookups.js +107 -0
  109. package/dist/modules/customers/components/calendar/editor/lookups.js.map +7 -0
  110. package/dist/modules/customers/components/calendar/types.js +30 -0
  111. package/dist/modules/customers/components/calendar/types.js.map +7 -0
  112. package/dist/modules/customers/components/calendar/useCalendarItems.js +131 -0
  113. package/dist/modules/customers/components/calendar/useCalendarItems.js.map +7 -0
  114. package/dist/modules/customers/components/calendar/useCalendarPreferences.js +41 -0
  115. package/dist/modules/customers/components/calendar/useCalendarPreferences.js.map +7 -0
  116. package/dist/modules/customers/lib/calendar/categories.js +28 -0
  117. package/dist/modules/customers/lib/calendar/categories.js.map +7 -0
  118. package/dist/modules/customers/lib/calendar/conflicts.js +72 -0
  119. package/dist/modules/customers/lib/calendar/conflicts.js.map +7 -0
  120. package/dist/modules/customers/lib/calendar/editorPayload.js +271 -0
  121. package/dist/modules/customers/lib/calendar/editorPayload.js.map +7 -0
  122. package/dist/modules/customers/lib/calendar/grid.js +48 -0
  123. package/dist/modules/customers/lib/calendar/grid.js.map +7 -0
  124. package/dist/modules/customers/lib/calendar/layout.js +39 -0
  125. package/dist/modules/customers/lib/calendar/layout.js.map +7 -0
  126. package/dist/modules/customers/lib/calendar/mapItem.js +79 -0
  127. package/dist/modules/customers/lib/calendar/mapItem.js.map +7 -0
  128. package/dist/modules/customers/lib/calendar/preferences.js +71 -0
  129. package/dist/modules/customers/lib/calendar/preferences.js.map +7 -0
  130. package/dist/modules/customers/lib/calendar/range.js +46 -0
  131. package/dist/modules/customers/lib/calendar/range.js.map +7 -0
  132. package/dist/modules/customers/lib/calendar/recurrence.js +113 -0
  133. package/dist/modules/customers/lib/calendar/recurrence.js.map +7 -0
  134. package/dist/modules/dashboards/services/widgetDataService.js +5 -5
  135. package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
  136. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +61 -1
  137. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  138. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +33 -1
  139. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  140. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +61 -1
  141. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  142. package/dist/modules/dictionaries/api/route.js +33 -1
  143. package/dist/modules/dictionaries/api/route.js.map +2 -2
  144. package/dist/modules/feature_toggles/lib/queries.js +36 -52
  145. package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
  146. package/dist/modules/perspectives/api/[tableId]/[perspectiveId]/route.js +32 -1
  147. package/dist/modules/perspectives/api/[tableId]/[perspectiveId]/route.js.map +2 -2
  148. package/dist/modules/perspectives/api/[tableId]/roles/[roleId]/route.js +32 -1
  149. package/dist/modules/perspectives/api/[tableId]/roles/[roleId]/route.js.map +2 -2
  150. package/dist/modules/perspectives/api/[tableId]/route.js +73 -2
  151. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  152. package/dist/modules/perspectives/services/perspectiveService.js +5 -3
  153. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  154. package/dist/modules/planner/api/access.js +9 -0
  155. package/dist/modules/planner/api/access.js.map +2 -2
  156. package/dist/modules/planner/api/availability-date-specific.js +22 -1
  157. package/dist/modules/planner/api/availability-date-specific.js.map +2 -2
  158. package/dist/modules/planner/api/availability-weekly.js +22 -1
  159. package/dist/modules/planner/api/availability-weekly.js.map +2 -2
  160. package/dist/modules/resources/api/resources/tags/assign/route.js +39 -0
  161. package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
  162. package/dist/modules/resources/api/resources/tags/unassign/route.js +39 -0
  163. package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
  164. package/dist/modules/sales/api/settings/document-numbers/route.js +33 -1
  165. package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
  166. package/dist/modules/sales/api/settings/order-editing/route.js +35 -3
  167. package/dist/modules/sales/api/settings/order-editing/route.js.map +2 -2
  168. package/dist/modules/staff/api/leave-requests/accept/route.js +41 -0
  169. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  170. package/dist/modules/staff/api/leave-requests/reject/route.js +41 -0
  171. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  172. package/dist/modules/staff/api/team-members/self/route.js +40 -0
  173. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  174. package/dist/modules/staff/api/team-members/tags/assign/route.js +41 -0
  175. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  176. package/dist/modules/staff/api/team-members/tags/unassign/route.js +41 -0
  177. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  178. package/dist/modules/translations/api/[entityType]/[entityId]/route.js +61 -1
  179. package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
  180. package/dist/modules/translations/api/context.js +7 -0
  181. package/dist/modules/translations/api/context.js.map +2 -2
  182. package/dist/modules/translations/api/put/locales.js +33 -1
  183. package/dist/modules/translations/api/put/locales.js.map +2 -2
  184. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +6 -7
  185. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  186. package/dist/modules/workflows/backend/instances/[id]/page.js.map +1 -1
  187. package/dist/modules/workflows/components/EdgeEditDialog.js.map +1 -1
  188. package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js.map +1 -1
  189. package/dist/modules/workflows/components/NodeEditDialog.js.map +1 -1
  190. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +1 -1
  191. package/dist/modules/workflows/components/WorkflowGraph.js.map +1 -1
  192. package/dist/modules/workflows/components/WorkflowGraphImpl.js +17 -9
  193. package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
  194. package/dist/modules/workflows/components/mobile/MobileVisualEditor.js.map +1 -1
  195. package/dist/modules/workflows/frontend/checkout-demo/deriveCurrentStep.js +8 -0
  196. package/dist/modules/workflows/frontend/checkout-demo/deriveCurrentStep.js.map +7 -0
  197. package/dist/modules/workflows/frontend/checkout-demo/page.js +2 -20
  198. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  199. package/dist/modules/workflows/lib/graph-utils.js +8 -0
  200. package/dist/modules/workflows/lib/graph-utils.js.map +2 -2
  201. package/generated/entities/catalog_product/index.ts +26 -0
  202. package/generated/entities/catalog_product_variant/index.ts +2 -0
  203. package/generated/entity-fields-registry.ts +28 -0
  204. package/package.json +7 -7
  205. package/src/modules/catalog/api/products/route.ts +123 -39
  206. package/src/modules/catalog/api/variants/route.ts +4 -0
  207. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +43 -0
  208. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +14 -0
  209. package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +2 -0
  210. package/src/modules/catalog/backend/catalog/products/create/page.tsx +41 -0
  211. package/src/modules/catalog/commands/products.ts +307 -2
  212. package/src/modules/catalog/commands/variants.ts +90 -1
  213. package/src/modules/catalog/components/products/ProductComplianceSection.tsx +497 -0
  214. package/src/modules/catalog/components/products/VariantBuilder.tsx +43 -0
  215. package/src/modules/catalog/components/products/productForm.ts +262 -0
  216. package/src/modules/catalog/components/products/variantForm.ts +4 -0
  217. package/src/modules/catalog/data/entities.ts +97 -0
  218. package/src/modules/catalog/data/types.ts +36 -0
  219. package/src/modules/catalog/data/validators.ts +159 -3
  220. package/src/modules/catalog/i18n/de.json +64 -0
  221. package/src/modules/catalog/i18n/en.json +64 -0
  222. package/src/modules/catalog/i18n/es.json +64 -0
  223. package/src/modules/catalog/i18n/pl.json +64 -0
  224. package/src/modules/catalog/lib/gtin.ts +66 -0
  225. package/src/modules/catalog/migrations/.snapshot-open-mercato.json +457 -0
  226. package/src/modules/catalog/migrations/Migration20260611090000.ts +17 -0
  227. package/src/modules/catalog/translations.ts +1 -1
  228. package/src/modules/configs/api/cache/route.ts +72 -10
  229. package/src/modules/configs/components/CachePanel.tsx +59 -29
  230. package/src/modules/currencies/api/currencies/options/route.ts +22 -4
  231. package/src/modules/currencies/services/rateFetchingService.ts +63 -26
  232. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +18 -18
  233. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +1 -1
  234. package/src/modules/customer_accounts/i18n/de.json +1 -1
  235. package/src/modules/customer_accounts/i18n/en.json +1 -1
  236. package/src/modules/customer_accounts/i18n/es.json +1 -1
  237. package/src/modules/customer_accounts/i18n/pl.json +1 -1
  238. package/src/modules/customers/backend/calendar/page.meta.ts +23 -0
  239. package/src/modules/customers/backend/calendar/page.tsx +12 -0
  240. package/src/modules/customers/cli.ts +1 -0
  241. package/src/modules/customers/components/calendar/AgendaList.tsx +219 -0
  242. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +386 -0
  243. package/src/modules/customers/components/calendar/CalendarFooter.tsx +61 -0
  244. package/src/modules/customers/components/calendar/CalendarHeader.tsx +40 -0
  245. package/src/modules/customers/components/calendar/CalendarScreen.tsx +590 -0
  246. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +207 -0
  247. package/src/modules/customers/components/calendar/CalendarTabs.tsx +63 -0
  248. package/src/modules/customers/components/calendar/CalendarToolbar.tsx +295 -0
  249. package/src/modules/customers/components/calendar/EventBlock.tsx +205 -0
  250. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +100 -0
  251. package/src/modules/customers/components/calendar/MonthGrid.tsx +236 -0
  252. package/src/modules/customers/components/calendar/ShortcutsDialog.tsx +57 -0
  253. package/src/modules/customers/components/calendar/TimeGrid.tsx +510 -0
  254. package/src/modules/customers/components/calendar/UpcomingCards.tsx +220 -0
  255. package/src/modules/customers/components/calendar/editor/CategoryField.tsx +79 -0
  256. package/src/modules/customers/components/calendar/editor/LocationField.tsx +37 -0
  257. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +148 -0
  258. package/src/modules/customers/components/calendar/editor/RelatedToField.tsx +242 -0
  259. package/src/modules/customers/components/calendar/editor/RepeatField.tsx +132 -0
  260. package/src/modules/customers/components/calendar/editor/ScheduleSection.tsx +110 -0
  261. package/src/modules/customers/components/calendar/editor/SegmentGroup.tsx +50 -0
  262. package/src/modules/customers/components/calendar/editor/hooks.ts +162 -0
  263. package/src/modules/customers/components/calendar/editor/inputs.tsx +158 -0
  264. package/src/modules/customers/components/calendar/editor/lookups.ts +160 -0
  265. package/src/modules/customers/components/calendar/types.ts +163 -0
  266. package/src/modules/customers/components/calendar/useCalendarItems.ts +162 -0
  267. package/src/modules/customers/components/calendar/useCalendarPreferences.ts +52 -0
  268. package/src/modules/customers/i18n/de.json +195 -0
  269. package/src/modules/customers/i18n/en.json +195 -0
  270. package/src/modules/customers/i18n/es.json +195 -0
  271. package/src/modules/customers/i18n/pl.json +195 -0
  272. package/src/modules/customers/lib/calendar/categories.ts +26 -0
  273. package/src/modules/customers/lib/calendar/conflicts.ts +117 -0
  274. package/src/modules/customers/lib/calendar/editorPayload.ts +388 -0
  275. package/src/modules/customers/lib/calendar/grid.ts +50 -0
  276. package/src/modules/customers/lib/calendar/layout.ts +47 -0
  277. package/src/modules/customers/lib/calendar/mapItem.ts +94 -0
  278. package/src/modules/customers/lib/calendar/preferences.ts +95 -0
  279. package/src/modules/customers/lib/calendar/range.ts +45 -0
  280. package/src/modules/customers/lib/calendar/recurrence.ts +137 -0
  281. package/src/modules/dashboards/services/widgetDataService.ts +8 -6
  282. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +61 -1
  283. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +33 -1
  284. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +65 -1
  285. package/src/modules/dictionaries/api/route.ts +36 -1
  286. package/src/modules/feature_toggles/lib/queries.ts +41 -60
  287. package/src/modules/perspectives/api/[tableId]/[perspectiveId]/route.ts +34 -1
  288. package/src/modules/perspectives/api/[tableId]/roles/[roleId]/route.ts +34 -1
  289. package/src/modules/perspectives/api/[tableId]/route.ts +107 -32
  290. package/src/modules/perspectives/services/perspectiveService.ts +9 -5
  291. package/src/modules/planner/api/access.ts +9 -0
  292. package/src/modules/planner/api/availability-date-specific.ts +22 -1
  293. package/src/modules/planner/api/availability-weekly.ts +22 -1
  294. package/src/modules/resources/api/resources/tags/assign/route.ts +42 -0
  295. package/src/modules/resources/api/resources/tags/unassign/route.ts +42 -0
  296. package/src/modules/sales/api/settings/document-numbers/route.ts +35 -1
  297. package/src/modules/sales/api/settings/order-editing/route.ts +37 -3
  298. package/src/modules/staff/api/leave-requests/accept/route.ts +45 -0
  299. package/src/modules/staff/api/leave-requests/reject/route.ts +45 -0
  300. package/src/modules/staff/api/team-members/self/route.ts +43 -0
  301. package/src/modules/staff/api/team-members/tags/assign/route.ts +45 -0
  302. package/src/modules/staff/api/team-members/tags/unassign/route.ts +45 -0
  303. package/src/modules/translations/api/[entityType]/[entityId]/route.ts +65 -1
  304. package/src/modules/translations/api/context.ts +7 -0
  305. package/src/modules/translations/api/put/locales.ts +35 -1
  306. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +11 -9
  307. package/src/modules/workflows/backend/instances/[id]/page.tsx +1 -1
  308. package/src/modules/workflows/components/EdgeEditDialog.tsx +1 -1
  309. package/src/modules/workflows/components/EdgeEditDialogCrudForm.tsx +1 -1
  310. package/src/modules/workflows/components/NodeEditDialog.tsx +1 -1
  311. package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +1 -1
  312. package/src/modules/workflows/components/WorkflowGraph.tsx +2 -2
  313. package/src/modules/workflows/components/WorkflowGraphImpl.tsx +27 -13
  314. package/src/modules/workflows/components/mobile/MobileVisualEditor.tsx +3 -3
  315. package/src/modules/workflows/frontend/checkout-demo/deriveCurrentStep.ts +12 -0
  316. package/src/modules/workflows/frontend/checkout-demo/page.tsx +3 -23
  317. package/src/modules/workflows/lib/graph-utils.ts +21 -1
@@ -4,11 +4,13 @@ import * as React from 'react'
4
4
  import { Spinner } from '@open-mercato/ui/primitives/spinner'
5
5
  import { Button } from '@open-mercato/ui/primitives/button'
6
6
  import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
7
+ import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
7
8
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
8
9
  import { useT } from '@open-mercato/shared/lib/i18n/context'
9
10
  import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
10
11
 
11
12
  const API_PATH = '/api/configs/cache'
13
+ const CACHE_MUTATION_CONTEXT_ID = 'configs-cache-panel'
12
14
 
13
15
  type CrudCacheSegment = {
14
16
  segment: string
@@ -39,6 +41,23 @@ export function CachePanel() {
39
41
  const [purgingAll, setPurgingAll] = React.useState(false)
40
42
  const [segmentPurges, setSegmentPurges] = React.useState<Record<string, boolean>>({})
41
43
 
44
+ const { runMutation, retryLastMutation } = useGuardedMutation<{
45
+ formId: string
46
+ resourceKind: string
47
+ retryLastMutation: () => Promise<boolean>
48
+ }>({
49
+ contextId: CACHE_MUTATION_CONTEXT_ID,
50
+ blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),
51
+ })
52
+ const cacheMutationContext = React.useMemo(
53
+ () => ({
54
+ formId: CACHE_MUTATION_CONTEXT_ID,
55
+ resourceKind: 'configs.cache',
56
+ retryLastMutation,
57
+ }),
58
+ [retryLastMutation],
59
+ )
60
+
42
61
  const loadStats = React.useCallback(async () => {
43
62
  setState((current) => ({ ...current, loading: true, error: null }))
44
63
  try {
@@ -106,18 +125,23 @@ export function CachePanel() {
106
125
  if (!confirmed) return
107
126
  setPurgingAll(true)
108
127
  try {
109
- const payload = await readApiResultOrThrow<{ stats?: CrudCacheStats }>(
110
- API_PATH,
111
- {
112
- method: 'POST',
113
- headers: { 'content-type': 'application/json' },
114
- body: JSON.stringify({ action: 'purgeAll' }),
115
- },
116
- {
117
- errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),
118
- allowNullResult: true,
119
- },
120
- )
128
+ const payload = await runMutation({
129
+ operation: () =>
130
+ readApiResultOrThrow<{ stats?: CrudCacheStats }>(
131
+ API_PATH,
132
+ {
133
+ method: 'POST',
134
+ headers: { 'content-type': 'application/json' },
135
+ body: JSON.stringify({ action: 'purgeAll' }),
136
+ },
137
+ {
138
+ errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),
139
+ allowNullResult: true,
140
+ },
141
+ ),
142
+ context: cacheMutationContext,
143
+ mutationPayload: { action: 'purgeAll' },
144
+ })
121
145
  const stats = payload?.stats
122
146
  if (stats) {
123
147
  setState({ loading: false, error: null, stats })
@@ -135,7 +159,7 @@ export function CachePanel() {
135
159
  } finally {
136
160
  setPurgingAll(false)
137
161
  }
138
- }, [canManage, confirm, purgingAll, t, handleRefresh]);
162
+ }, [canManage, confirm, purgingAll, t, handleRefresh, runMutation, cacheMutationContext]);
139
163
 
140
164
 
141
165
  const handlePurgeSegment = React.useCallback(async (segment: string) => {
@@ -147,18 +171,23 @@ export function CachePanel() {
147
171
  if (!confirmed) return
148
172
  setSegmentPurges((prev) => ({ ...prev, [segment]: true }))
149
173
  try {
150
- const payload = await readApiResultOrThrow<{ stats?: CrudCacheStats; deleted?: number }>(
151
- API_PATH,
152
- {
153
- method: 'POST',
154
- headers: { 'content-type': 'application/json' },
155
- body: JSON.stringify({ action: 'purgeSegment', segment }),
156
- },
157
- {
158
- errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),
159
- allowNullResult: true,
160
- },
161
- )
174
+ const payload = await runMutation({
175
+ operation: () =>
176
+ readApiResultOrThrow<{ stats?: CrudCacheStats; deleted?: number }>(
177
+ API_PATH,
178
+ {
179
+ method: 'POST',
180
+ headers: { 'content-type': 'application/json' },
181
+ body: JSON.stringify({ action: 'purgeSegment', segment }),
182
+ },
183
+ {
184
+ errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),
185
+ allowNullResult: true,
186
+ },
187
+ ),
188
+ context: cacheMutationContext,
189
+ mutationPayload: { action: 'purgeSegment', segment },
190
+ })
162
191
  const stats = payload?.stats
163
192
  if (stats) {
164
193
  setState({ loading: false, error: null, stats })
@@ -186,7 +215,7 @@ export function CachePanel() {
186
215
  return next
187
216
  })
188
217
  }
189
- }, [canManage, confirm, segmentPurges, t, handleRefresh]);
218
+ }, [canManage, confirm, segmentPurges, t, handleRefresh, runMutation, cacheMutationContext]);
190
219
 
191
220
  if (state.loading) {
192
221
  return (
@@ -220,7 +249,7 @@ export function CachePanel() {
220
249
  {state.error}
221
250
  </div>
222
251
  <div className="flex flex-wrap gap-2">
223
- <Button variant="outline" onClick={handleRefresh}>
252
+ <Button variant="outline" type="button" onClick={handleRefresh}>
224
253
  {t('configs.cache.retry', 'Retry')}
225
254
  </Button>
226
255
  </div>
@@ -259,11 +288,11 @@ export function CachePanel() {
259
288
  ) : null}
260
289
  </div>
261
290
  <div className="flex items-center gap-2">
262
- <Button variant="outline" onClick={handleRefresh}>
291
+ <Button variant="outline" type="button" onClick={handleRefresh}>
263
292
  {t('configs.cache.refresh', 'Refresh')}
264
293
  </Button>
265
294
  {canShowActions ? (
266
- <Button variant="destructive" disabled={purgingAll} onClick={() => { void handlePurgeAll() }}>
295
+ <Button variant="destructive" type="button" disabled={purgingAll} onClick={() => { void handlePurgeAll() }}>
267
296
  {purgingAll
268
297
  ? t('configs.cache.purgeAllLoading', 'Purging…')
269
298
  : t('configs.cache.purgeAll', 'Purge all cache')}
@@ -327,6 +356,7 @@ export function CachePanel() {
327
356
  <Button
328
357
  variant="outline"
329
358
  size="sm"
359
+ type="button"
330
360
  disabled={isPurging}
331
361
  onClick={() => { void handlePurgeSegment(segment.segment) }}
332
362
  >
@@ -7,6 +7,7 @@ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
7
7
  import { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'
8
8
  import {
9
9
  buildCollectionTags,
10
+ debugCrudCache,
10
11
  isCrudCacheEnabled,
11
12
  resolveCrudCache,
12
13
  } from '@open-mercato/shared/lib/crud/cache'
@@ -78,9 +79,18 @@ export async function GET(req: Request) {
78
79
  : null
79
80
 
80
81
  if (cache && cacheKey) {
81
- const cached = await runWithCacheTenant(tenantId, () => cache.get(cacheKey))
82
- if (cached) {
83
- return NextResponse.json(cached)
82
+ try {
83
+ const cached = await runWithCacheTenant(tenantId, () => cache.get(cacheKey))
84
+ if (cached) {
85
+ return NextResponse.json(cached)
86
+ }
87
+ } catch (err) {
88
+ // A cache-backend read error must degrade to a fresh DB read, never a 500.
89
+ debugCrudCache('get', {
90
+ resource: CURRENCY_OPTIONS_RESOURCE,
91
+ key: cacheKey,
92
+ error: err instanceof Error ? err.message : String(err),
93
+ })
84
94
  }
85
95
  }
86
96
 
@@ -124,7 +134,15 @@ export async function GET(req: Request) {
124
134
  tags: buildCollectionTags(CURRENCY_OPTIONS_RESOURCE, tenantId, [orgId]),
125
135
  }),
126
136
  )
127
- } catch {}
137
+ } catch (err) {
138
+ // A cache write must never break the request; log it for observability
139
+ // instead of swallowing the failure silently (matches the CRUD factory).
140
+ debugCrudCache('store', {
141
+ resource: CURRENCY_OPTIONS_RESOURCE,
142
+ key: cacheKey,
143
+ error: err instanceof Error ? err.message : String(err),
144
+ })
145
+ }
128
146
  }
129
147
 
130
148
  return NextResponse.json(payload)
@@ -13,6 +13,11 @@ export interface FetchOptions {
13
13
  forceUpdate?: boolean
14
14
  }
15
15
 
16
+ type ProviderFetchOutcome =
17
+ | { kind: 'skipped'; providerSource: string; error: string }
18
+ | { kind: 'failed'; providerSource: string; error: string }
19
+ | { kind: 'fetched'; providerSource: string; rates: RateProviderResult[] }
20
+
16
21
  const exchangeRateKey = (
17
22
  fromCurrencyCode: string,
18
23
  toCurrencyCode: string,
@@ -54,46 +59,78 @@ export class RateFetchingService {
54
59
  ? options.providers
55
60
  : Array.from(this.providers.keys())
56
61
 
57
- for (const providerSource of providerList) {
58
- const provider = this.providers.get(providerSource)
59
-
60
- if (!provider) {
61
- result.errors.push(`Unknown provider: ${providerSource}`)
62
+ // Fetch every provider concurrently: provider calls are independent network I/O,
63
+ // so overlapping them caps total latency at the slowest provider instead of the sum
64
+ // of all provider timeouts. Each provider is isolated in its own try/catch so a
65
+ // single failure never rejects the batch.
66
+ const outcomes = await Promise.all(
67
+ providerList.map((providerSource) =>
68
+ this.fetchFromProvider(providerSource, date, scope, currencyCodeSet)
69
+ )
70
+ )
71
+
72
+ // Persist sequentially in provider order: a single EntityManager is not safe for
73
+ // concurrent transactions, and stable ordering keeps DB writes and the byProvider
74
+ // response shape deterministic regardless of which fetch resolved first.
75
+ for (const outcome of outcomes) {
76
+ if (outcome.kind === 'skipped') {
77
+ result.errors.push(outcome.error)
62
78
  continue
63
79
  }
64
80
 
65
- if (!provider.isAvailable()) {
66
- result.errors.push(`Provider not available: ${providerSource}`)
81
+ if (outcome.kind === 'failed') {
82
+ result.errors.push(`${outcome.providerSource}: ${outcome.error}`)
83
+ result.byProvider[outcome.providerSource] = { count: 0, errors: [outcome.error] }
67
84
  continue
68
85
  }
69
86
 
70
87
  try {
71
- const rates = await provider.fetchRates(date, scope, currencyCodeSet)
72
-
73
- // Filter: only currencies that exist in both directions
74
- const validRates = rates.filter(
75
- (r) =>
76
- currencyCodeSet.has(r.fromCurrencyCode) &&
77
- currencyCodeSet.has(r.toCurrencyCode)
78
- )
79
-
80
- const stored = await this.storeRates(validRates, scope)
81
-
82
- result.byProvider[providerSource] = { count: stored }
88
+ const stored = await this.storeRates(outcome.rates, scope)
89
+ result.byProvider[outcome.providerSource] = { count: stored }
83
90
  result.totalFetched += stored
84
- } catch (err: any) {
85
- const errorMsg = `${providerSource}: ${err.message}`
86
- result.errors.push(errorMsg)
87
- result.byProvider[providerSource] = {
88
- count: 0,
89
- errors: [err.message],
90
- }
91
+ } catch (err) {
92
+ const message = err instanceof Error ? err.message : String(err)
93
+ result.errors.push(`${outcome.providerSource}: ${message}`)
94
+ result.byProvider[outcome.providerSource] = { count: 0, errors: [message] }
91
95
  }
92
96
  }
93
97
 
94
98
  return result
95
99
  }
96
100
 
101
+ private async fetchFromProvider(
102
+ providerSource: string,
103
+ date: Date,
104
+ scope: { tenantId: string; organizationId: string },
105
+ currencyCodeSet: Set<string>
106
+ ): Promise<ProviderFetchOutcome> {
107
+ const provider = this.providers.get(providerSource)
108
+
109
+ if (!provider) {
110
+ return { kind: 'skipped', providerSource, error: `Unknown provider: ${providerSource}` }
111
+ }
112
+
113
+ if (!provider.isAvailable()) {
114
+ return { kind: 'skipped', providerSource, error: `Provider not available: ${providerSource}` }
115
+ }
116
+
117
+ try {
118
+ const rates = await provider.fetchRates(date, scope, currencyCodeSet)
119
+
120
+ // Filter: only currencies that exist in both directions
121
+ const validRates = rates.filter(
122
+ (r) =>
123
+ currencyCodeSet.has(r.fromCurrencyCode) &&
124
+ currencyCodeSet.has(r.toCurrencyCode)
125
+ )
126
+
127
+ return { kind: 'fetched', providerSource, rates: validRates }
128
+ } catch (err) {
129
+ const message = err instanceof Error ? err.message : String(err)
130
+ return { kind: 'failed', providerSource, error: message }
131
+ }
132
+ }
133
+
97
134
  private async getExistingCurrencies(scope: {
98
135
  tenantId: string
99
136
  organizationId: string
@@ -251,25 +251,25 @@ export default function CustomerUserDetailPage({ params }: { params?: { id?: str
251
251
  React.useEffect(() => {
252
252
  if (!data) return
253
253
  let cancelled = false
254
- async function loadCrmNames() {
255
- if (data!.personEntityId) {
256
- try {
257
- const call = await apiCall<{ id?: string; firstName?: string; lastName?: string }>(`/api/customers/people/${encodeURIComponent(data!.personEntityId)}`)
258
- if (!cancelled && call.ok && call.result) {
259
- setPersonName([call.result.firstName, call.result.lastName].filter(Boolean).join(' ') || call.result.id || null)
260
- }
261
- } catch { /* ignore */ }
262
- }
263
- if (data!.customerEntityId) {
264
- try {
265
- const call = await apiCall<{ id?: string; name?: string }>(`/api/customers/${encodeURIComponent(data!.customerEntityId)}`)
266
- if (!cancelled && call.ok && call.result) {
267
- setCompanyName(call.result.name || call.result.id || null)
268
- }
269
- } catch { /* ignore */ }
270
- }
254
+ async function loadPersonName() {
255
+ if (!data!.personEntityId) return
256
+ try {
257
+ const call = await apiCall<{ id?: string; firstName?: string; lastName?: string }>(`/api/customers/people/${encodeURIComponent(data!.personEntityId)}`)
258
+ if (!cancelled && call.ok && call.result) {
259
+ setPersonName([call.result.firstName, call.result.lastName].filter(Boolean).join(' ') || call.result.id || null)
260
+ }
261
+ } catch { /* ignore */ }
262
+ }
263
+ async function loadCompanyName() {
264
+ if (!data!.customerEntityId) return
265
+ try {
266
+ const call = await apiCall<{ id?: string; name?: string }>(`/api/customers/${encodeURIComponent(data!.customerEntityId)}`)
267
+ if (!cancelled && call.ok && call.result) {
268
+ setCompanyName(call.result.name || call.result.id || null)
269
+ }
270
+ } catch { /* ignore */ }
271
271
  }
272
- loadCrmNames()
272
+ void Promise.all([loadPersonName(), loadCompanyName()])
273
273
  return () => { cancelled = true }
274
274
  }, [data])
275
275
 
@@ -500,7 +500,7 @@ export default function CustomerAccountsPage() {
500
500
  })}
501
501
  </p>
502
502
  <p className="mt-0.5 text-xs text-status-info-text">
503
- {t('customer_accounts.admin.portalInfo.credentials', 'Demo credentials: alice.johnson@example.com / password123')}
503
+ {t('customer_accounts.admin.portalInfo.credentials', 'Demo credentials: alice.johnson@example.com / Password123!')}
504
504
  </p>
505
505
  </div>
506
506
  <div className="flex shrink-0 flex-col gap-2">
@@ -121,7 +121,7 @@
121
121
  "customer_accounts.admin.portalFeatures.users.invite": "Invite team members",
122
122
  "customer_accounts.admin.portalFeatures.users.manage": "Manage team members",
123
123
  "customer_accounts.admin.portalFeatures.users.view": "View team members",
124
- "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / password123",
124
+ "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / Password123!",
125
125
  "customer_accounts.admin.portalInfo.description": "Manage customer portal accounts. Customers can self-register, log in, and access orders, quotes, and invoices through the portal.",
126
126
  "customer_accounts.admin.portalInfo.open": "Open Portal",
127
127
  "customer_accounts.admin.portalInfo.openConfiguration": "Open Configuration",
@@ -121,7 +121,7 @@
121
121
  "customer_accounts.admin.portalFeatures.users.invite": "Invite team members",
122
122
  "customer_accounts.admin.portalFeatures.users.manage": "Manage team members",
123
123
  "customer_accounts.admin.portalFeatures.users.view": "View team members",
124
- "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / password123",
124
+ "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / Password123!",
125
125
  "customer_accounts.admin.portalInfo.description": "Manage customer portal accounts. Customers can self-register, log in, and access orders, quotes, and invoices through the portal.",
126
126
  "customer_accounts.admin.portalInfo.open": "Open Portal",
127
127
  "customer_accounts.admin.portalInfo.openConfiguration": "Open Configuration",
@@ -121,7 +121,7 @@
121
121
  "customer_accounts.admin.portalFeatures.users.invite": "Invite team members",
122
122
  "customer_accounts.admin.portalFeatures.users.manage": "Manage team members",
123
123
  "customer_accounts.admin.portalFeatures.users.view": "View team members",
124
- "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / password123",
124
+ "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / Password123!",
125
125
  "customer_accounts.admin.portalInfo.description": "Manage customer portal accounts. Customers can self-register, log in, and access orders, quotes, and invoices through the portal.",
126
126
  "customer_accounts.admin.portalInfo.open": "Open Portal",
127
127
  "customer_accounts.admin.portalInfo.openConfiguration": "Open Configuration",
@@ -121,7 +121,7 @@
121
121
  "customer_accounts.admin.portalFeatures.users.invite": "Invite team members",
122
122
  "customer_accounts.admin.portalFeatures.users.manage": "Manage team members",
123
123
  "customer_accounts.admin.portalFeatures.users.view": "View team members",
124
- "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / password123",
124
+ "customer_accounts.admin.portalInfo.credentials": "Demo credentials: alice.johnson@example.com / Password123!",
125
125
  "customer_accounts.admin.portalInfo.description": "Manage customer portal accounts. Customers can self-register, log in, and access orders, quotes, and invoices through the portal.",
126
126
  "customer_accounts.admin.portalInfo.open": "Open Portal",
127
127
  "customer_accounts.admin.portalInfo.openConfiguration": "Open Configuration",
@@ -0,0 +1,23 @@
1
+ import React from 'react'
2
+
3
+ const calendarIcon = React.createElement(
4
+ 'svg',
5
+ { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2 },
6
+ React.createElement('rect', { x: 3, y: 4, width: 18, height: 18, rx: 2 }),
7
+ React.createElement('path', { d: 'M16 2v4' }),
8
+ React.createElement('path', { d: 'M8 2v4' }),
9
+ React.createElement('path', { d: 'M3 10h18' }),
10
+ )
11
+
12
+ export const metadata = {
13
+ requireAuth: true,
14
+ requireFeatures: ['customers.interactions.view'],
15
+ pageTitle: 'Calendar',
16
+ pageTitleKey: 'customers.calendar.nav.title',
17
+ pageGroup: 'Customers',
18
+ pageGroupKey: 'customers.nav.group',
19
+ pagePriority: 10,
20
+ pageOrder: 50,
21
+ icon: calendarIcon,
22
+ breadcrumb: [{ label: 'Calendar', labelKey: 'customers.calendar.nav.title' }],
23
+ }
@@ -0,0 +1,12 @@
1
+ import { Page, PageBody } from '@open-mercato/ui/backend/Page'
2
+ import { CalendarScreen } from '../../components/calendar/CalendarScreen'
3
+
4
+ export default function CustomersCalendarPage() {
5
+ return (
6
+ <Page>
7
+ <PageBody>
8
+ <CalendarScreen />
9
+ </PageBody>
10
+ </Page>
11
+ )
12
+ }
@@ -113,6 +113,7 @@ const ADDRESS_TYPE_DEFAULTS: DictionaryDefault[] = [
113
113
  const ACTIVITY_TYPE_DEFAULTS: DictionaryDefault[] = [
114
114
  { value: 'call', label: 'Call', color: '#2563eb', icon: 'lucide:phone-call' },
115
115
  { value: 'email', label: 'Email', color: '#16a34a', icon: 'lucide:mail' },
116
+ { value: 'event', label: 'Event', color: '#6366f1', icon: 'lucide:calendar' },
116
117
  { value: 'meeting', label: 'Meeting', color: '#f59e0b', icon: 'lucide:users' },
117
118
  { value: 'note', label: 'Note', color: '#a855f7', icon: 'lucide:notebook' },
118
119
  { value: 'task', label: 'Task', color: '#ef4444', icon: 'lucide:check-square' },