@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
@@ -13,7 +13,8 @@ import {
13
13
  DialogTitle,
14
14
  } from '@open-mercato/ui/primitives/dialog'
15
15
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
16
- import { apiCall, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
16
+ import { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
17
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
17
18
  import { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'
18
19
  import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
19
20
  import { useT } from '@open-mercato/shared/lib/i18n/context'
@@ -40,6 +41,7 @@ type Pipeline = {
40
41
  isDefault: boolean
41
42
  organizationId: string
42
43
  tenantId: string
44
+ updatedAt?: string | null
43
45
  }
44
46
 
45
47
  type PipelineStage = {
@@ -49,6 +51,7 @@ type PipelineStage = {
49
51
  order: number
50
52
  color: string | null
51
53
  icon: string | null
54
+ updatedAt?: string | null
52
55
  }
53
56
 
54
57
  type PipelineDialogState =
@@ -66,6 +69,7 @@ function normalizePipeline(raw: Record<string, unknown>): Pipeline {
66
69
  isDefault: raw.isDefault === true || raw.is_default === true,
67
70
  organizationId: typeof raw.organizationId === 'string' ? raw.organizationId : (typeof raw.organization_id === 'string' ? raw.organization_id : ''),
68
71
  tenantId: typeof raw.tenantId === 'string' ? raw.tenantId : (typeof raw.tenant_id === 'string' ? raw.tenant_id : ''),
72
+ updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt : (typeof raw.updated_at === 'string' ? raw.updated_at : null),
69
73
  }
70
74
  }
71
75
 
@@ -77,6 +81,7 @@ function normalizeStage(raw: Record<string, unknown>): PipelineStage {
77
81
  order: typeof raw.order === 'number' ? raw.order : 0,
78
82
  color: typeof raw.color === 'string' && raw.color.trim().length ? raw.color.trim() : null,
79
83
  icon: typeof raw.icon === 'string' && raw.icon.trim().length ? raw.icon.trim() : null,
84
+ updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt : (typeof raw.updated_at === 'string' ? raw.updated_at : null),
80
85
  }
81
86
  }
82
87
 
@@ -171,11 +176,15 @@ export default function PipelineSettings(): React.ReactElement {
171
176
  }
172
177
  flash(t('customers.pipelines.flash.created', 'Pipeline created'), 'success')
173
178
  } else if (pipelineDialog?.mode === 'edit') {
174
- const res = await apiCall('/api/customers/pipelines', {
175
- method: 'PUT',
176
- headers: { 'content-type': 'application/json' },
177
- body: JSON.stringify({ id: pipelineDialog.entry.id, name: pipelineForm.name.trim(), isDefault: pipelineForm.isDefault }),
178
- })
179
+ const res = await withScopedApiRequestHeaders(
180
+ buildOptimisticLockHeader(pipelineDialog.entry.updatedAt),
181
+ () =>
182
+ apiCall('/api/customers/pipelines', {
183
+ method: 'PUT',
184
+ headers: { 'content-type': 'application/json' },
185
+ body: JSON.stringify({ id: pipelineDialog.entry.id, name: pipelineForm.name.trim(), isDefault: pipelineForm.isDefault }),
186
+ }),
187
+ )
179
188
  if (!res.ok) {
180
189
  await raiseCrudError(res.response, t('customers.pipelines.errors.updateFailed', 'Failed to update pipeline'))
181
190
  return
@@ -197,11 +206,15 @@ export default function PipelineSettings(): React.ReactElement {
197
206
  variant: 'destructive',
198
207
  })
199
208
  if (!confirmed) return
200
- const res = await apiCall('/api/customers/pipelines', {
201
- method: 'DELETE',
202
- headers: { 'content-type': 'application/json' },
203
- body: JSON.stringify({ id: pipeline.id }),
204
- })
209
+ const res = await withScopedApiRequestHeaders(
210
+ buildOptimisticLockHeader(pipeline.updatedAt),
211
+ () =>
212
+ apiCall('/api/customers/pipelines', {
213
+ method: 'DELETE',
214
+ headers: { 'content-type': 'application/json' },
215
+ body: JSON.stringify({ id: pipeline.id }),
216
+ }),
217
+ )
205
218
  if (!res.ok) {
206
219
  const body = (res.result ?? {}) as Record<string, unknown>
207
220
  const msg = typeof body.error === 'string' ? body.error : t('customers.pipelines.errors.deleteFailed', 'Failed to delete pipeline')
@@ -248,11 +261,15 @@ export default function PipelineSettings(): React.ReactElement {
248
261
  flash(t('customers.pipelines.flash.stageCreated', 'Stage created'), 'success')
249
262
  await loadStages(stageDialog.pipelineId)
250
263
  } else if (stageDialog?.mode === 'edit') {
251
- const res = await apiCall('/api/customers/pipeline-stages', {
252
- method: 'PUT',
253
- headers: { 'content-type': 'application/json' },
254
- body: JSON.stringify({ id: stageDialog.entry.id, label: stageForm.label.trim(), ...appearance }),
255
- })
264
+ const res = await withScopedApiRequestHeaders(
265
+ buildOptimisticLockHeader(stageDialog.entry.updatedAt),
266
+ () =>
267
+ apiCall('/api/customers/pipeline-stages', {
268
+ method: 'PUT',
269
+ headers: { 'content-type': 'application/json' },
270
+ body: JSON.stringify({ id: stageDialog.entry.id, label: stageForm.label.trim(), ...appearance }),
271
+ }),
272
+ )
256
273
  if (!res.ok) {
257
274
  await raiseCrudError(res.response, t('customers.pipelines.errors.stageUpdateFailed', 'Failed to update stage'))
258
275
  return
@@ -274,11 +291,15 @@ export default function PipelineSettings(): React.ReactElement {
274
291
  variant: 'destructive',
275
292
  })
276
293
  if (!confirmed) return
277
- const res = await apiCall('/api/customers/pipeline-stages', {
278
- method: 'DELETE',
279
- headers: { 'content-type': 'application/json' },
280
- body: JSON.stringify({ id: stage.id }),
281
- })
294
+ const res = await withScopedApiRequestHeaders(
295
+ buildOptimisticLockHeader(stage.updatedAt),
296
+ () =>
297
+ apiCall('/api/customers/pipeline-stages', {
298
+ method: 'DELETE',
299
+ headers: { 'content-type': 'application/json' },
300
+ body: JSON.stringify({ id: stage.id }),
301
+ }),
302
+ )
282
303
  if (!res.ok) {
283
304
  const body = (res.result ?? {}) as Record<string, unknown>
284
305
  const msg = typeof body.error === 'string' ? body.error : t('customers.pipelines.errors.stageDeleteFailed', 'Failed to delete stage')
@@ -18,7 +18,7 @@ const TYPE_ICONS: Record<string, React.ComponentType<{ className?: string }>> =
18
18
  interface ActivityTimelineProps {
19
19
  activities: InteractionSummary[]
20
20
  onEdit?: (activity: InteractionSummary) => void
21
- onMarkDone?: (activityId: string) => void | Promise<void>
21
+ onMarkDone?: (activityId: string, updatedAt?: string | null) => void | Promise<void>
22
22
  }
23
23
 
24
24
  export function ActivityTimeline({ activities, onEdit, onMarkDone }: ActivityTimelineProps) {
@@ -77,7 +77,7 @@ function TimelineEntry({
77
77
  t: TranslateFn
78
78
  withBorder: boolean
79
79
  onEdit?: (activity: InteractionSummary) => void
80
- onMarkDone?: (activityId: string) => void | Promise<void>
80
+ onMarkDone?: (activityId: string, updatedAt?: string | null) => void | Promise<void>
81
81
  }) {
82
82
  const dateStr = activity.scheduledAt ?? activity.occurredAt ?? activity.createdAt
83
83
  const TypeIcon = TYPE_ICONS[activity.interactionType]
@@ -91,7 +91,7 @@ function TimelineEntry({
91
91
  if (!onMarkDone || markingDone) return
92
92
  setMarkingDone(true)
93
93
  try {
94
- await onMarkDone(activity.id)
94
+ await onMarkDone(activity.id, activity.updatedAt)
95
95
  } finally {
96
96
  setMarkingDone(false)
97
97
  }
@@ -107,6 +107,7 @@ export function AddressesSection({
107
107
  const response = await apiCallOrThrow<Record<string, unknown>>(
108
108
  '/api/customers/addresses',
109
109
  {
110
+ // optimistic-lock-exempt: address link add/remove sub-resource
110
111
  method: 'POST',
111
112
  headers: { 'content-type': 'application/json' },
112
113
  body: JSON.stringify({
@@ -123,6 +124,7 @@ export function AddressesSection({
123
124
  await apiCallOrThrow(
124
125
  '/api/customers/addresses',
125
126
  {
127
+ // optimistic-lock-exempt: address link add/remove sub-resource
126
128
  method: 'PUT',
127
129
  headers: { 'content-type': 'application/json' },
128
130
  body: JSON.stringify({
@@ -138,6 +140,7 @@ export function AddressesSection({
138
140
  await apiCallOrThrow(
139
141
  '/api/customers/addresses',
140
142
  {
143
+ // optimistic-lock-exempt: address link add/remove sub-resource
141
144
  method: 'DELETE',
142
145
  headers: { 'content-type': 'application/json' },
143
146
  body: JSON.stringify({ id }),
@@ -170,6 +173,7 @@ export function AddressesSection({
170
173
  const response = await apiCallOrThrow<Record<string, unknown>>(
171
174
  '/api/customers/dictionaries/address-types',
172
175
  {
176
+ // optimistic-lock-exempt: address-type dictionary create-only
173
177
  method: 'POST',
174
178
  headers: { 'content-type': 'application/json' },
175
179
  body: JSON.stringify({ value }),
@@ -360,6 +360,7 @@ export function CompanyPeopleSection({
360
360
  for (const personId of addedIds) {
361
361
  await runWriteMutation(
362
362
  () =>
363
+ // optimistic-lock-exempt: person-company link add/remove
363
364
  apiCallOrThrow(
364
365
  `/api/customers/people/${encodeURIComponent(personId)}/companies`,
365
366
  {
@@ -514,6 +515,7 @@ export function CompanyPeopleSection({
514
515
  try {
515
516
  await runWriteMutation(
516
517
  () =>
518
+ // optimistic-lock-exempt: person-company link add/remove
517
519
  apiCallOrThrow(
518
520
  `/api/customers/people/${encodeURIComponent(personId)}/companies/${encodeURIComponent(companyId)}`,
519
521
  { method: 'DELETE' },
@@ -651,6 +651,7 @@ export function DealsSection({
651
651
  : currentCompanyIds
652
652
  await runWriteMutation(
653
653
  () =>
654
+ // optimistic-lock-exempt: deal association list (link)
654
655
  updateCrud(
655
656
  'customers/deals',
656
657
  { id: dealId, personIds: nextPersonIds, companyIds: nextCompanyIds },
@@ -684,6 +685,7 @@ export function DealsSection({
684
685
  : currentCompanyIds
685
686
  await runWriteMutation(
686
687
  () =>
688
+ // optimistic-lock-exempt: deal association list (unlink)
687
689
  updateCrud(
688
690
  'customers/deals',
689
691
  { id: dealId, personIds: nextPersonIds, companyIds: nextCompanyIds },
@@ -762,6 +764,7 @@ export function DealsSection({
762
764
  if (Object.keys(custom).length) payload.customFields = custom
763
765
  const { result } = await runWriteMutation(
764
766
  () =>
767
+ // optimistic-lock-exempt: deal create-only, no prior version
765
768
  createCrud<{ id?: string }>('customers/deals', payload, {
766
769
  errorMessage: translate('customers.people.detail.deals.error', 'Failed to save deal.'),
767
770
  }),
@@ -848,6 +851,7 @@ export function DealsSection({
848
851
  }
849
852
  await runWriteMutation(
850
853
  () =>
854
+ // optimistic-lock-exempt: deal association list (unlink)
851
855
  updateCrud('customers/deals', payload, {
852
856
  errorMessage: translate('customers.people.detail.deals.unlinkError', 'Failed to unlink deal.'),
853
857
  }),
@@ -190,6 +190,11 @@ export function EmailCardActions({ data }: EmailCardActionsProps) {
190
190
  const next = data.currentVisibility === 'private' ? 'shared' : 'private'
191
191
  try {
192
192
  await runMutation({
193
+ // optimistic-lock-exempt: dedicated single-field visibility
194
+ // action endpoint (shared/private toggle), not a full-record
195
+ // edit. The canonical interaction edit/delete is version-locked
196
+ // at the command layer (customers.interactions.* commands); this
197
+ // idempotent toggle derives `next` from freshly-loaded state.
193
198
  operation: async () => {
194
199
  const r = await apiCall<{ ok?: boolean }>(
195
200
  `/api/customers/interactions/${interactionId}/visibility`,
@@ -854,6 +854,7 @@ export function EntityTagsDialog({
854
854
  readApiResultOrThrow<Record<string, unknown>>(
855
855
  '/api/customers/tags',
856
856
  {
857
+ // optimistic-lock-exempt: tag dictionary create-only
857
858
  method: 'POST',
858
859
  headers: { 'content-type': 'application/json' },
859
860
  body: JSON.stringify({
@@ -892,6 +893,7 @@ export function EntityTagsDialog({
892
893
  readApiResultOrThrow<{ id: string; slug: string; label: string }>(
893
894
  '/api/customers/labels',
894
895
  {
896
+ // optimistic-lock-exempt: label dictionary create-only
895
897
  method: 'POST',
896
898
  headers: { 'content-type': 'application/json' },
897
899
  body: JSON.stringify(payload),
@@ -956,6 +958,7 @@ export function EntityTagsDialog({
956
958
  await runGuardedMutation(
957
959
  () =>
958
960
  apiCallOrThrow(`/api/customers/${entityType === 'person' ? 'people' : 'companies'}`, {
961
+ // optimistic-lock-exempt: tag/label dictionary + custom-field selection write (assignment add/remove)
959
962
  method: 'PUT',
960
963
  headers: { 'content-type': 'application/json' },
961
964
  body: JSON.stringify({
@@ -984,6 +987,7 @@ export function EntityTagsDialog({
984
987
  await runGuardedMutation(
985
988
  () =>
986
989
  apiCallOrThrow('/api/customers/tags/assign', {
990
+ // optimistic-lock-exempt: tag assignment add/remove
987
991
  method: 'POST',
988
992
  headers: { 'content-type': 'application/json' },
989
993
  body: JSON.stringify({ tagId, entityId }),
@@ -996,6 +1000,7 @@ export function EntityTagsDialog({
996
1000
  await runGuardedMutation(
997
1001
  () =>
998
1002
  apiCallOrThrow('/api/customers/tags/unassign', {
1003
+ // optimistic-lock-exempt: tag assignment add/remove
999
1004
  method: 'POST',
1000
1005
  headers: { 'content-type': 'application/json' },
1001
1006
  body: JSON.stringify({ tagId, entityId }),
@@ -1016,6 +1021,7 @@ export function EntityTagsDialog({
1016
1021
  await runGuardedMutation(
1017
1022
  () =>
1018
1023
  apiCallOrThrow('/api/customers/labels/assign', {
1024
+ // optimistic-lock-exempt: label assignment add/remove
1019
1025
  method: 'POST',
1020
1026
  headers: { 'content-type': 'application/json' },
1021
1027
  body: JSON.stringify(payload),
@@ -1031,6 +1037,7 @@ export function EntityTagsDialog({
1031
1037
  await runGuardedMutation(
1032
1038
  () =>
1033
1039
  apiCallOrThrow('/api/customers/labels/unassign', {
1040
+ // optimistic-lock-exempt: label assignment add/remove
1034
1041
  method: 'POST',
1035
1042
  headers: { 'content-type': 'application/json' },
1036
1043
  body: JSON.stringify(payload),
@@ -760,6 +760,7 @@ export function ManageTagsDialog({ open, onClose }: ManageTagsDialogProps) {
760
760
  if (entry.id) {
761
761
  await runGuardedMutation(
762
762
  () =>
763
+ // optimistic-lock-exempt: tag dictionary entry assignment add/remove
763
764
  apiCallOrThrow(`/api/customers/dictionaries/${category.kind}/${entry.id}`, {
764
765
  method: 'DELETE',
765
766
  }),
@@ -779,6 +780,7 @@ export function ManageTagsDialog({ open, onClose }: ManageTagsDialogProps) {
779
780
  if (!entry.id) {
780
781
  await runGuardedMutation(
781
782
  () =>
783
+ // optimistic-lock-exempt: tag dictionary entry create-only
782
784
  apiCallOrThrow(`/api/customers/dictionaries/${category.kind}`, {
783
785
  method: 'POST',
784
786
  headers: { 'content-type': 'application/json' },
@@ -805,6 +807,7 @@ export function ManageTagsDialog({ open, onClose }: ManageTagsDialogProps) {
805
807
 
806
808
  await runGuardedMutation(
807
809
  () =>
810
+ // optimistic-lock-exempt: tag dictionary entry assignment add/remove
808
811
  apiCallOrThrow(`/api/customers/dictionaries/${category.kind}/${entry.id}`, {
809
812
  method: 'PATCH',
810
813
  headers: { 'content-type': 'application/json' },
@@ -891,6 +894,7 @@ export function ManageTagsDialog({ open, onClose }: ManageTagsDialogProps) {
891
894
  try {
892
895
  await runGuardedMutation(
893
896
  () =>
897
+ // optimistic-lock-exempt: tag dictionary kind-settings assignment add/remove
894
898
  apiCallOrThrow('/api/customers/dictionaries/kind-settings', {
895
899
  method: 'PATCH',
896
900
  headers: { 'content-type': 'application/json' },
@@ -238,6 +238,7 @@ export function PersonCompaniesSection({
238
238
  for (const companyId of removedIds) {
239
239
  await runWriteMutation(
240
240
  () =>
241
+ // optimistic-lock-exempt: person-company link add/remove
241
242
  apiCallOrThrow(
242
243
  `/api/customers/people/${encodeURIComponent(personId)}/companies/${encodeURIComponent(companyId)}`,
243
244
  { method: 'DELETE' },
@@ -249,6 +250,7 @@ export function PersonCompaniesSection({
249
250
  for (const companyId of addedIds) {
250
251
  await runWriteMutation(
251
252
  () =>
253
+ // optimistic-lock-exempt: person-company link add/remove
252
254
  apiCallOrThrow(
253
255
  `/api/customers/people/${encodeURIComponent(personId)}/companies`,
254
256
  {
@@ -271,6 +273,7 @@ export function PersonCompaniesSection({
271
273
  ) {
272
274
  await runWriteMutation(
273
275
  () =>
276
+ // optimistic-lock-exempt: person-company link set-primary (add/remove)
274
277
  apiCallOrThrow(
275
278
  `/api/customers/people/${encodeURIComponent(personId)}/companies/${encodeURIComponent(nextPrimaryId)}`,
276
279
  {
@@ -332,6 +335,7 @@ export function PersonCompaniesSection({
332
335
  try {
333
336
  await runWriteMutation(
334
337
  () =>
338
+ // optimistic-lock-exempt: person-company link add/remove
335
339
  apiCallOrThrow(
336
340
  `/api/customers/people/${encodeURIComponent(personId)}/companies/${encodeURIComponent(companyId)}`,
337
341
  { method: 'DELETE' },
@@ -82,6 +82,7 @@ export function RoleAssignmentRow({
82
82
  try {
83
83
  await runMutationWithContext(
84
84
  () =>
85
+ // optimistic-lock-exempt: role assignment add/remove
85
86
  apiCallOrThrow(`/api/customers/${basePath}/${entityId}/roles?roleId=${role.id}`, {
86
87
  method: 'PUT',
87
88
  headers: { 'content-type': 'application/json' },
@@ -110,6 +111,7 @@ export function RoleAssignmentRow({
110
111
  try {
111
112
  await runMutationWithContext(
112
113
  () =>
114
+ // optimistic-lock-exempt: role assignment add/remove
113
115
  apiCallOrThrow(`/api/customers/${basePath}/${entityId}/roles?roleId=${role.id}`, {
114
116
  method: 'DELETE',
115
117
  }),
@@ -5,7 +5,8 @@ import { Users, Phone, Check, Mail, Calendar, AlertTriangle, X, StickyNote } fro
5
5
  import { cn } from '@open-mercato/shared/lib/utils'
6
6
  import { useT } from '@open-mercato/shared/lib/i18n/context'
7
7
  import { validatePhoneNumber } from '@open-mercato/shared/lib/phone'
8
- import { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
8
+ import { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
9
+ import { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'
9
10
  import { mapCrudServerErrorToFormErrors } from '@open-mercato/ui/backend/utils/serverErrors'
10
11
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
11
12
  import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
@@ -411,12 +412,19 @@ export function ScheduleActivityDialog({
411
412
  ...(Object.keys(customValues).length > 0 ? { customValues } : {}),
412
413
  }
413
414
  await runGuardedMutation(
414
- () =>
415
- apiCallOrThrow('/api/customers/interactions', {
416
- method: isSaveEdit ? 'PUT' : 'POST',
417
- headers: { 'content-type': 'application/json' },
418
- body: JSON.stringify(payload),
419
- }),
415
+ () => {
416
+ const call = () =>
417
+ apiCallOrThrow('/api/customers/interactions', {
418
+ method: isSaveEdit ? 'PUT' : 'POST',
419
+ headers: { 'content-type': 'application/json' },
420
+ body: JSON.stringify(payload),
421
+ })
422
+ // Optimistic lock only applies to edits — a stale modal save against a
423
+ // concurrently changed/deleted activity surfaces the conflict bar (#2055).
424
+ return isSaveEdit
425
+ ? withScopedApiRequestHeaders(buildOptimisticLockHeader(editData?.updatedAt), call)
426
+ : call()
427
+ },
420
428
  {
421
429
  operation: isSaveEdit ? 'updateActivity' : 'createActivity',
422
430
  interactionId: editData?.id ?? null,
@@ -428,6 +436,14 @@ export function ScheduleActivityDialog({
428
436
  // Delay data reload so the dialog can unmount cleanly and Radix restores body scroll
429
437
  requestAnimationFrame(() => { onActivityCreated?.() })
430
438
  } catch (err) {
439
+ // An optimistic-lock 409 was already surfaced as the persistent conflict
440
+ // bar by `runGuardedMutation` (useGuardedMutation → surfaceRecordConflict).
441
+ // Do NOT additionally flash the raw `record_modified` code here — that
442
+ // showed an untranslated toast on top of the localized bar (#2055 QA).
443
+ if (extractOptimisticLockConflict(err)) {
444
+ onClose()
445
+ return
446
+ }
431
447
  const { message, fieldErrors } = mapCrudServerErrorToFormErrors(err)
432
448
  const phoneFieldError = fieldErrors?.phoneNumber
433
449
  if (state.activityType === 'call' && phoneFieldError) {
@@ -2,7 +2,9 @@
2
2
 
3
3
  import * as React from 'react'
4
4
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
5
- import { apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
5
+ import { apiCallOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
6
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
7
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
6
8
  import { useT } from '@open-mercato/shared/lib/i18n/context'
7
9
 
8
10
  export type GuardedMutationRunner = <T>(
@@ -18,8 +20,8 @@ export type UseInteractionMutationsOptions = {
18
20
  }
19
21
 
20
22
  export type UseInteractionMutationsResult = {
21
- completeInteraction: (interactionId: string) => Promise<void>
22
- cancelInteraction: (interactionId: string) => Promise<void>
23
+ completeInteraction: (interactionId: string, updatedAt?: string | null) => Promise<void>
24
+ cancelInteraction: (interactionId: string, updatedAt?: string | null) => Promise<void>
23
25
  }
24
26
 
25
27
  /**
@@ -44,20 +46,24 @@ export function useInteractionMutations({
44
46
  }, [logContext, onAfterChange])
45
47
 
46
48
  const completeInteraction = React.useCallback(
47
- async (interactionId: string) => {
49
+ async (interactionId: string, updatedAt?: string | null) => {
48
50
  try {
49
51
  await runMutationWithContext(
50
52
  () =>
51
- apiCallOrThrow('/api/customers/interactions/complete', {
52
- method: 'POST',
53
- headers: { 'content-type': 'application/json' },
54
- body: JSON.stringify({ id: interactionId, occurredAt: new Date().toISOString() }),
55
- }),
53
+ withScopedApiRequestHeaders(
54
+ buildOptimisticLockHeader(updatedAt ?? null),
55
+ () => apiCallOrThrow('/api/customers/interactions/complete', {
56
+ method: 'POST',
57
+ headers: { 'content-type': 'application/json' },
58
+ body: JSON.stringify({ id: interactionId, occurredAt: new Date().toISOString() }),
59
+ }),
60
+ ),
56
61
  { id: interactionId, status: 'done', operation: 'completeActivity' },
57
62
  )
58
63
  flash(t('customers.timeline.planned.completed', 'Activity completed'), 'success')
59
64
  await triggerRefresh()
60
65
  } catch (err) {
66
+ if (surfaceRecordConflict(err, t)) { await triggerRefresh(); return }
61
67
  console.warn(`[${logContext}] complete interaction failed`, interactionId, err)
62
68
  flash(t('customers.timeline.planned.error', 'Failed to complete activity'), 'error')
63
69
  }
@@ -66,20 +72,24 @@ export function useInteractionMutations({
66
72
  )
67
73
 
68
74
  const cancelInteraction = React.useCallback(
69
- async (interactionId: string) => {
75
+ async (interactionId: string, updatedAt?: string | null) => {
70
76
  try {
71
77
  await runMutationWithContext(
72
78
  () =>
73
- apiCallOrThrow('/api/customers/interactions', {
74
- method: 'PUT',
75
- headers: { 'content-type': 'application/json' },
76
- body: JSON.stringify({ id: interactionId, status: 'canceled' }),
77
- }),
79
+ withScopedApiRequestHeaders(
80
+ buildOptimisticLockHeader(updatedAt ?? null),
81
+ () => apiCallOrThrow('/api/customers/interactions', {
82
+ method: 'PUT',
83
+ headers: { 'content-type': 'application/json' },
84
+ body: JSON.stringify({ id: interactionId, status: 'canceled' }),
85
+ }),
86
+ ),
78
87
  { id: interactionId, status: 'canceled', operation: 'cancelActivity' },
79
88
  )
80
89
  flash(t('customers.timeline.planned.canceled', 'Activity canceled'), 'success')
81
90
  await triggerRefresh()
82
91
  } catch (err) {
92
+ if (surfaceRecordConflict(err, t)) { await triggerRefresh(); return }
83
93
  console.warn(`[${logContext}] cancel interaction failed`, interactionId, err)
84
94
  flash(t('customers.timeline.planned.cancelError', 'Failed to cancel activity'), 'error')
85
95
  }