@open-mercato/core 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4559.1.839e136509

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 (644) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +5 -0
  3. package/dist/generated/entities/role/index.js +3 -1
  4. package/dist/generated/entities/role/index.js.map +2 -2
  5. package/dist/generated/entities/user/index.js +3 -1
  6. package/dist/generated/entities/user/index.js.map +2 -2
  7. package/dist/generated/entity-fields-registry.js +2 -0
  8. package/dist/generated/entity-fields-registry.js.map +2 -2
  9. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  10. package/dist/helpers/integration/dbFixtures.js +2 -1
  11. package/dist/helpers/integration/dbFixtures.js.map +2 -2
  12. package/dist/helpers/integration/optimisticLockUi.js +104 -0
  13. package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
  14. package/dist/helpers/integration/salesFixtures.js +17 -0
  15. package/dist/helpers/integration/salesFixtures.js.map +2 -2
  16. package/dist/modules/api_keys/backend/api-keys/page.js +9 -5
  17. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  18. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
  19. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  20. package/dist/modules/auth/api/roles/acl/route.js +32 -13
  21. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  22. package/dist/modules/auth/api/roles/route.js +3 -1
  23. package/dist/modules/auth/api/roles/route.js.map +2 -2
  24. package/dist/modules/auth/api/sidebar/preferences/route.js +71 -3
  25. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  26. package/dist/modules/auth/api/users/acl/route.js +42 -19
  27. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  28. package/dist/modules/auth/api/users/route.js +3 -1
  29. package/dist/modules/auth/api/users/route.js.map +2 -2
  30. package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
  31. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  32. package/dist/modules/auth/backend/roles/page.js +8 -4
  33. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  34. package/dist/modules/auth/backend/users/[id]/edit/page.js +27 -5
  35. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  36. package/dist/modules/auth/backend/users/page.js +6 -2
  37. package/dist/modules/auth/backend/users/page.js.map +2 -2
  38. package/dist/modules/auth/components/AclEditor.js +3 -1
  39. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  40. package/dist/modules/auth/data/entities.js +6 -0
  41. package/dist/modules/auth/data/entities.js.map +2 -2
  42. package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
  43. package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
  44. package/dist/modules/business_rules/api/rules/route.js +28 -0
  45. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  46. package/dist/modules/business_rules/api/sets/route.js +28 -0
  47. package/dist/modules/business_rules/api/sets/route.js.map +2 -2
  48. package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
  49. package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
  50. package/dist/modules/business_rules/backend/rules/page.js +20 -11
  51. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  52. package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
  53. package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
  54. package/dist/modules/business_rules/backend/sets/page.js +20 -11
  55. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  56. package/dist/modules/catalog/api/categories/route.js +2 -0
  57. package/dist/modules/catalog/api/categories/route.js.map +2 -2
  58. package/dist/modules/catalog/api/products/route.js +2 -1
  59. package/dist/modules/catalog/api/products/route.js.map +2 -2
  60. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
  61. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
  62. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +94 -40
  63. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  64. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +37 -8
  65. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  66. package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
  67. package/dist/modules/catalog/commands/variants.js +32 -31
  68. package/dist/modules/catalog/commands/variants.js.map +2 -2
  69. package/dist/modules/catalog/components/PriceKindSettings.js +12 -5
  70. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  71. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  72. package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
  73. package/dist/modules/catalog/components/products/ProductsDataTable.js +5 -3
  74. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  75. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  76. package/dist/modules/catalog/components/products/variantForm.js +2 -1
  77. package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
  78. package/dist/modules/communication_channels/api/post/test-seed/route.js +23 -2
  79. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  80. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +5 -0
  81. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
  82. package/dist/modules/communication_channels/commands/set-primary-channel.js +2 -1
  83. package/dist/modules/communication_channels/commands/set-primary-channel.js.map +2 -2
  84. package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
  85. package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
  86. package/dist/modules/currencies/backend/currencies/page.js +18 -11
  87. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  88. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
  89. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
  90. package/dist/modules/currencies/backend/exchange-rates/page.js +10 -6
  91. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  92. package/dist/modules/currencies/commands/currencies.js +7 -5
  93. package/dist/modules/currencies/commands/currencies.js.map +2 -2
  94. package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
  95. package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
  96. package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
  97. package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
  98. package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
  99. package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
  100. package/dist/modules/customer_accounts/api/admin/users/[id].js +28 -5
  101. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
  102. package/dist/modules/customer_accounts/api/admin/users.js +2 -0
  103. package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
  104. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
  105. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
  106. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +8 -4
  107. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  108. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
  109. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
  110. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
  111. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  112. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +18 -11
  113. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  114. package/dist/modules/customers/api/companies/route.js +13 -2
  115. package/dist/modules/customers/api/companies/route.js.map +2 -2
  116. package/dist/modules/customers/api/deals/route.js +2 -0
  117. package/dist/modules/customers/api/deals/route.js.map +2 -2
  118. package/dist/modules/customers/api/people/route.js +11 -2
  119. package/dist/modules/customers/api/people/route.js.map +2 -2
  120. package/dist/modules/customers/api/todos/route.js +1 -0
  121. package/dist/modules/customers/api/todos/route.js.map +2 -2
  122. package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
  123. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
  124. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  125. package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
  126. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  127. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  128. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
  129. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  130. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
  131. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
  132. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
  133. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  134. package/dist/modules/customers/backend/customers/deals/page.js +16 -6
  135. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  136. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
  137. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  138. package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
  139. package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
  140. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  141. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +50 -23
  142. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  143. package/dist/modules/customers/commands/addresses.js +16 -14
  144. package/dist/modules/customers/commands/addresses.js.map +2 -2
  145. package/dist/modules/customers/commands/companies.js +1 -1
  146. package/dist/modules/customers/commands/companies.js.map +2 -2
  147. package/dist/modules/customers/commands/interactions.js +41 -4
  148. package/dist/modules/customers/commands/interactions.js.map +2 -2
  149. package/dist/modules/customers/commands/people.js +1 -1
  150. package/dist/modules/customers/commands/people.js.map +2 -2
  151. package/dist/modules/customers/commands/personCompanyLinks.js +8 -5
  152. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  153. package/dist/modules/customers/commands/pipeline-stages.js +13 -11
  154. package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
  155. package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
  156. package/dist/modules/customers/components/DictionarySettings.js +20 -13
  157. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  158. package/dist/modules/customers/components/DictionarySortSettings.js +4 -0
  159. package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
  160. package/dist/modules/customers/components/PipelineSettings.js +38 -23
  161. package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
  162. package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
  163. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
  164. package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
  165. package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
  166. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
  167. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  168. package/dist/modules/customers/components/detail/DealsSection.js +36 -24
  169. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  170. package/dist/modules/customers/components/detail/EmailCardActions.js +5 -0
  171. package/dist/modules/customers/components/detail/EmailCardActions.js.map +2 -2
  172. package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
  173. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  174. package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
  175. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
  176. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
  177. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  178. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
  179. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
  180. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
  181. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  182. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
  183. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
  184. package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
  185. package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
  186. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
  187. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  188. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  189. package/dist/modules/customers/components/formConfig.js.map +2 -2
  190. package/dist/modules/customers/data/guards.js +66 -0
  191. package/dist/modules/customers/data/guards.js.map +7 -0
  192. package/dist/modules/customers/di.js +37 -0
  193. package/dist/modules/customers/di.js.map +2 -2
  194. package/dist/modules/customers/lib/todoCompatibility.js +11 -0
  195. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  196. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  197. package/dist/modules/data_sync/api/options.js +4 -4
  198. package/dist/modules/data_sync/api/options.js.map +2 -2
  199. package/dist/modules/data_sync/api/schedules/route.js +9 -1
  200. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  201. package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
  202. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  203. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
  204. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  205. package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
  206. package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
  207. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
  208. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  209. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +17 -1
  210. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  211. package/dist/modules/dictionaries/components/DictionariesManager.js +31 -10
  212. package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
  213. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +28 -15
  214. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  215. package/dist/modules/directory/api/organizations/route.js +3 -0
  216. package/dist/modules/directory/api/organizations/route.js.map +2 -2
  217. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
  218. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
  219. package/dist/modules/directory/backend/directory/organizations/page.js +9 -5
  220. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  221. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
  222. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
  223. package/dist/modules/directory/backend/directory/tenants/page.js +8 -4
  224. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  225. package/dist/modules/directory/commands/organizations.js +7 -2
  226. package/dist/modules/directory/commands/organizations.js.map +2 -2
  227. package/dist/modules/entities/api/records.js +66 -0
  228. package/dist/modules/entities/api/records.js.map +2 -2
  229. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
  230. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  231. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +8 -4
  232. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  233. package/dist/modules/entities/lib/helpers.js +17 -0
  234. package/dist/modules/entities/lib/helpers.js.map +2 -2
  235. package/dist/modules/feature_toggles/api/global/[id]/override/route.js +2 -1
  236. package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
  237. package/dist/modules/feature_toggles/api/overrides/route.js +15 -0
  238. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  239. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +15 -14
  240. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
  241. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
  242. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
  243. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +6 -2
  244. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  245. package/dist/modules/feature_toggles/components/formConfig.js +2 -1
  246. package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
  247. package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
  248. package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
  249. package/dist/modules/feature_toggles/data/validators.js +7 -4
  250. package/dist/modules/feature_toggles/data/validators.js.map +2 -2
  251. package/dist/modules/inbox_ops/api/settings/route.js +17 -2
  252. package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
  253. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
  254. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
  255. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
  256. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  257. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
  258. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  259. package/dist/modules/integrations/backend/integrations/page.js +12 -8
  260. package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
  261. package/dist/modules/messages/commands/messages.js +13 -10
  262. package/dist/modules/messages/commands/messages.js.map +2 -2
  263. package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
  264. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  265. package/dist/modules/perspectives/services/perspectiveService.js +7 -0
  266. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  267. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
  268. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
  269. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
  270. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  271. package/dist/modules/planner/components/AvailabilityRuleSetForm.js +2 -0
  272. package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
  273. package/dist/modules/planner/components/AvailabilityRulesEditor.js +36 -11
  274. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  275. package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
  276. package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
  277. package/dist/modules/query_index/lib/engine.js +19 -0
  278. package/dist/modules/query_index/lib/engine.js.map +2 -2
  279. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -0
  280. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
  281. package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
  282. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  283. package/dist/modules/resources/backend/resources/resources/[id]/page.js +14 -3
  284. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  285. package/dist/modules/resources/backend/resources/resources/page.js +8 -4
  286. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  287. package/dist/modules/resources/components/ResourceCrudForm.js +2 -0
  288. package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
  289. package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -0
  290. package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
  291. package/dist/modules/sales/api/documents/factory.js +7 -2
  292. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  293. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
  294. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
  295. package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
  296. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  297. package/dist/modules/sales/backend/sales/channels/page.js +16 -4
  298. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  299. package/dist/modules/sales/backend/sales/documents/[id]/page.js +68 -22
  300. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  301. package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
  302. package/dist/modules/sales/commands/documentAddresses.js +181 -2
  303. package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
  304. package/dist/modules/sales/commands/documents.js +29 -1
  305. package/dist/modules/sales/commands/documents.js.map +2 -2
  306. package/dist/modules/sales/commands/returns.js +12 -2
  307. package/dist/modules/sales/commands/returns.js.map +2 -2
  308. package/dist/modules/sales/commands/shared.js +15 -0
  309. package/dist/modules/sales/commands/shared.js.map +2 -2
  310. package/dist/modules/sales/commands/shipments.js +4 -1
  311. package/dist/modules/sales/commands/shipments.js.map +2 -2
  312. package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
  313. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  314. package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
  315. package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
  316. package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
  317. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  318. package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
  319. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  320. package/dist/modules/sales/components/StatusSettings.js +18 -11
  321. package/dist/modules/sales/components/StatusSettings.js.map +2 -2
  322. package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
  323. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  324. package/dist/modules/sales/components/channels/ChannelOfferForm.js +47 -16
  325. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  326. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +8 -4
  327. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  328. package/dist/modules/sales/components/documents/AddressesSection.js +44 -25
  329. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  330. package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
  331. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  332. package/dist/modules/sales/components/documents/ItemsSection.js +22 -13
  333. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  334. package/dist/modules/sales/components/documents/LineItemDialog.js +23 -10
  335. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  336. package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
  337. package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
  338. package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
  339. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  340. package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
  341. package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
  342. package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
  343. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  344. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +10 -5
  345. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  346. package/dist/modules/sales/components/documents/ShipmentDialog.js +21 -7
  347. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  348. package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
  349. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  350. package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
  351. package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
  352. package/dist/modules/sales/di.js +18 -0
  353. package/dist/modules/sales/di.js.map +2 -2
  354. package/dist/modules/staff/api/job-histories.js +11 -2
  355. package/dist/modules/staff/api/job-histories.js.map +2 -2
  356. package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
  357. package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
  358. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
  359. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
  360. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
  361. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
  362. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
  363. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  364. package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
  365. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  366. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +1 -0
  367. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
  368. package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
  369. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  370. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
  371. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  372. package/dist/modules/staff/backend/staff/teams/page.js +12 -3
  373. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  374. package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
  375. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  376. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
  377. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
  378. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  379. package/dist/modules/staff/commands/job-histories.js +40 -3
  380. package/dist/modules/staff/commands/job-histories.js.map +2 -2
  381. package/dist/modules/staff/components/LeaveRequestForm.js +1 -0
  382. package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
  383. package/dist/modules/staff/components/TeamForm.js +1 -0
  384. package/dist/modules/staff/components/TeamForm.js.map +2 -2
  385. package/dist/modules/staff/components/TeamMemberForm.js +1 -0
  386. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  387. package/dist/modules/staff/components/TeamRoleForm.js +1 -0
  388. package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
  389. package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
  390. package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
  391. package/dist/modules/staff/data/validators.js +7 -1
  392. package/dist/modules/staff/data/validators.js.map +2 -2
  393. package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
  394. package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
  395. package/dist/modules/translations/components/TranslationManager.js +12 -8
  396. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  397. package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
  398. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  399. package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
  400. package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
  401. package/dist/modules/workflows/backend/definitions/page.js +19 -8
  402. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  403. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
  404. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  405. package/dist/modules/workflows/components/formConfig.js +4 -1
  406. package/dist/modules/workflows/components/formConfig.js.map +2 -2
  407. package/dist/modules/workflows/di.js +12 -0
  408. package/dist/modules/workflows/di.js.map +2 -2
  409. package/generated/entities/role/index.ts +1 -0
  410. package/generated/entities/user/index.ts +1 -0
  411. package/generated/entity-fields-registry.ts +2 -0
  412. package/jest.setup.ts +17 -0
  413. package/package.json +8 -7
  414. package/src/helpers/integration/communicationChannelsFixtures.ts +6 -0
  415. package/src/helpers/integration/dbFixtures.ts +1 -1
  416. package/src/helpers/integration/optimisticLockUi.ts +172 -0
  417. package/src/helpers/integration/salesFixtures.ts +29 -0
  418. package/src/modules/api_keys/backend/api-keys/page.tsx +10 -5
  419. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
  420. package/src/modules/auth/api/roles/acl/route.ts +37 -11
  421. package/src/modules/auth/api/roles/route.ts +2 -0
  422. package/src/modules/auth/api/sidebar/preferences/route.ts +73 -0
  423. package/src/modules/auth/api/users/acl/route.ts +46 -18
  424. package/src/modules/auth/api/users/route.ts +2 -0
  425. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
  426. package/src/modules/auth/backend/roles/page.tsx +9 -4
  427. package/src/modules/auth/backend/users/[id]/edit/page.tsx +37 -4
  428. package/src/modules/auth/backend/users/page.tsx +7 -2
  429. package/src/modules/auth/components/AclEditor.tsx +10 -1
  430. package/src/modules/auth/data/entities.ts +7 -1
  431. package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
  432. package/src/modules/business_rules/api/rules/route.ts +30 -0
  433. package/src/modules/business_rules/api/sets/route.ts +30 -0
  434. package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
  435. package/src/modules/business_rules/backend/rules/page.tsx +20 -11
  436. package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
  437. package/src/modules/business_rules/backend/sets/page.tsx +20 -11
  438. package/src/modules/catalog/api/categories/route.ts +3 -0
  439. package/src/modules/catalog/api/products/route.ts +4 -0
  440. package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
  441. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +112 -35
  442. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +56 -7
  443. package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
  444. package/src/modules/catalog/commands/variants.ts +32 -32
  445. package/src/modules/catalog/components/PriceKindSettings.tsx +20 -7
  446. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +1 -0
  447. package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
  448. package/src/modules/catalog/components/products/ProductsDataTable.tsx +8 -4
  449. package/src/modules/catalog/components/products/productForm.ts +3 -0
  450. package/src/modules/catalog/components/products/variantForm.ts +9 -0
  451. package/src/modules/communication_channels/api/post/test-seed/route.ts +28 -1
  452. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +5 -0
  453. package/src/modules/communication_channels/commands/set-primary-channel.ts +10 -7
  454. package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
  455. package/src/modules/currencies/backend/currencies/page.tsx +18 -11
  456. package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
  457. package/src/modules/currencies/backend/exchange-rates/page.tsx +10 -6
  458. package/src/modules/currencies/commands/currencies.ts +10 -5
  459. package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
  460. package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
  461. package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
  462. package/src/modules/customer_accounts/api/admin/users/[id].ts +38 -5
  463. package/src/modules/customer_accounts/api/admin/users.ts +2 -0
  464. package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
  465. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +9 -4
  466. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
  467. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
  468. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +19 -11
  469. package/src/modules/customers/AGENTS.md +2 -2
  470. package/src/modules/customers/api/companies/route.ts +14 -1
  471. package/src/modules/customers/api/deals/route.ts +3 -0
  472. package/src/modules/customers/api/people/route.ts +12 -1
  473. package/src/modules/customers/api/todos/route.ts +1 -0
  474. package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
  475. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
  476. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
  477. package/src/modules/customers/backend/customers/companies/page.tsx +2 -0
  478. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
  479. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
  480. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
  481. package/src/modules/customers/backend/customers/deals/page.tsx +18 -6
  482. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
  483. package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
  484. package/src/modules/customers/backend/customers/people/page.tsx +2 -0
  485. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +84 -24
  486. package/src/modules/customers/commands/addresses.ts +16 -14
  487. package/src/modules/customers/commands/companies.ts +3 -1
  488. package/src/modules/customers/commands/interactions.ts +50 -4
  489. package/src/modules/customers/commands/people.ts +2 -1
  490. package/src/modules/customers/commands/personCompanyLinks.ts +8 -5
  491. package/src/modules/customers/commands/pipeline-stages.ts +16 -16
  492. package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
  493. package/src/modules/customers/components/DictionarySettings.tsx +18 -13
  494. package/src/modules/customers/components/DictionarySortSettings.tsx +4 -0
  495. package/src/modules/customers/components/PipelineSettings.tsx +42 -21
  496. package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
  497. package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
  498. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
  499. package/src/modules/customers/components/detail/DealsSection.tsx +4 -0
  500. package/src/modules/customers/components/detail/EmailCardActions.tsx +5 -0
  501. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
  502. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
  503. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
  504. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
  505. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
  506. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
  507. package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
  508. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
  509. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
  510. package/src/modules/customers/components/detail/types.ts +1 -0
  511. package/src/modules/customers/components/formConfig.tsx +2 -0
  512. package/src/modules/customers/data/guards.ts +67 -0
  513. package/src/modules/customers/di.ts +66 -0
  514. package/src/modules/customers/i18n/de.json +2 -0
  515. package/src/modules/customers/i18n/en.json +2 -0
  516. package/src/modules/customers/i18n/es.json +2 -0
  517. package/src/modules/customers/i18n/pl.json +2 -0
  518. package/src/modules/customers/lib/todoCompatibility.ts +14 -0
  519. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
  520. package/src/modules/data_sync/api/options.ts +7 -4
  521. package/src/modules/data_sync/api/schedules/route.ts +9 -1
  522. package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
  523. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
  524. package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
  525. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
  526. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +23 -0
  527. package/src/modules/dictionaries/components/DictionariesManager.tsx +32 -9
  528. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +30 -14
  529. package/src/modules/dictionaries/i18n/de.json +1 -0
  530. package/src/modules/dictionaries/i18n/en.json +1 -0
  531. package/src/modules/dictionaries/i18n/es.json +1 -0
  532. package/src/modules/dictionaries/i18n/pl.json +1 -0
  533. package/src/modules/directory/api/organizations/route.ts +3 -0
  534. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
  535. package/src/modules/directory/backend/directory/organizations/page.tsx +10 -5
  536. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
  537. package/src/modules/directory/backend/directory/tenants/page.tsx +8 -4
  538. package/src/modules/directory/commands/organizations.ts +7 -4
  539. package/src/modules/entities/api/records.ts +99 -0
  540. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
  541. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
  542. package/src/modules/entities/lib/helpers.ts +17 -0
  543. package/src/modules/feature_toggles/api/global/[id]/override/route.ts +1 -0
  544. package/src/modules/feature_toggles/api/overrides/route.ts +19 -0
  545. package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +19 -13
  546. package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
  547. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +7 -2
  548. package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
  549. package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
  550. package/src/modules/feature_toggles/data/validators.ts +11 -3
  551. package/src/modules/inbox_ops/api/settings/route.ts +18 -0
  552. package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
  553. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
  554. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
  555. package/src/modules/integrations/backend/integrations/page.tsx +13 -8
  556. package/src/modules/messages/commands/messages.ts +27 -15
  557. package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
  558. package/src/modules/perspectives/services/perspectiveService.ts +13 -1
  559. package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
  560. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
  561. package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +3 -0
  562. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +58 -15
  563. package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
  564. package/src/modules/query_index/lib/engine.ts +34 -0
  565. package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +7 -1
  566. package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
  567. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +23 -3
  568. package/src/modules/resources/backend/resources/resources/page.tsx +15 -4
  569. package/src/modules/resources/components/ResourceCrudForm.tsx +3 -0
  570. package/src/modules/resources/components/ResourceTypeCrudForm.tsx +2 -0
  571. package/src/modules/sales/api/documents/factory.ts +13 -1
  572. package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
  573. package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
  574. package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
  575. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +73 -20
  576. package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
  577. package/src/modules/sales/commands/documentAddresses.ts +226 -4
  578. package/src/modules/sales/commands/documents.ts +28 -0
  579. package/src/modules/sales/commands/returns.ts +12 -3
  580. package/src/modules/sales/commands/shared.ts +36 -0
  581. package/src/modules/sales/commands/shipments.ts +17 -1
  582. package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
  583. package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
  584. package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
  585. package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
  586. package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
  587. package/src/modules/sales/components/StatusSettings.tsx +20 -11
  588. package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
  589. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +67 -14
  590. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +7 -4
  591. package/src/modules/sales/components/documents/AddressesSection.tsx +35 -25
  592. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
  593. package/src/modules/sales/components/documents/ItemsSection.tsx +24 -13
  594. package/src/modules/sales/components/documents/LineItemDialog.tsx +26 -9
  595. package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
  596. package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
  597. package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
  598. package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
  599. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +11 -4
  600. package/src/modules/sales/components/documents/ShipmentDialog.tsx +23 -8
  601. package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
  602. package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
  603. package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
  604. package/src/modules/sales/di.ts +35 -0
  605. package/src/modules/sales/i18n/de.json +3 -0
  606. package/src/modules/sales/i18n/en.json +3 -0
  607. package/src/modules/sales/i18n/es.json +3 -0
  608. package/src/modules/sales/i18n/pl.json +3 -0
  609. package/src/modules/staff/api/job-histories.ts +12 -2
  610. package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
  611. package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
  612. package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
  613. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
  614. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -2
  615. package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +8 -0
  616. package/src/modules/staff/backend/staff/team-roles/page.tsx +6 -2
  617. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
  618. package/src/modules/staff/backend/staff/teams/page.tsx +9 -3
  619. package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
  620. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -0
  621. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
  622. package/src/modules/staff/commands/job-histories.ts +42 -3
  623. package/src/modules/staff/components/LeaveRequestForm.tsx +2 -0
  624. package/src/modules/staff/components/TeamForm.tsx +2 -0
  625. package/src/modules/staff/components/TeamMemberForm.tsx +2 -0
  626. package/src/modules/staff/components/TeamRoleForm.tsx +2 -0
  627. package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
  628. package/src/modules/staff/data/validators.ts +6 -0
  629. package/src/modules/staff/i18n/de.json +1 -0
  630. package/src/modules/staff/i18n/en.json +1 -0
  631. package/src/modules/staff/i18n/es.json +1 -0
  632. package/src/modules/staff/i18n/pl.json +1 -0
  633. package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
  634. package/src/modules/translations/components/TranslationManager.tsx +13 -8
  635. package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
  636. package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
  637. package/src/modules/workflows/backend/definitions/page.tsx +20 -9
  638. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
  639. package/src/modules/workflows/components/formConfig.tsx +5 -0
  640. package/src/modules/workflows/di.ts +20 -0
  641. package/src/modules/workflows/i18n/de.json +1 -0
  642. package/src/modules/workflows/i18n/en.json +1 -0
  643. package/src/modules/workflows/i18n/es.json +1 -0
  644. package/src/modules/workflows/i18n/pl.json +1 -0
