@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
@@ -3,7 +3,8 @@
3
3
  import * as React from 'react'
4
4
  import { Page, PageBody } from '@open-mercato/ui/backend/Page'
5
5
  import { useT } from '@open-mercato/shared/lib/i18n/context'
6
- import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
6
+ import { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
7
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
7
8
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
8
9
  import { Button } from '@open-mercato/ui/primitives/button'
9
10
  import { Input } from '@open-mercato/ui/primitives/input'
@@ -24,6 +25,7 @@ type Pipeline = {
24
25
  id: string
25
26
  name: string
26
27
  isDefault: boolean
28
+ updatedAt?: string | null
27
29
  }
28
30
 
29
31
  type PipelineStage = {
@@ -33,6 +35,7 @@ type PipelineStage = {
33
35
  order: number
34
36
  color: string | null
35
37
  icon: string | null
38
+ updatedAt?: string | null
36
39
  }
37
40
 
38
41
  type PipelineDialogState =
@@ -146,11 +149,14 @@ export default function PipelineStagesPage() {
146
149
  await loadPipelines()
147
150
  if (newId) setSelectedPipelineId(newId)
148
151
  } else if (pipelineDialog?.mode === 'edit') {
149
- const result = await apiCall('/api/customers/pipelines', {
150
- method: 'PUT',
151
- body: JSON.stringify({ id: pipelineDialog.pipeline.id, name: pipelineName.trim(), isDefault: pipelineIsDefault }),
152
- headers: { 'Content-Type': 'application/json' },
153
- })
152
+ const result = await withScopedApiRequestHeaders(
153
+ buildOptimisticLockHeader(pipelineDialog.pipeline.updatedAt),
154
+ () => apiCall('/api/customers/pipelines', {
155
+ method: 'PUT',
156
+ body: JSON.stringify({ id: pipelineDialog.pipeline.id, name: pipelineName.trim(), isDefault: pipelineIsDefault }),
157
+ headers: { 'Content-Type': 'application/json' },
158
+ }),
159
+ )
154
160
  if (!result.ok) {
155
161
  flash(t('customers.config.pipelineStages.errorUpdatePipeline', 'Failed to update pipeline'), 'error')
156
162
  return
@@ -175,11 +181,14 @@ export default function PipelineStagesPage() {
175
181
  variant: 'destructive',
176
182
  })
177
183
  if (!confirmed) return
178
- const result = await apiCall('/api/customers/pipelines', {
179
- method: 'DELETE',
180
- body: JSON.stringify({ id: pipeline.id }),
181
- headers: { 'Content-Type': 'application/json' },
182
- })
184
+ const result = await withScopedApiRequestHeaders(
185
+ buildOptimisticLockHeader(pipeline.updatedAt),
186
+ () => apiCall('/api/customers/pipelines', {
187
+ method: 'DELETE',
188
+ body: JSON.stringify({ id: pipeline.id }),
189
+ headers: { 'Content-Type': 'application/json' },
190
+ }),
191
+ )
183
192
  if (!result.ok) {
184
193
  const error = (result.result as { error?: string })?.error
185
194
  flash(error ?? t('customers.config.pipelineStages.errorDeletePipeline', 'Failed to delete pipeline'), 'error')
@@ -224,11 +233,14 @@ export default function PipelineStagesPage() {
224
233
  }
225
234
  flash(t('customers.config.pipelineStages.createdStage', 'Stage created'), 'success')
226
235
  } else if (stageDialog?.mode === 'edit') {
227
- const result = await apiCall('/api/customers/pipeline-stages', {
228
- method: 'PUT',
229
- body: JSON.stringify({ id: stageDialog.stage.id, label: stageName.trim(), color: stageColor, icon: stageIcon }),
230
- headers: { 'Content-Type': 'application/json' },
231
- })
236
+ const result = await withScopedApiRequestHeaders(
237
+ buildOptimisticLockHeader(stageDialog.stage.updatedAt),
238
+ () => apiCall('/api/customers/pipeline-stages', {
239
+ method: 'PUT',
240
+ body: JSON.stringify({ id: stageDialog.stage.id, label: stageName.trim(), color: stageColor, icon: stageIcon }),
241
+ headers: { 'Content-Type': 'application/json' },
242
+ }),
243
+ )
232
244
  if (!result.ok) {
233
245
  flash(t('customers.config.pipelineStages.errorUpdateStage', 'Failed to update stage'), 'error')
234
246
  return
@@ -253,11 +265,14 @@ export default function PipelineStagesPage() {
253
265
  variant: 'destructive',
254
266
  })
255
267
  if (!confirmed) return
256
- const result = await apiCall('/api/customers/pipeline-stages', {
257
- method: 'DELETE',
258
- body: JSON.stringify({ id: stage.id }),
259
- headers: { 'Content-Type': 'application/json' },
260
- })
268
+ const result = await withScopedApiRequestHeaders(
269
+ buildOptimisticLockHeader(stage.updatedAt),
270
+ () => apiCall('/api/customers/pipeline-stages', {
271
+ method: 'DELETE',
272
+ body: JSON.stringify({ id: stage.id }),
273
+ headers: { 'Content-Type': 'application/json' },
274
+ }),
275
+ )
261
276
  if (!result.ok) {
262
277
  const error = (result.result as { error?: string })?.error
263
278
  flash(error ?? t('customers.config.pipelineStages.errorDeleteStage', 'Failed to delete stage'), 'error')
@@ -8,7 +8,8 @@ import { Button } from '@open-mercato/ui/primitives/button'
8
8
  import { Separator } from '@open-mercato/ui/primitives/separator'
9
9
  import { Spinner } from '@open-mercato/ui/primitives/spinner'
10
10
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
11
- import { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
11
+ import { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
12
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
12
13
  import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
13
14
  import { mapCrudServerErrorToFormErrors } from '@open-mercato/ui/backend/utils/serverErrors'
14
15
  import { E } from '#generated/entities.ids.generated'
@@ -70,6 +71,7 @@ type CompanyOverview = {
70
71
  nextInteractionIcon?: string | null
71
72
  nextInteractionColor?: string | null
72
73
  organizationId?: string | null
74
+ updatedAt?: string | null
73
75
  }
74
76
  profile: {
75
77
  id: string
@@ -324,19 +326,31 @@ export default function CustomerCompanyDetailPage({ params }: { params?: { id?:
324
326
  async (patch: Record<string, unknown>, apply: (prev: CompanyOverview) => CompanyOverview) => {
325
327
  if (!data) return
326
328
  const payload = { id: data.company.id, ...patch }
327
- await runMutationWithContext(
328
- () => apiCallOrThrow(
329
- '/api/customers/companies',
330
- {
331
- method: 'PUT',
332
- headers: { 'content-type': 'application/json' },
333
- body: JSON.stringify(payload),
334
- },
335
- { errorMessage: t('customers.companies.detail.inline.error', 'Unable to update company.') },
329
+ const result = await runMutationWithContext(
330
+ () => withScopedApiRequestHeaders(
331
+ buildOptimisticLockHeader((data?.company as { updatedAt?: string } | undefined)?.updatedAt),
332
+ () => apiCallOrThrow<{ ok?: boolean; updatedAt?: string | null }>(
333
+ '/api/customers/companies',
334
+ {
335
+ method: 'PUT',
336
+ headers: { 'content-type': 'application/json' },
337
+ body: JSON.stringify(payload),
338
+ },
339
+ { errorMessage: t('customers.companies.detail.inline.error', 'Unable to update company.') },
340
+ ),
336
341
  ),
337
342
  payload,
338
343
  )
339
- setData((prev) => (prev ? apply(prev) : prev))
344
+ // Refresh the optimistic-lock token so the next sequential inline edit does
345
+ // not send a stale updatedAt and falsely 409 (#2055, default-ON locking).
346
+ const nextUpdatedAt = result?.result?.updatedAt ?? null
347
+ setData((prev) => {
348
+ if (!prev) return prev
349
+ const applied = apply(prev)
350
+ return nextUpdatedAt
351
+ ? { ...applied, company: { ...applied.company, updatedAt: nextUpdatedAt } }
352
+ : applied
353
+ })
340
354
  },
341
355
  [data, runMutationWithContext, t],
342
356
  )
@@ -417,19 +431,24 @@ export default function CustomerCompanyDetailPage({ params }: { params?: { id?:
417
431
  id: data.company.id,
418
432
  customFields: customPayload,
419
433
  }
434
+ let customFieldsUpdatedAt: string | null = null
420
435
  try {
421
- await runMutationWithContext(
422
- () => apiCallOrThrow(
423
- '/api/customers/companies',
424
- {
425
- method: 'PUT',
426
- headers: { 'content-type': 'application/json' },
427
- body: JSON.stringify(payload),
428
- },
429
- { errorMessage: t('customers.companies.detail.inline.error', 'Unable to update company.') },
436
+ const result = await runMutationWithContext(
437
+ () => withScopedApiRequestHeaders(
438
+ buildOptimisticLockHeader((data?.company as { updatedAt?: string } | undefined)?.updatedAt),
439
+ () => apiCallOrThrow<{ ok?: boolean; updatedAt?: string | null }>(
440
+ '/api/customers/companies',
441
+ {
442
+ method: 'PUT',
443
+ headers: { 'content-type': 'application/json' },
444
+ body: JSON.stringify(payload),
445
+ },
446
+ { errorMessage: t('customers.companies.detail.inline.error', 'Unable to update company.') },
447
+ ),
430
448
  ),
431
449
  payload,
432
450
  )
451
+ customFieldsUpdatedAt = result?.result?.updatedAt ?? null
433
452
  } catch (err) {
434
453
  const { message: helperMessage, fieldErrors } = mapCrudServerErrorToFormErrors(err)
435
454
  const message = helperMessage ?? t('customers.companies.detail.inline.error', 'Unable to update company.')
@@ -448,6 +467,9 @@ export default function CustomerCompanyDetailPage({ params }: { params?: { id?:
448
467
  if (!prev) return prev
449
468
  return {
450
469
  ...prev,
470
+ company: customFieldsUpdatedAt
471
+ ? { ...prev.company, updatedAt: customFieldsUpdatedAt }
472
+ : prev.company,
451
473
  customFields: {
452
474
  ...prev.customFields,
453
475
  ...normalized,
@@ -493,13 +515,16 @@ export default function CustomerCompanyDetailPage({ params }: { params?: { id?:
493
515
  setIsDeleting(true)
494
516
  try {
495
517
  await runMutationWithContext(
496
- () => apiCallOrThrow(
497
- `/api/customers/companies?id=${encodeURIComponent(currentCompanyId)}`,
498
- {
499
- method: 'DELETE',
500
- headers: { 'content-type': 'application/json' },
501
- },
502
- { errorMessage: t('customers.companies.list.deleteError', 'Failed to delete company.') },
518
+ () => withScopedApiRequestHeaders(
519
+ buildOptimisticLockHeader((data?.company as { updatedAt?: string } | undefined)?.updatedAt),
520
+ () => apiCallOrThrow(
521
+ `/api/customers/companies?id=${encodeURIComponent(currentCompanyId)}`,
522
+ {
523
+ method: 'DELETE',
524
+ headers: { 'content-type': 'application/json' },
525
+ },
526
+ { errorMessage: t('customers.companies.list.deleteError', 'Failed to delete company.') },
527
+ ),
503
528
  ),
504
529
  { id: currentCompanyId },
505
530
  )
@@ -448,6 +448,7 @@ export default function CustomersCompaniesPage() {
448
448
  try {
449
449
  await runSingleMutation({
450
450
  operation: async () => {
451
+ // optimistic-lock-exempt: delete-only mutation — no field-level lost-update
451
452
  await apiCallOrThrow(
452
453
  `/api/customers/companies?id=${encodeURIComponent(company.id)}`,
453
454
  {
@@ -487,6 +488,7 @@ export default function CustomersCompaniesPage() {
487
488
  runBulkDelete(
488
489
  selectedRows,
489
490
  async (row) => {
491
+ // optimistic-lock-exempt: bulk delete-only mutation — no field-level lost-update
490
492
  await apiCallOrThrow(`/api/customers/companies?id=${encodeURIComponent(row.id)}`, {
491
493
  method: 'DELETE',
492
494
  headers: { 'content-type': 'application/json' },
@@ -6,8 +6,10 @@ import { useRouter, useSearchParams } from 'next/navigation'
6
6
  import { Page, PageBody } from '@open-mercato/ui/backend/Page'
7
7
  import { Building2, Hash, Users, BarChart3, StickyNote } from 'lucide-react'
8
8
  import { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
9
- import { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
9
+ import { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
10
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
10
11
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
12
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
11
13
  import { useT } from '@open-mercato/shared/lib/i18n/context'
12
14
  import { Button } from '@open-mercato/ui/primitives/button'
13
15
  import { AttachmentsSection, ErrorMessage, LoadingMessage, RecordNotFoundState, type SectionAction } from '@open-mercato/ui/backend/detail'
@@ -204,6 +206,7 @@ export default function CompanyDetailV2Page({ params }: { params?: { id?: string
204
206
  // moment instead of "today" (#1807 prefill).
205
207
  const editPayload = {
206
208
  id: activity.id,
209
+ updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt as string : typeof raw.updated_at === 'string' ? raw.updated_at as string : null,
207
210
  interactionType: typeof activity.interactionType === 'string' ? activity.interactionType : undefined,
208
211
  title: typeof activity.title === 'string' ? activity.title : null,
209
212
  body: typeof activity.body === 'string' ? activity.body : null,
@@ -323,10 +326,28 @@ export default function CompanyDetailV2Page({ params }: { params?: { id?: string
323
326
  variant: 'destructive',
324
327
  })
325
328
  if (!approved) return
326
- await runMutationWithContext(
327
- () => deleteCrud('customers/companies', { id: companyId }),
328
- { id: companyId, operation: 'deleteCompany' },
329
- )
329
+ try {
330
+ await runMutationWithContext(
331
+ () => withScopedApiRequestHeaders(
332
+ buildOptimisticLockHeader((data?.company as { updatedAt?: string } | undefined)?.updatedAt),
333
+ () => deleteCrud('customers/companies', { id: companyId }),
334
+ ),
335
+ { id: companyId, operation: 'deleteCompany' },
336
+ )
337
+ } catch (err) {
338
+ // The guarded mutation already routes a 409 to the unified conflict bar;
339
+ // surface any other server error (e.g. "Cannot delete company: linked
340
+ // deals…") as a flash instead of letting it crash the page.
341
+ if (!surfaceRecordConflict(err, t)) {
342
+ flash(
343
+ err instanceof Error && err.message.trim().length > 0
344
+ ? err.message
345
+ : t('customers.companies.detail.deleteError', 'Failed to delete company.'),
346
+ 'error',
347
+ )
348
+ }
349
+ return
350
+ }
330
351
  flash(t('customers.companies.list.deleteSuccess', 'Company deleted.'), 'success')
331
352
  router.push('/backend/customers/companies')
332
353
  }, [confirm, data?.company?.id, router, runMutationWithContext, t])
@@ -457,6 +478,7 @@ export default function CompanyDetailV2Page({ params }: { params?: { id?: string
457
478
  initialValues={initialValues}
458
479
  onSubmit={handleFormSubmit}
459
480
  onDelete={handleDelete}
481
+ optimisticLockUpdatedAt={(data?.company as { updatedAt?: string } | undefined)?.updatedAt}
460
482
  hideFooterActions
461
483
  collapsibleGroups={{ pageType: 'company-v2', chevronPosition: 'right' }}
462
484
  sortableGroups={{ pageType: 'company-v2' }}
@@ -1,7 +1,10 @@
1
1
  import * as React from 'react'
2
2
  import { useRouter } from 'next/navigation'
3
3
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
4
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
4
5
  import { deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'
6
+ import { withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
7
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
5
8
  import { useT } from '@open-mercato/shared/lib/i18n/context'
6
9
  import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
7
10
  import type { DealFormSubmitPayload } from '../../../../../components/detail/DealForm'
@@ -40,11 +43,23 @@ export function useDealFormHandlers({
40
43
  if (!data) return
41
44
  setIsSaving(true)
42
45
  try {
43
- await updateCrud('customers/deals', {
46
+ const body: Record<string, unknown> = {
44
47
  id: data.deal.id,
45
48
  ...payload.base,
46
- ...payload.custom,
47
- })
49
+ }
50
+ // Custom-field values MUST travel under `customFields` (bare keys). The
51
+ // deal update route's `splitCustomFieldPayload` only routes
52
+ // `customFields`/`customValues`/`cf_`/`cf:` entries to the custom-field
53
+ // writer; spreading bare keys into the body would land them in `base`
54
+ // where `dealUpdateSchema.parse` silently drops them, so edits never
55
+ // persisted (boolean/select/multi all reverted on refresh).
56
+ if (payload.custom && Object.keys(payload.custom).length) {
57
+ body.customFields = payload.custom
58
+ }
59
+ await withScopedApiRequestHeaders(
60
+ buildOptimisticLockHeader(data.deal.updatedAt),
61
+ () => updateCrud('customers/deals', body),
62
+ )
48
63
  flash(t('customers.deals.detail.updateSuccess', 'Deal updated.'), 'success')
49
64
  await loadData()
50
65
  } finally {
@@ -64,10 +79,27 @@ export function useDealFormHandlers({
64
79
  variant: 'destructive',
65
80
  })
66
81
  if (!approved) return
67
- await runMutationWithContext(
68
- () => deleteCrud('customers/deals', currentDealId),
69
- { id: currentDealId, operation: 'deleteDeal' },
70
- )
82
+ try {
83
+ await runMutationWithContext(
84
+ () => withScopedApiRequestHeaders(
85
+ buildOptimisticLockHeader(data.deal.updatedAt),
86
+ () => deleteCrud('customers/deals', currentDealId),
87
+ ),
88
+ { id: currentDealId, operation: 'deleteDeal' },
89
+ )
90
+ } catch (err) {
91
+ // The guarded mutation routes a 409 to the unified conflict bar; surface
92
+ // any other server error as a flash instead of letting it crash the page.
93
+ if (!surfaceRecordConflict(err, t)) {
94
+ flash(
95
+ err instanceof Error && err.message.trim().length > 0
96
+ ? err.message
97
+ : t('customers.deals.detail.deleteError', 'Failed to delete deal.'),
98
+ 'error',
99
+ )
100
+ }
101
+ return
102
+ }
71
103
  flash(t('customers.deals.detail.deleteSuccess', 'Deal deleted.'), 'success')
72
104
  router.push('/backend/customers/deals')
73
105
  }, [confirm, currentDealId, data, router, runMutationWithContext, t])
@@ -228,6 +228,7 @@ export default function DealDetailPage({ params }: { params?: { id?: string } })
228
228
  const rawActivity = activity as unknown as Record<string, unknown>
229
229
  openScheduleEdit({
230
230
  id: activity.id,
231
+ updatedAt: typeof rawActivity.updatedAt === 'string' ? rawActivity.updatedAt as string : typeof rawActivity.updated_at === 'string' ? rawActivity.updated_at as string : null,
231
232
  interactionType: activity.interactionType,
232
233
  title: activity.title ?? null,
233
234
  body: activity.body ?? null,
@@ -11,7 +11,9 @@ import type { AdvancedFilterTree } from '@open-mercato/shared/lib/query/advanced
11
11
  import { createEmptyTree, makeRuleTree, makeMultiRuleTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'
12
12
  import { deserializeTree, deserializeAdvancedFilter, flatToTree, mapDictionaryColorToTone, serializeTree, type FilterFieldDef, type FilterOption as AdvancedFilterOption } from '@open-mercato/shared/lib/query/advanced-filter'
13
13
  import { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'
14
- import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
14
+ import { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
15
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
16
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
15
17
  import { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
16
18
  import { groupBulkDeleteFailures, runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'
17
19
  import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
@@ -447,14 +449,18 @@ export default function CustomersDealsPage() {
447
449
  variant: 'destructive',
448
450
  })
449
451
  if (!confirmed) return
452
+ const lockVersion = rows.find((row) => row.id === dealId)?.updatedAt ?? null
450
453
  setPendingDeleteId(dealId)
451
454
  try {
452
455
  await runSingleMutation({
453
456
  operation: async () => {
454
- await deleteCrud('customers/deals', {
455
- body: { id: dealId },
456
- errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),
457
- })
457
+ await withScopedApiRequestHeaders(
458
+ buildOptimisticLockHeader(lockVersion),
459
+ () => deleteCrud('customers/deals', {
460
+ body: { id: dealId },
461
+ errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),
462
+ }),
463
+ )
458
464
  },
459
465
  context: {
460
466
  formId: singleMutationContextId,
@@ -468,6 +474,12 @@ export default function CustomersDealsPage() {
468
474
  setTotal((prev) => Math.max(0, prev - 1))
469
475
  handleRefresh()
470
476
  } catch (err) {
477
+ // A stale delete surfaces the unified conflict bar (via the guarded
478
+ // mutation) — skip the generic error flash to avoid a double message (#2332).
479
+ if (surfaceRecordConflict(err, t)) {
480
+ handleRefresh()
481
+ return
482
+ }
471
483
  const message =
472
484
  err instanceof Error && err.message
473
485
  ? err.message
@@ -477,7 +489,7 @@ export default function CustomersDealsPage() {
477
489
  setPendingDeleteId(null)
478
490
  }
479
491
  },
480
- [confirm, handleRefresh, pendingDeleteId, retrySingleMutation, runSingleMutation, singleMutationContextId, t],
492
+ [confirm, handleRefresh, pendingDeleteId, retrySingleMutation, rows, runSingleMutation, singleMutationContextId, t],
481
493
  )
482
494
 
483
495
  const handlePageSizeChange = React.useCallback((newSize: number) => {
@@ -41,7 +41,9 @@ import {
41
41
  SelectTrigger,
42
42
  SelectValue,
43
43
  } from '@open-mercato/ui/primitives/select'
44
- import { apiCall, apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
44
+ import { apiCall, apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
45
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
46
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
45
47
  import { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'
46
48
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
47
49
  import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
@@ -1107,22 +1109,29 @@ export default function DealsKanbanPage(): React.ReactElement {
1107
1109
  }
1108
1110
  setPendingDealId(dealId)
1109
1111
 
1112
+ // The moved deal's version, so a concurrent edit/move from another tab is
1113
+ // refused instead of silently overwritten (#2055).
1114
+ const dealVersion = typeof movingItem?.updated_at === 'string' ? movingItem.updated_at : null
1115
+
1110
1116
  runMoveMutation({
1111
1117
  operation: async () => {
1112
- await apiCallOrThrow(
1113
- '/api/customers/deals',
1114
- {
1115
- method: 'PUT',
1116
- headers: { 'content-type': 'application/json' },
1117
- body: JSON.stringify({ id: dealId, pipelineStageId: targetStageId }),
1118
- },
1119
- {
1120
- errorMessage: translateWithFallback(
1121
- t,
1122
- 'customers.deals.pipeline.moveError',
1123
- 'Failed to update deal stage.',
1124
- ),
1125
- },
1118
+ await withScopedApiRequestHeaders(
1119
+ buildOptimisticLockHeader(dealVersion),
1120
+ () => apiCallOrThrow(
1121
+ '/api/customers/deals',
1122
+ {
1123
+ method: 'PUT',
1124
+ headers: { 'content-type': 'application/json' },
1125
+ body: JSON.stringify({ id: dealId, pipelineStageId: targetStageId }),
1126
+ },
1127
+ {
1128
+ errorMessage: translateWithFallback(
1129
+ t,
1130
+ 'customers.deals.pipeline.moveError',
1131
+ 'Failed to update deal stage.',
1132
+ ),
1133
+ },
1134
+ ),
1126
1135
  )
1127
1136
  },
1128
1137
  context: {
@@ -1145,6 +1154,8 @@ export default function DealsKanbanPage(): React.ReactElement {
1145
1154
  }
1146
1155
  // Restore extra-pages cache to pre-move snapshot
1147
1156
  setExtraCardsByStage(extraSnapshot)
1157
+ // A stale move surfaces the unified conflict bar — skip the generic flash.
1158
+ if (surfaceRecordConflict(error, t)) return
1148
1159
  const message =
1149
1160
  error instanceof Error && error.message
1150
1161
  ? error.message
@@ -1740,24 +1751,28 @@ export default function DealsKanbanPage(): React.ReactElement {
1740
1751
 
1741
1752
  const updateDealStatus = React.useCallback(
1742
1753
  async (dealId: string, status: 'win' | 'loose') => {
1754
+ const dealVersion = deals.find((deal) => deal.id === dealId)?.updatedAt ?? null
1743
1755
  setPendingDealId(dealId)
1744
1756
  try {
1745
1757
  await runDealMutation({
1746
1758
  operation: async () => {
1747
- await apiCallOrThrow(
1748
- '/api/customers/deals',
1749
- {
1750
- method: 'PUT',
1751
- headers: { 'content-type': 'application/json' },
1752
- body: JSON.stringify({ id: dealId, status }),
1753
- },
1754
- {
1755
- errorMessage: translateWithFallback(
1756
- t,
1757
- 'customers.deals.kanban.menu.error.status',
1758
- 'Failed to update deal status.',
1759
- ),
1760
- },
1759
+ await withScopedApiRequestHeaders(
1760
+ buildOptimisticLockHeader(dealVersion),
1761
+ () => apiCallOrThrow(
1762
+ '/api/customers/deals',
1763
+ {
1764
+ method: 'PUT',
1765
+ headers: { 'content-type': 'application/json' },
1766
+ body: JSON.stringify({ id: dealId, status }),
1767
+ },
1768
+ {
1769
+ errorMessage: translateWithFallback(
1770
+ t,
1771
+ 'customers.deals.kanban.menu.error.status',
1772
+ 'Failed to update deal status.',
1773
+ ),
1774
+ },
1775
+ ),
1761
1776
  )
1762
1777
  },
1763
1778
  context: {
@@ -1783,6 +1798,7 @@ export default function DealsKanbanPage(): React.ReactElement {
1783
1798
  )
1784
1799
  invalidateKanbanData()
1785
1800
  } catch (error) {
1801
+ if (surfaceRecordConflict(error, t)) { invalidateKanbanData(); return }
1786
1802
  const message =
1787
1803
  error instanceof Error && error.message
1788
1804
  ? error.message
@@ -1796,7 +1812,7 @@ export default function DealsKanbanPage(): React.ReactElement {
1796
1812
  setPendingDealId(null)
1797
1813
  }
1798
1814
  },
1799
- [invalidateKanbanData, retryDealMutation, runDealMutation, t],
1815
+ [deals, invalidateKanbanData, retryDealMutation, runDealMutation, t],
1800
1816
  )
1801
1817
 
1802
1818
  const deleteDeal = React.useCallback(
@@ -1818,18 +1834,22 @@ export default function DealsKanbanPage(): React.ReactElement {
1818
1834
  })
1819
1835
  if (!confirmed) return
1820
1836
 
1837
+ const lockVersion = deals.find((deal) => deal.id === dealId)?.updatedAt ?? null
1821
1838
  setPendingDealId(dealId)
1822
1839
  try {
1823
1840
  await runDealMutation({
1824
1841
  operation: async () => {
1825
- await deleteCrud('customers/deals', {
1826
- body: { id: dealId },
1827
- errorMessage: translateWithFallback(
1828
- t,
1829
- 'customers.deals.kanban.menu.delete.error',
1830
- 'Failed to delete deal.',
1831
- ),
1832
- })
1842
+ await withScopedApiRequestHeaders(
1843
+ buildOptimisticLockHeader(lockVersion),
1844
+ () => deleteCrud('customers/deals', {
1845
+ body: { id: dealId },
1846
+ errorMessage: translateWithFallback(
1847
+ t,
1848
+ 'customers.deals.kanban.menu.delete.error',
1849
+ 'Failed to delete deal.',
1850
+ ),
1851
+ }),
1852
+ )
1833
1853
  },
1834
1854
  context: {
1835
1855
  formId: dealMutationContextId,
@@ -1844,6 +1864,11 @@ export default function DealsKanbanPage(): React.ReactElement {
1844
1864
  )
1845
1865
  invalidateKanbanData()
1846
1866
  } catch (error) {
1867
+ // A stale delete surfaces the unified conflict bar — skip the generic flash (#2332).
1868
+ if (surfaceRecordConflict(error, t)) {
1869
+ invalidateKanbanData()
1870
+ return
1871
+ }
1847
1872
  const message =
1848
1873
  error instanceof Error && error.message
1849
1874
  ? error.message
@@ -1857,7 +1882,7 @@ export default function DealsKanbanPage(): React.ReactElement {
1857
1882
  setPendingDealId(null)
1858
1883
  }
1859
1884
  },
1860
- [confirm, invalidateKanbanData, retryDealMutation, runDealMutation, t],
1885
+ [confirm, deals, invalidateKanbanData, retryDealMutation, runDealMutation, t],
1861
1886
  )
1862
1887
 
1863
1888
  const bulkSelectionSummary = React.useMemo(() => {