@@ -1,7 +1,9 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
- import { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
4
+ import { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
5
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
6
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
5
7
  import { useT } from '@open-mercato/shared/lib/i18n/context'
6
8
  import type { InteractionSummary } from '../types'
7
9
 
@@ -226,87 +228,126 @@ export function useInteractions({
226
228
  const updateInteraction = React.useCallback(
227
229
  async (id: string, payload: InteractionUpdatePayload) => {
228
230
  setIsMutating(true)
231
+ // Send the optimistic-lock header (target's loaded `updatedAt`) so a stale
232
+ // edit — including a task/activity edited from another tab — surfaces the
233
+ // conflict bar instead of silently overwriting (#2055). A stale edit after
234
+ // the record was deleted elsewhere maps to the same 409 via the server's
235
+ // enforceRecordGoneIsConflict, instead of a bare "Interaction not found" 404.
236
+ const target = interactions.find((entry) => entry.id === id)
229
237
  try {
230
- await apiCallOrThrow(
231
- '/api/customers/interactions',
232
- {
233
- method: 'PUT',
234
- headers: { 'content-type': 'application/json' },
235
- body: JSON.stringify({ id, ...payload }),
236
- },
237
- { errorMessage: t('customers.interactions.update.error', 'Failed to update interaction.') },
238
+ await withScopedApiRequestHeaders(
239
+ buildOptimisticLockHeader(target?.updatedAt ?? null),
240
+ () => apiCallOrThrow(
241
+ '/api/customers/interactions',
242
+ {
243
+ method: 'PUT',
244
+ headers: { 'content-type': 'application/json' },
245
+ body: JSON.stringify({ id, ...payload }),
246
+ },
247
+ { errorMessage: t('customers.interactions.update.error', 'Failed to update interaction.') },
248
+ ),
238
249
  )
239
250
  await refresh()
251
+ } catch (err) {
252
+ if (surfaceRecordConflict(err, t)) { await refresh(); return }
253
+ throw err
240
254
  } finally {
241
255
  setIsMutating(false)
242
256
  }
243
257
  },
244
- [refresh, t],
258
+ [interactions, refresh, t],
245
259
  )
246
260
 
247
261
  const completeInteraction = React.useCallback(
248
262
  async (id: string) => {
249
263
  setIsMutating(true)
250
264
  setPendingId(id)
265
+ const target = interactions.find((entry) => entry.id === id)
251
266
  try {
252
- await apiCallOrThrow(
253
- '/api/customers/interactions/complete',
254
- {
255
- method: 'POST',
256
- headers: { 'content-type': 'application/json' },
257
- body: JSON.stringify({ id }),
258
- },
259
- { errorMessage: t('customers.interactions.complete.error', 'Failed to complete interaction.') },
267
+ await withScopedApiRequestHeaders(
268
+ buildOptimisticLockHeader(target?.updatedAt ?? null),
269
+ () => apiCallOrThrow(
270
+ '/api/customers/interactions/complete',
271
+ {
272
+ method: 'POST',
273
+ headers: { 'content-type': 'application/json' },
274
+ body: JSON.stringify({ id }),
275
+ },
276
+ { errorMessage: t('customers.interactions.complete.error', 'Failed to complete interaction.') },
277
+ ),
260
278
  )
261
279
  await refresh()
280
+ } catch (err) {
281
+ if (surfaceRecordConflict(err, t)) { await refresh(); return }
282
+ throw err
262
283
  } finally {
263
284
  setPendingId(null)
264
285
  setIsMutating(false)
265
286
  }
266
287
  },
267
- [refresh, t],
288
+ [interactions, refresh, t],
268
289
  )
269
290
 
270
291
  const cancelInteraction = React.useCallback(
271
292
  async (id: string) => {
272
293
  setIsMutating(true)
273
294
  setPendingId(id)
295
+ const target = interactions.find((entry) => entry.id === id)
274
296
  try {
275
- await apiCallOrThrow(
276
- '/api/customers/interactions/cancel',
277
- {
278
- method: 'POST',
279
- headers: { 'content-type': 'application/json' },
280
- body: JSON.stringify({ id }),
281
- },
282
- { errorMessage: t('customers.interactions.cancel.error', 'Failed to cancel interaction.') },
297
+ await withScopedApiRequestHeaders(
298
+ buildOptimisticLockHeader(target?.updatedAt ?? null),
299
+ () => apiCallOrThrow(
300
+ '/api/customers/interactions/cancel',
301
+ {
302
+ method: 'POST',
303
+ headers: { 'content-type': 'application/json' },
304
+ body: JSON.stringify({ id }),
305
+ },
306
+ { errorMessage: t('customers.interactions.cancel.error', 'Failed to cancel interaction.') },
307
+ ),
283
308
  )
284
309
  await refresh()
310
+ } catch (err) {
311
+ if (surfaceRecordConflict(err, t)) { await refresh(); return }
312
+ throw err
285
313
  } finally {
286
314
  setPendingId(null)
287
315
  setIsMutating(false)
288
316
  }
289
317
  },
290
- [refresh, t],
318
+ [interactions, refresh, t],
291
319
  )
292
320
 
293
321
  const deleteInteraction = React.useCallback(
294
322
  async (id: string) => {
295
323
  setIsMutating(true)
324
+ const target = interactions.find((entry) => entry.id === id)
296
325
  try {
297
- await apiCallOrThrow(
298
- `/api/customers/interactions?id=${encodeURIComponent(id)}`,
299
- {
300
- method: 'DELETE',
301
- },
302
- { errorMessage: t('customers.interactions.delete.error', 'Failed to delete interaction.') },
326
+ await withScopedApiRequestHeaders(
327
+ buildOptimisticLockHeader(target?.updatedAt ?? null),
328
+ () =>
329
+ apiCallOrThrow(
330
+ `/api/customers/interactions?id=${encodeURIComponent(id)}`,
331
+ {
332
+ method: 'DELETE',
333
+ },
334
+ { errorMessage: t('customers.interactions.delete.error', 'Failed to delete interaction.') },
335
+ ),
303
336
  )
304
337
  await refresh()
338
+ } catch (err) {
339
+ // A stale delete (the record was changed/deleted in another tab) surfaces
340
+ // the unified conflict bar and re-syncs the list instead of a raw error (#2055).
341
+ if (surfaceRecordConflict(err, t)) {
342
+ await refresh()
343
+ return
344
+ }
345
+ throw err
305
346
  } finally {
306
347
  setIsMutating(false)
307
348
  }
308
349
  },
309
- [refresh, t],
350
+ [interactions, refresh, t],
310
351
  )
311
352
 
312
353
  const hasMore = entityId != null && nextCursor != null
@@ -1,7 +1,8 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
- import { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
4
+ import { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
5
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
5
6
  import { resolveTodoApiPath } from '../utils'
6
7
  import type { TodoLinkSummary } from '../types'
7
8
  import { generateTempId } from '@open-mercato/core/modules/customers/lib/detailHelpers'
@@ -22,6 +23,7 @@ type CustomerTodoRow = {
22
23
  todoDueAt: string | null
23
24
  todoCustomValues: Record<string, unknown> | null
24
25
  todoOrganizationId: string | null
26
+ todoUpdatedAt?: string | null
25
27
  organizationId: string
26
28
  tenantId: string
27
29
  createdAt: string
@@ -83,6 +85,7 @@ function mapRowToSummary(row: CustomerTodoRow): TodoLinkSummary {
83
85
  description: row.todoDescription ?? null,
84
86
  dueAt: row.todoDueAt ?? null,
85
87
  todoOrganizationId: row.todoOrganizationId ?? null,
88
+ updatedAt: row.todoUpdatedAt ?? null,
86
89
  customValues: row.todoCustomValues ?? null,
87
90
  }
88
91
  }
@@ -369,14 +372,21 @@ export function usePersonTasks({
369
372
  if (Object.keys(customValues).length) {
370
373
  body.customFields = customValues
371
374
  }
372
- await apiCallOrThrow(
373
- apiPath,
374
- {
375
- method: 'PUT',
376
- headers: { 'content-type': 'application/json' },
377
- body: JSON.stringify(body),
378
- },
379
- { errorMessage: 'Failed to update task.' },
375
+ // Send the optimistic-lock header (task's loaded updatedAt) so a stale
376
+ // edit — or an edit after the task was deleted in another tab — surfaces
377
+ // the unified conflict bar (409) instead of silently overwriting or
378
+ // returning a bare "Interaction not found" 404 (#2055).
379
+ await withScopedApiRequestHeaders(
380
+ buildOptimisticLockHeader(task.updatedAt ?? null),
381
+ () => apiCallOrThrow(
382
+ apiPath,
383
+ {
384
+ method: 'PUT',
385
+ headers: { 'content-type': 'application/json' },
386
+ body: JSON.stringify(body),
387
+ },
388
+ { errorMessage: 'Failed to update task.' },
389
+ ),
380
390
  )
381
391
  setTasks((prev) =>
382
392
  prev.map((item) => {
@@ -440,14 +450,17 @@ export function usePersonTasks({
440
450
  if (!task.id) throw new Error('Task link id missing')
441
451
  setIsMutating(true)
442
452
  try {
443
- await apiCallOrThrow(
444
- '/api/customers/todos',
445
- {
446
- method: 'DELETE',
447
- headers: { 'content-type': 'application/json' },
448
- body: JSON.stringify({ id: task.id }),
449
- },
450
- { errorMessage: 'Failed to remove task.' },
453
+ await withScopedApiRequestHeaders(
454
+ buildOptimisticLockHeader(task.updatedAt ?? null),
455
+ () => apiCallOrThrow(
456
+ '/api/customers/todos',
457
+ {
458
+ method: 'DELETE',
459
+ headers: { 'content-type': 'application/json' },
460
+ body: JSON.stringify({ id: task.id }),
461
+ },
462
+ { errorMessage: 'Failed to remove task.' },
463
+ ),
451
464
  )
452
465
  setTasks((prev) => prev.filter((item) => item.id !== task.id))
453
466
  setPageInfo((prev) => ({
@@ -19,6 +19,8 @@ export type LinkedEntity = {
19
19
 
20
20
  export type ScheduleActivityEditData = {
21
21
  id: string
22
+ /** Record version for the OSS optimistic-lock header on edit (#2055). */
23
+ updatedAt?: string | null
22
24
  interactionType?: string
23
25
  title?: string | null
24
26
  body?: string | null
@@ -113,6 +113,7 @@ export type TodoLinkSummary = {
113
113
  description?: string | null
114
114
  dueAt?: string | null
115
115
  todoOrganizationId?: string | null
116
+ updatedAt?: string | null
116
117
  customValues?: Record<string, unknown> | null
117
118
  externalHref?: string | null
118
119
  }
@@ -1897,6 +1897,8 @@ export type PersonOverview = {
1897
1897
  nextInteractionIcon?: string | null
1898
1898
  nextInteractionColor?: string | null
1899
1899
  organizationId?: string | null
1900
+ updatedAt?: string | null
1901
+ updated_at?: string | null
1900
1902
  }
1901
1903
  profile: {
1902
1904
  id: string
@@ -0,0 +1,67 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql'
2
+ import type { MutationGuard } from '@open-mercato/shared/lib/crud/mutation-guard-registry'
3
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
4
+ import { parseOptimisticLockEnv } from '@open-mercato/shared/lib/crud/optimistic-lock'
5
+ import { getAllOptimisticLockReaders } from '@open-mercato/shared/lib/crud/optimistic-lock-store'
6
+ import {
7
+ OPTIMISTIC_LOCK_CONFLICT_CODE,
8
+ OPTIMISTIC_LOCK_CONFLICT_ERROR,
9
+ OPTIMISTIC_LOCK_ENV_VAR,
10
+ OPTIMISTIC_LOCK_HEADER_NAME,
11
+ } from '@open-mercato/shared/lib/crud/optimistic-lock-headers'
12
+
13
+ function normalizeIsoToken(raw: string): string | null {
14
+ const ms = Date.parse(raw)
15
+ if (!Number.isFinite(ms)) return null
16
+ return new Date(ms).toISOString()
17
+ }
18
+
19
+ const optimisticLockGuard: MutationGuard = {
20
+ id: 'customers.optimistic-lock',
21
+ targetEntity: '*',
22
+ operations: ['update', 'delete'],
23
+ priority: 100,
24
+ async validate(input) {
25
+ const config = parseOptimisticLockEnv(process.env[OPTIMISTIC_LOCK_ENV_VAR])
26
+ if (config.mode === 'off') return { ok: true }
27
+ const enabled = config.mode === 'all' || config.entities.has(input.resourceKind.toLowerCase())
28
+ if (!enabled) return { ok: true }
29
+ const readers = getAllOptimisticLockReaders()
30
+ const reader = readers[input.resourceKind]
31
+ if (!reader) return { ok: true }
32
+ const expectedRaw = input.requestHeaders.get(OPTIMISTIC_LOCK_HEADER_NAME)
33
+ if (!expectedRaw || expectedRaw.trim().length === 0) return { ok: true }
34
+ const expectedIso = normalizeIsoToken(expectedRaw.trim())
35
+ if (!expectedIso) return { ok: true }
36
+ if (!input.resourceId) return { ok: true }
37
+ const container = await createRequestContainer()
38
+ let em: EntityManager
39
+ try {
40
+ em = container.resolve('em') as EntityManager
41
+ } catch {
42
+ return { ok: true }
43
+ }
44
+ const currentRaw = await reader(em, {
45
+ resourceKind: input.resourceKind,
46
+ resourceId: input.resourceId,
47
+ tenantId: input.tenantId,
48
+ organizationId: input.organizationId ?? null,
49
+ })
50
+ if (currentRaw == null) return { ok: true }
51
+ const currentIso = normalizeIsoToken(currentRaw)
52
+ if (currentIso == null) return { ok: true }
53
+ if (currentIso === expectedIso) return { ok: true }
54
+ return {
55
+ ok: false,
56
+ status: 409,
57
+ body: {
58
+ error: OPTIMISTIC_LOCK_CONFLICT_ERROR,
59
+ code: OPTIMISTIC_LOCK_CONFLICT_CODE,
60
+ currentUpdatedAt: currentIso,
61
+ expectedUpdatedAt: expectedIso,
62
+ },
63
+ }
64
+ },
65
+ }
66
+
67
+ export const guards: MutationGuard[] = [optimisticLockGuard]
@@ -1,11 +1,77 @@
1
1
  import { asValue } from 'awilix'
2
+ import type { EntityManager } from '@mikro-orm/postgresql'
2
3
  import type { AppContainer } from '@open-mercato/shared/lib/di/container'
4
+ import type { OptimisticLockCurrentReader } from '@open-mercato/shared/lib/crud/optimistic-lock'
5
+ import { registerOptimisticLockReaders } from '@open-mercato/shared/lib/crud/optimistic-lock-store'
3
6
  import { CustomerEntity, CustomerAddress, CustomerInteraction } from './data/entities'
4
7
 
8
+ const RESOURCE_KIND_COMPANY = 'customers.company'
9
+ // The CRUD factory derives resourceKind via singularize-the-second-segment of
10
+ // the commandId. For `customers.companies.update` it produces 'customers.company'.
11
+ // For `customers.people.update` it does NOT singularize 'people' → 'person' (the
12
+ // irregular plural is preserved), so the runtime resourceKind is
13
+ // 'customers.people'. We register the reader under BOTH names so the
14
+ // env opt-in entry can use either form (`customers.person` per spec or
15
+ // `customers.people` matching the factory's derivation).
16
+ const RESOURCE_KIND_PERSON = 'customers.person'
17
+ const RESOURCE_KIND_PEOPLE = 'customers.people'
18
+
19
+ const readCustomerCompanyUpdatedAt: OptimisticLockCurrentReader = async (
20
+ em: EntityManager,
21
+ { resourceId, tenantId, organizationId },
22
+ ) => {
23
+ const row = await em.findOne(
24
+ CustomerEntity,
25
+ {
26
+ id: resourceId,
27
+ tenantId,
28
+ ...(organizationId ? { organizationId } : {}),
29
+ kind: 'company',
30
+ deletedAt: null,
31
+ },
32
+ { fields: ['updatedAt'] as const },
33
+ )
34
+ return row?.updatedAt instanceof Date ? row.updatedAt.toISOString() : null
35
+ }
36
+
37
+ const readCustomerPersonUpdatedAt: OptimisticLockCurrentReader = async (
38
+ em: EntityManager,
39
+ { resourceId, tenantId, organizationId },
40
+ ) => {
41
+ const row = await em.findOne(
42
+ CustomerEntity,
43
+ {
44
+ id: resourceId,
45
+ tenantId,
46
+ ...(organizationId ? { organizationId } : {}),
47
+ kind: 'person',
48
+ deletedAt: null,
49
+ },
50
+ { fields: ['updatedAt'] as const },
51
+ )
52
+ return row?.updatedAt instanceof Date ? row.updatedAt.toISOString() : null
53
+ }
54
+
55
+ // Hand-wired readers must register at module-load time so they LAND BEFORE
56
+ // the factory's `registerOptimisticLockReaderIfAbsent` calls in
57
+ // `makeCrudRoute`. The discriminator (`kind: 'company' | 'person'`) cannot
58
+ // be expressed by the generic auto-reader because both kinds share the
59
+ // `customer_entities` polymorphic table. Registered unconditionally — the
60
+ // guard's mode check short-circuits when `OM_OPTIMISTIC_LOCK=off`.
61
+ registerOptimisticLockReaders({
62
+ [RESOURCE_KIND_COMPANY]: readCustomerCompanyUpdatedAt,
63
+ [RESOURCE_KIND_PERSON]: readCustomerPersonUpdatedAt,
64
+ [RESOURCE_KIND_PEOPLE]: readCustomerPersonUpdatedAt,
65
+ })
66
+
5
67
  export function register(container: AppContainer) {
6
68
  container.register({
7
69
  CustomerEntity: asValue(CustomerEntity),
8
70
  CustomerAddress: asValue(CustomerAddress),
9
71
  CustomerInteraction: asValue(CustomerInteraction),
10
72
  })
73
+ // `crudMutationGuardService` is registered platform-wide in the shared
74
+ // DI bootstrap (`packages/shared/src/lib/di/container.ts`). It already
75
+ // resolves the hand-wired readers above from the global store, so this
76
+ // module no longer needs its own DI binding.
11
77
  }
@@ -317,6 +317,7 @@
317
317
  "customers.companies.detail.deals.loading": "Deals werden geladen…",
318
318
  "customers.companies.detail.deleteConfirmDescription": "Diese Aktion kann nicht rückgängig gemacht werden.",
319
319
  "customers.companies.detail.deleteConfirmTitle": "Unternehmen löschen?",
320
+ "customers.companies.detail.deleteError": "Unternehmen konnte nicht gelöscht werden.",
320
321
  "customers.companies.detail.employees": "Mitarbeiter",
321
322
  "customers.companies.detail.empty.addresses": "Keine Adressen erfasst.",
322
323
  "customers.companies.detail.empty.comments": "Noch keine Notizen.",
@@ -1673,6 +1674,7 @@
1673
1674
  "customers.people.detail.deals.valueInvalid": "Bitte gib einen gültigen Betrag ein",
1674
1675
  "customers.people.detail.deleteConfirmDescription": "Diese Aktion kann nicht rückgängig gemacht werden.",
1675
1676
  "customers.people.detail.deleteConfirmTitle": "Person löschen?",
1677
+ "customers.people.detail.deleteError": "Person konnte nicht gelöscht werden.",
1676
1678
  "customers.people.detail.empty.activities": "Noch keine Aktivitäten",
1677
1679
  "customers.people.detail.empty.addresses": "Noch keine Adressen",
1678
1680
  "customers.people.detail.empty.comments": "Noch keine Notizen",
@@ -317,6 +317,7 @@
317
317
  "customers.companies.detail.deals.loading": "Loading deals…",
318
318
  "customers.companies.detail.deleteConfirmDescription": "This action cannot be undone.",
319
319
  "customers.companies.detail.deleteConfirmTitle": "Delete company?",
320
+ "customers.companies.detail.deleteError": "Failed to delete company.",
320
321
  "customers.companies.detail.employees": "employees",
321
322
  "customers.companies.detail.empty.addresses": "No addresses recorded.",
322
323
  "customers.companies.detail.empty.comments": "No notes yet.",
@@ -1673,6 +1674,7 @@
1673
1674
  "customers.people.detail.deals.valueInvalid": "Enter a valid amount",
1674
1675
  "customers.people.detail.deleteConfirmDescription": "This action cannot be undone.",
1675
1676
  "customers.people.detail.deleteConfirmTitle": "Delete person?",
1677
+ "customers.people.detail.deleteError": "Failed to delete person.",
1676
1678
  "customers.people.detail.empty.activities": "No activity yet",
1677
1679
  "customers.people.detail.empty.addresses": "No addresses yet",
1678
1680
  "customers.people.detail.empty.comments": "No notes yet",
@@ -317,6 +317,7 @@
317
317
  "customers.companies.detail.deals.loading": "Cargando oportunidades…",
318
318
  "customers.companies.detail.deleteConfirmDescription": "Esta acción no se puede deshacer.",
319
319
  "customers.companies.detail.deleteConfirmTitle": "¿Eliminar empresa?",
320
+ "customers.companies.detail.deleteError": "Error al eliminar la empresa.",
320
321
  "customers.companies.detail.employees": "empleados",
321
322
  "customers.companies.detail.empty.addresses": "Sin direcciones registradas.",
322
323
  "customers.companies.detail.empty.comments": "Sin notas aún.",
@@ -1673,6 +1674,7 @@
1673
1674
  "customers.people.detail.deals.valueInvalid": "Introduce un importe válido",
1674
1675
  "customers.people.detail.deleteConfirmDescription": "Esta acción no se puede deshacer.",
1675
1676
  "customers.people.detail.deleteConfirmTitle": "¿Eliminar persona?",
1677
+ "customers.people.detail.deleteError": "Error al eliminar la persona.",
1676
1678
  "customers.people.detail.empty.activities": "Sin actividad",
1677
1679
  "customers.people.detail.empty.addresses": "Sin direcciones",
1678
1680
  "customers.people.detail.empty.comments": "Sin notas",
@@ -317,6 +317,7 @@
317
317
  "customers.companies.detail.deals.loading": "Ładowanie szans sprzedaży…",
318
318
  "customers.companies.detail.deleteConfirmDescription": "Tej operacji nie można cofnąć.",
319
319
  "customers.companies.detail.deleteConfirmTitle": "Usunąć firmę?",
320
+ "customers.companies.detail.deleteError": "Nie udało się usunąć firmy.",
320
321
  "customers.companies.detail.employees": "osób",
321
322
  "customers.companies.detail.empty.addresses": "Brak zarejestrowanych adresów.",
322
323
  "customers.companies.detail.empty.comments": "Brak notatek.",
@@ -1673,6 +1674,7 @@
1673
1674
  "customers.people.detail.deals.valueInvalid": "Podaj poprawną kwotę",
1674
1675
  "customers.people.detail.deleteConfirmDescription": "Tej operacji nie można cofnąć.",
1675
1676
  "customers.people.detail.deleteConfirmTitle": "Usunąć osobę?",
1677
+ "customers.people.detail.deleteError": "Nie udało się usunąć osoby.",
1676
1678
  "customers.people.detail.empty.activities": "Brak aktywności",
1677
1679
  "customers.people.detail.empty.addresses": "Brak adresów",
1678
1680
  "customers.people.detail.empty.comments": "Brak notatek",
@@ -26,6 +26,7 @@ export type CustomerTodoRow = {
26
26
  todoDueAt?: string | null
27
27
  todoCustomValues?: Record<string, unknown> | null
28
28
  todoOrganizationId: string | null
29
+ todoUpdatedAt?: string | null
29
30
  organizationId: string
30
31
  tenantId: string
31
32
  createdAt: string
@@ -46,6 +47,7 @@ export type LegacyTodoDetail = {
46
47
  description: string | null
47
48
  dueAt: string | null
48
49
  organizationId: string | null
50
+ updatedAt: string | null
49
51
  customValues: Record<string, unknown> | null
50
52
  }
51
53
 
@@ -336,6 +338,15 @@ export async function resolveLegacyTodoDetails(
336
338
  }
337
339
  }
338
340
 
341
+ const updatedAt = (() => {
342
+ const candidates = [record.updated_at, record.updatedAt]
343
+ for (const candidate of candidates) {
344
+ const parsed = parseDateValue(candidate)
345
+ if (parsed) return parsed
346
+ }
347
+ return null
348
+ })()
349
+
339
350
  details.set(`${source}:${rawId}`, {
340
351
  title: extractTodoTitle(record),
341
352
  isDone,
@@ -344,6 +355,7 @@ export async function resolveLegacyTodoDetails(
344
355
  description,
345
356
  dueAt,
346
357
  organizationId,
358
+ updatedAt,
347
359
  customValues: Object.keys(customValues).length > 0 ? customValues : null,
348
360
  })
349
361
  }
@@ -550,6 +562,7 @@ export function mapLegacyTodoLinkToRow(
550
562
  todoDueAt: detail?.dueAt ?? null,
551
563
  todoCustomValues: detail?.customValues ?? null,
552
564
  todoOrganizationId: detail?.organizationId ?? link.organizationId ?? null,
565
+ todoUpdatedAt: detail?.updatedAt ?? null,
553
566
  organizationId: link.organizationId,
554
567
  tenantId: link.tenantId,
555
568
  createdAt: link.createdAt.toISOString(),
@@ -595,6 +608,7 @@ export function mapInteractionRecordToTodoRow(
595
608
  todoDueAt: interaction.scheduledAt ?? null,
596
609
  todoCustomValues: Object.keys(customValues).length > 0 ? customValues : null,
597
610
  todoOrganizationId: interaction.organizationId ?? null,
611
+ todoUpdatedAt: interaction.updatedAt ?? null,
598
612
  organizationId: interaction.organizationId ?? '',
599
613
  tenantId: interaction.tenantId ?? '',
600
614
  createdAt: interaction.createdAt,
@@ -242,6 +242,7 @@ export const WidgetVisibilityEditor = React.forwardRef<WidgetVisibilityEditorHan
242
242
  organizationId: organizationId ?? null,
243
243
  widgetIds: selected,
244
244
  }
245
+ // optimistic-lock-exempt: per-role widget visibility preference
245
246
  await apiCallOrThrow('/api/dashboards/roles/widgets', {
246
247
  method: 'PUT',
247
248
  headers: { 'content-type': 'application/json' },
@@ -258,6 +259,7 @@ export const WidgetVisibilityEditor = React.forwardRef<WidgetVisibilityEditorHan
258
259
  mode,
259
260
  widgetIds: selected,
260
261
  }
262
+ // optimistic-lock-exempt: per-user widget visibility preference
261
263
  await apiCallOrThrow('/api/dashboards/users/widgets', {
262
264
  method: 'PUT',
263
265
  headers: { 'content-type': 'application/json' },
@@ -33,9 +33,12 @@ export async function GET(req: Request) {
33
33
  const adapter = getDataSyncAdapter(integration.providerKey as string)
34
34
  if (!adapter) return null
35
35
 
36
- const [credentials, state] = await Promise.all([
37
- credentialsService.resolve(integration.id, scope),
38
- stateService.resolveState(integration.id, scope),
36
+ const [credentials, isEnabled] = await Promise.all([
37
+ credentialsService.resolve(integration.id, scope).catch(() => null),
38
+ stateService
39
+ .resolveState(integration.id, scope)
40
+ .then((state) => state.isEnabled)
41
+ .catch(() => false),
39
42
  ])
40
43
 
41
44
  return {
@@ -48,7 +51,7 @@ export async function GET(req: Request) {
48
51
  canStartRun: adapter.runMode !== 'provider',
49
52
  supportedEntities: adapter.supportedEntities,
50
53
  hasCredentials: Boolean(credentials),
51
- isEnabled: state.isEnabled,
54
+ isEnabled,
52
55
  settingsPath: `/backend/integrations/${encodeURIComponent(integration.id)}`,
53
56
  }
54
57
  }),
@@ -5,6 +5,8 @@ import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
5
5
  import { createSyncScheduleSchema, listSyncSchedulesQuerySchema } from '../../data/validators'
6
6
  import type { SyncScheduleService } from '../../lib/sync-schedule-service'
7
7
  import { serializeSchedule } from './serialize'
8
+ import { readOptimisticLockExpected } from '@open-mercato/shared/lib/crud/optimistic-lock-command'
9
+ import { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
8
10
 
9
11
  export const metadata = {
10
12
  GET: { requireAuth: true, requireFeatures: ['data_sync.configure'] },
@@ -65,12 +67,18 @@ export async function POST(req: Request) {
65
67
  const scheduleService = container.resolve('dataSyncScheduleService') as SyncScheduleService
66
68
 
67
69
  try {
68
- const schedule = await scheduleService.saveSchedule(parsed.data, {
70
+ const schedule = await scheduleService.saveSchedule({
71
+ ...parsed.data,
72
+ expectedUpdatedAt: readOptimisticLockExpected(req),
73
+ }, {
69
74
  organizationId: auth.orgId as string,
70
75
  tenantId: auth.tenantId,
71
76
  })
72
77
  return NextResponse.json(serializeSchedule(schedule), { status: 201 })
73
78
  } catch (error) {
79
+ if (isCrudHttpError(error)) {
80
+ return NextResponse.json(error.body, { status: error.status })
81
+ }
74
82
  const message = error instanceof Error ? error.message : 'Failed to save sync schedule'
75
83
  return NextResponse.json({ error: message }, { status: 422 })
76
84
  }