@open-mercato/core 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4544.1.71c003c861

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 (633) 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/optimisticLockUi.js +104 -0
  10. package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
  11. package/dist/helpers/integration/salesFixtures.js +17 -0
  12. package/dist/helpers/integration/salesFixtures.js.map +2 -2
  13. package/dist/modules/api_keys/backend/api-keys/page.js +9 -5
  14. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  15. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
  16. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  17. package/dist/modules/auth/api/roles/acl/route.js +32 -13
  18. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  19. package/dist/modules/auth/api/roles/route.js +3 -1
  20. package/dist/modules/auth/api/roles/route.js.map +2 -2
  21. package/dist/modules/auth/api/sidebar/preferences/route.js +71 -3
  22. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  23. package/dist/modules/auth/api/users/acl/route.js +42 -19
  24. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  25. package/dist/modules/auth/api/users/route.js +3 -1
  26. package/dist/modules/auth/api/users/route.js.map +2 -2
  27. package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
  28. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  29. package/dist/modules/auth/backend/roles/page.js +8 -4
  30. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  31. package/dist/modules/auth/backend/users/[id]/edit/page.js +27 -5
  32. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  33. package/dist/modules/auth/backend/users/page.js +6 -2
  34. package/dist/modules/auth/backend/users/page.js.map +2 -2
  35. package/dist/modules/auth/components/AclEditor.js +3 -1
  36. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  37. package/dist/modules/auth/data/entities.js +6 -0
  38. package/dist/modules/auth/data/entities.js.map +2 -2
  39. package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
  40. package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
  41. package/dist/modules/business_rules/api/rules/route.js +28 -0
  42. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  43. package/dist/modules/business_rules/api/sets/route.js +28 -0
  44. package/dist/modules/business_rules/api/sets/route.js.map +2 -2
  45. package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
  46. package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
  47. package/dist/modules/business_rules/backend/rules/page.js +20 -11
  48. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  49. package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
  50. package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
  51. package/dist/modules/business_rules/backend/sets/page.js +20 -11
  52. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  53. package/dist/modules/catalog/api/categories/route.js +2 -0
  54. package/dist/modules/catalog/api/categories/route.js.map +2 -2
  55. package/dist/modules/catalog/api/products/route.js +2 -1
  56. package/dist/modules/catalog/api/products/route.js.map +2 -2
  57. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
  58. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
  59. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +94 -40
  60. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  61. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +37 -8
  62. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  63. package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
  64. package/dist/modules/catalog/commands/variants.js +32 -31
  65. package/dist/modules/catalog/commands/variants.js.map +2 -2
  66. package/dist/modules/catalog/components/PriceKindSettings.js +12 -5
  67. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  68. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  69. package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
  70. package/dist/modules/catalog/components/products/ProductsDataTable.js +5 -3
  71. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  72. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  73. package/dist/modules/catalog/components/products/variantForm.js +2 -1
  74. package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
  75. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +5 -0
  76. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
  77. package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
  78. package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
  79. package/dist/modules/currencies/backend/currencies/page.js +18 -11
  80. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  81. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
  82. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
  83. package/dist/modules/currencies/backend/exchange-rates/page.js +10 -6
  84. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  85. package/dist/modules/currencies/commands/currencies.js +7 -5
  86. package/dist/modules/currencies/commands/currencies.js.map +2 -2
  87. package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
  88. package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
  89. package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
  90. package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
  91. package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
  92. package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
  93. package/dist/modules/customer_accounts/api/admin/users/[id].js +28 -5
  94. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
  95. package/dist/modules/customer_accounts/api/admin/users.js +2 -0
  96. package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
  97. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
  98. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
  99. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +8 -4
  100. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  101. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
  102. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
  103. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
  104. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  105. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +18 -11
  106. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  107. package/dist/modules/customers/api/companies/route.js +13 -2
  108. package/dist/modules/customers/api/companies/route.js.map +2 -2
  109. package/dist/modules/customers/api/deals/route.js +2 -0
  110. package/dist/modules/customers/api/deals/route.js.map +2 -2
  111. package/dist/modules/customers/api/people/route.js +11 -2
  112. package/dist/modules/customers/api/people/route.js.map +2 -2
  113. package/dist/modules/customers/api/todos/route.js +1 -0
  114. package/dist/modules/customers/api/todos/route.js.map +2 -2
  115. package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
  116. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
  117. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  118. package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
  119. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  120. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  121. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
  122. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  123. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
  124. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
  125. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
  126. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  127. package/dist/modules/customers/backend/customers/deals/page.js +16 -6
  128. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  129. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
  130. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  131. package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
  132. package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
  133. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  134. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +50 -23
  135. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  136. package/dist/modules/customers/commands/addresses.js +16 -14
  137. package/dist/modules/customers/commands/addresses.js.map +2 -2
  138. package/dist/modules/customers/commands/companies.js +1 -1
  139. package/dist/modules/customers/commands/companies.js.map +2 -2
  140. package/dist/modules/customers/commands/interactions.js +41 -4
  141. package/dist/modules/customers/commands/interactions.js.map +2 -2
  142. package/dist/modules/customers/commands/people.js +1 -1
  143. package/dist/modules/customers/commands/people.js.map +2 -2
  144. package/dist/modules/customers/commands/personCompanyLinks.js +8 -5
  145. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  146. package/dist/modules/customers/commands/pipeline-stages.js +13 -11
  147. package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
  148. package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
  149. package/dist/modules/customers/components/DictionarySettings.js +20 -13
  150. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  151. package/dist/modules/customers/components/DictionarySortSettings.js +4 -0
  152. package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
  153. package/dist/modules/customers/components/PipelineSettings.js +38 -23
  154. package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
  155. package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
  156. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
  157. package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
  158. package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
  159. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
  160. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  161. package/dist/modules/customers/components/detail/DealsSection.js +36 -24
  162. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  163. package/dist/modules/customers/components/detail/EmailCardActions.js +5 -0
  164. package/dist/modules/customers/components/detail/EmailCardActions.js.map +2 -2
  165. package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
  166. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  167. package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
  168. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
  169. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
  170. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  171. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
  172. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
  173. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
  174. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  175. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
  176. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
  177. package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
  178. package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
  179. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
  180. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  181. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  182. package/dist/modules/customers/components/formConfig.js.map +2 -2
  183. package/dist/modules/customers/data/guards.js +66 -0
  184. package/dist/modules/customers/data/guards.js.map +7 -0
  185. package/dist/modules/customers/di.js +37 -0
  186. package/dist/modules/customers/di.js.map +2 -2
  187. package/dist/modules/customers/lib/todoCompatibility.js +11 -0
  188. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  189. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  190. package/dist/modules/data_sync/api/options.js +4 -4
  191. package/dist/modules/data_sync/api/options.js.map +2 -2
  192. package/dist/modules/data_sync/api/schedules/route.js +9 -1
  193. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  194. package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
  195. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  196. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
  197. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  198. package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
  199. package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
  200. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
  201. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  202. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +17 -1
  203. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  204. package/dist/modules/dictionaries/components/DictionariesManager.js +31 -10
  205. package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
  206. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +28 -15
  207. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  208. package/dist/modules/directory/api/organizations/route.js +3 -0
  209. package/dist/modules/directory/api/organizations/route.js.map +2 -2
  210. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
  211. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
  212. package/dist/modules/directory/backend/directory/organizations/page.js +9 -5
  213. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  214. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
  215. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
  216. package/dist/modules/directory/backend/directory/tenants/page.js +8 -4
  217. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  218. package/dist/modules/directory/commands/organizations.js +7 -2
  219. package/dist/modules/directory/commands/organizations.js.map +2 -2
  220. package/dist/modules/entities/api/records.js +66 -0
  221. package/dist/modules/entities/api/records.js.map +2 -2
  222. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
  223. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  224. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +8 -4
  225. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  226. package/dist/modules/entities/lib/helpers.js +17 -0
  227. package/dist/modules/entities/lib/helpers.js.map +2 -2
  228. package/dist/modules/feature_toggles/api/global/[id]/override/route.js +2 -1
  229. package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
  230. package/dist/modules/feature_toggles/api/overrides/route.js +15 -0
  231. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  232. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +15 -14
  233. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
  234. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
  235. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
  236. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +6 -2
  237. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  238. package/dist/modules/feature_toggles/components/formConfig.js +2 -1
  239. package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
  240. package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
  241. package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
  242. package/dist/modules/feature_toggles/data/validators.js +7 -4
  243. package/dist/modules/feature_toggles/data/validators.js.map +2 -2
  244. package/dist/modules/inbox_ops/api/settings/route.js +17 -2
  245. package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
  246. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
  247. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
  248. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
  249. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  250. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
  251. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  252. package/dist/modules/integrations/backend/integrations/page.js +12 -8
  253. package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
  254. package/dist/modules/messages/commands/messages.js +13 -10
  255. package/dist/modules/messages/commands/messages.js.map +2 -2
  256. package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
  257. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  258. package/dist/modules/perspectives/services/perspectiveService.js +7 -0
  259. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  260. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
  261. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
  262. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
  263. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  264. package/dist/modules/planner/components/AvailabilityRuleSetForm.js +2 -0
  265. package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
  266. package/dist/modules/planner/components/AvailabilityRulesEditor.js +36 -11
  267. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  268. package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
  269. package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
  270. package/dist/modules/query_index/lib/engine.js +19 -0
  271. package/dist/modules/query_index/lib/engine.js.map +2 -2
  272. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -0
  273. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
  274. package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
  275. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  276. package/dist/modules/resources/backend/resources/resources/[id]/page.js +14 -3
  277. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  278. package/dist/modules/resources/backend/resources/resources/page.js +8 -4
  279. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  280. package/dist/modules/resources/components/ResourceCrudForm.js +2 -0
  281. package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
  282. package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -0
  283. package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
  284. package/dist/modules/sales/api/documents/factory.js +7 -2
  285. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  286. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
  287. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
  288. package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
  289. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  290. package/dist/modules/sales/backend/sales/channels/page.js +16 -4
  291. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  292. package/dist/modules/sales/backend/sales/documents/[id]/page.js +68 -22
  293. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  294. package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
  295. package/dist/modules/sales/commands/documentAddresses.js +181 -2
  296. package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
  297. package/dist/modules/sales/commands/documents.js +29 -1
  298. package/dist/modules/sales/commands/documents.js.map +2 -2
  299. package/dist/modules/sales/commands/returns.js +12 -2
  300. package/dist/modules/sales/commands/returns.js.map +2 -2
  301. package/dist/modules/sales/commands/shared.js +15 -0
  302. package/dist/modules/sales/commands/shared.js.map +2 -2
  303. package/dist/modules/sales/commands/shipments.js +4 -1
  304. package/dist/modules/sales/commands/shipments.js.map +2 -2
  305. package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
  306. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  307. package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
  308. package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
  309. package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
  310. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  311. package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
  312. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  313. package/dist/modules/sales/components/StatusSettings.js +18 -11
  314. package/dist/modules/sales/components/StatusSettings.js.map +2 -2
  315. package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
  316. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  317. package/dist/modules/sales/components/channels/ChannelOfferForm.js +47 -16
  318. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  319. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +8 -4
  320. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  321. package/dist/modules/sales/components/documents/AddressesSection.js +44 -25
  322. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  323. package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
  324. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  325. package/dist/modules/sales/components/documents/ItemsSection.js +22 -13
  326. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  327. package/dist/modules/sales/components/documents/LineItemDialog.js +23 -10
  328. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  329. package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
  330. package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
  331. package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
  332. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  333. package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
  334. package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
  335. package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
  336. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  337. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +10 -5
  338. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  339. package/dist/modules/sales/components/documents/ShipmentDialog.js +21 -7
  340. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  341. package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
  342. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  343. package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
  344. package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
  345. package/dist/modules/sales/di.js +18 -0
  346. package/dist/modules/sales/di.js.map +2 -2
  347. package/dist/modules/staff/api/job-histories.js +11 -2
  348. package/dist/modules/staff/api/job-histories.js.map +2 -2
  349. package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
  350. package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
  351. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
  352. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
  353. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
  354. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
  355. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
  356. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  357. package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
  358. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  359. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +1 -0
  360. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
  361. package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
  362. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  363. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
  364. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  365. package/dist/modules/staff/backend/staff/teams/page.js +12 -3
  366. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  367. package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
  368. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  369. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
  370. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
  371. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  372. package/dist/modules/staff/commands/job-histories.js +40 -3
  373. package/dist/modules/staff/commands/job-histories.js.map +2 -2
  374. package/dist/modules/staff/components/LeaveRequestForm.js +1 -0
  375. package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
  376. package/dist/modules/staff/components/TeamForm.js +1 -0
  377. package/dist/modules/staff/components/TeamForm.js.map +2 -2
  378. package/dist/modules/staff/components/TeamMemberForm.js +1 -0
  379. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  380. package/dist/modules/staff/components/TeamRoleForm.js +1 -0
  381. package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
  382. package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
  383. package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
  384. package/dist/modules/staff/data/validators.js +7 -1
  385. package/dist/modules/staff/data/validators.js.map +2 -2
  386. package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
  387. package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
  388. package/dist/modules/translations/components/TranslationManager.js +12 -8
  389. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  390. package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
  391. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  392. package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
  393. package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
  394. package/dist/modules/workflows/backend/definitions/page.js +19 -8
  395. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  396. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
  397. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  398. package/dist/modules/workflows/components/formConfig.js +4 -1
  399. package/dist/modules/workflows/components/formConfig.js.map +2 -2
  400. package/dist/modules/workflows/di.js +12 -0
  401. package/dist/modules/workflows/di.js.map +2 -2
  402. package/generated/entities/role/index.ts +1 -0
  403. package/generated/entities/user/index.ts +1 -0
  404. package/generated/entity-fields-registry.ts +2 -0
  405. package/jest.setup.ts +17 -0
  406. package/package.json +8 -7
  407. package/src/helpers/integration/optimisticLockUi.ts +172 -0
  408. package/src/helpers/integration/salesFixtures.ts +29 -0
  409. package/src/modules/api_keys/backend/api-keys/page.tsx +10 -5
  410. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
  411. package/src/modules/auth/api/roles/acl/route.ts +37 -11
  412. package/src/modules/auth/api/roles/route.ts +2 -0
  413. package/src/modules/auth/api/sidebar/preferences/route.ts +73 -0
  414. package/src/modules/auth/api/users/acl/route.ts +46 -18
  415. package/src/modules/auth/api/users/route.ts +2 -0
  416. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
  417. package/src/modules/auth/backend/roles/page.tsx +9 -4
  418. package/src/modules/auth/backend/users/[id]/edit/page.tsx +37 -4
  419. package/src/modules/auth/backend/users/page.tsx +7 -2
  420. package/src/modules/auth/components/AclEditor.tsx +10 -1
  421. package/src/modules/auth/data/entities.ts +7 -1
  422. package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
  423. package/src/modules/business_rules/api/rules/route.ts +30 -0
  424. package/src/modules/business_rules/api/sets/route.ts +30 -0
  425. package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
  426. package/src/modules/business_rules/backend/rules/page.tsx +20 -11
  427. package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
  428. package/src/modules/business_rules/backend/sets/page.tsx +20 -11
  429. package/src/modules/catalog/api/categories/route.ts +3 -0
  430. package/src/modules/catalog/api/products/route.ts +4 -0
  431. package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
  432. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +112 -35
  433. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +56 -7
  434. package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
  435. package/src/modules/catalog/commands/variants.ts +32 -32
  436. package/src/modules/catalog/components/PriceKindSettings.tsx +20 -7
  437. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +1 -0
  438. package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
  439. package/src/modules/catalog/components/products/ProductsDataTable.tsx +8 -4
  440. package/src/modules/catalog/components/products/productForm.ts +3 -0
  441. package/src/modules/catalog/components/products/variantForm.ts +9 -0
  442. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +5 -0
  443. package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
  444. package/src/modules/currencies/backend/currencies/page.tsx +18 -11
  445. package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
  446. package/src/modules/currencies/backend/exchange-rates/page.tsx +10 -6
  447. package/src/modules/currencies/commands/currencies.ts +10 -5
  448. package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
  449. package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
  450. package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
  451. package/src/modules/customer_accounts/api/admin/users/[id].ts +38 -5
  452. package/src/modules/customer_accounts/api/admin/users.ts +2 -0
  453. package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
  454. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +9 -4
  455. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
  456. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
  457. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +19 -11
  458. package/src/modules/customers/AGENTS.md +2 -2
  459. package/src/modules/customers/api/companies/route.ts +14 -1
  460. package/src/modules/customers/api/deals/route.ts +3 -0
  461. package/src/modules/customers/api/people/route.ts +12 -1
  462. package/src/modules/customers/api/todos/route.ts +1 -0
  463. package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
  464. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
  465. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
  466. package/src/modules/customers/backend/customers/companies/page.tsx +2 -0
  467. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
  468. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
  469. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
  470. package/src/modules/customers/backend/customers/deals/page.tsx +18 -6
  471. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
  472. package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
  473. package/src/modules/customers/backend/customers/people/page.tsx +2 -0
  474. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +84 -24
  475. package/src/modules/customers/commands/addresses.ts +16 -14
  476. package/src/modules/customers/commands/companies.ts +3 -1
  477. package/src/modules/customers/commands/interactions.ts +50 -4
  478. package/src/modules/customers/commands/people.ts +2 -1
  479. package/src/modules/customers/commands/personCompanyLinks.ts +8 -5
  480. package/src/modules/customers/commands/pipeline-stages.ts +16 -16
  481. package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
  482. package/src/modules/customers/components/DictionarySettings.tsx +18 -13
  483. package/src/modules/customers/components/DictionarySortSettings.tsx +4 -0
  484. package/src/modules/customers/components/PipelineSettings.tsx +42 -21
  485. package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
  486. package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
  487. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
  488. package/src/modules/customers/components/detail/DealsSection.tsx +4 -0
  489. package/src/modules/customers/components/detail/EmailCardActions.tsx +5 -0
  490. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
  491. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
  492. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
  493. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
  494. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
  495. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
  496. package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
  497. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
  498. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
  499. package/src/modules/customers/components/detail/types.ts +1 -0
  500. package/src/modules/customers/components/formConfig.tsx +2 -0
  501. package/src/modules/customers/data/guards.ts +67 -0
  502. package/src/modules/customers/di.ts +66 -0
  503. package/src/modules/customers/i18n/de.json +2 -0
  504. package/src/modules/customers/i18n/en.json +2 -0
  505. package/src/modules/customers/i18n/es.json +2 -0
  506. package/src/modules/customers/i18n/pl.json +2 -0
  507. package/src/modules/customers/lib/todoCompatibility.ts +14 -0
  508. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
  509. package/src/modules/data_sync/api/options.ts +7 -4
  510. package/src/modules/data_sync/api/schedules/route.ts +9 -1
  511. package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
  512. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
  513. package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
  514. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
  515. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +23 -0
  516. package/src/modules/dictionaries/components/DictionariesManager.tsx +32 -9
  517. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +30 -14
  518. package/src/modules/dictionaries/i18n/de.json +1 -0
  519. package/src/modules/dictionaries/i18n/en.json +1 -0
  520. package/src/modules/dictionaries/i18n/es.json +1 -0
  521. package/src/modules/dictionaries/i18n/pl.json +1 -0
  522. package/src/modules/directory/api/organizations/route.ts +3 -0
  523. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
  524. package/src/modules/directory/backend/directory/organizations/page.tsx +10 -5
  525. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
  526. package/src/modules/directory/backend/directory/tenants/page.tsx +8 -4
  527. package/src/modules/directory/commands/organizations.ts +7 -4
  528. package/src/modules/entities/api/records.ts +99 -0
  529. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
  530. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
  531. package/src/modules/entities/lib/helpers.ts +17 -0
  532. package/src/modules/feature_toggles/api/global/[id]/override/route.ts +1 -0
  533. package/src/modules/feature_toggles/api/overrides/route.ts +19 -0
  534. package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +19 -13
  535. package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
  536. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +7 -2
  537. package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
  538. package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
  539. package/src/modules/feature_toggles/data/validators.ts +11 -3
  540. package/src/modules/inbox_ops/api/settings/route.ts +18 -0
  541. package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
  542. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
  543. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
  544. package/src/modules/integrations/backend/integrations/page.tsx +13 -8
  545. package/src/modules/messages/commands/messages.ts +27 -15
  546. package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
  547. package/src/modules/perspectives/services/perspectiveService.ts +13 -1
  548. package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
  549. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
  550. package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +3 -0
  551. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +58 -15
  552. package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
  553. package/src/modules/query_index/lib/engine.ts +34 -0
  554. package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +7 -1
  555. package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
  556. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +23 -3
  557. package/src/modules/resources/backend/resources/resources/page.tsx +15 -4
  558. package/src/modules/resources/components/ResourceCrudForm.tsx +3 -0
  559. package/src/modules/resources/components/ResourceTypeCrudForm.tsx +2 -0
  560. package/src/modules/sales/api/documents/factory.ts +13 -1
  561. package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
  562. package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
  563. package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
  564. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +73 -20
  565. package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
  566. package/src/modules/sales/commands/documentAddresses.ts +226 -4
  567. package/src/modules/sales/commands/documents.ts +28 -0
  568. package/src/modules/sales/commands/returns.ts +12 -3
  569. package/src/modules/sales/commands/shared.ts +36 -0
  570. package/src/modules/sales/commands/shipments.ts +17 -1
  571. package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
  572. package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
  573. package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
  574. package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
  575. package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
  576. package/src/modules/sales/components/StatusSettings.tsx +20 -11
  577. package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
  578. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +67 -14
  579. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +7 -4
  580. package/src/modules/sales/components/documents/AddressesSection.tsx +35 -25
  581. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
  582. package/src/modules/sales/components/documents/ItemsSection.tsx +24 -13
  583. package/src/modules/sales/components/documents/LineItemDialog.tsx +26 -9
  584. package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
  585. package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
  586. package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
  587. package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
  588. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +11 -4
  589. package/src/modules/sales/components/documents/ShipmentDialog.tsx +23 -8
  590. package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
  591. package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
  592. package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
  593. package/src/modules/sales/di.ts +35 -0
  594. package/src/modules/sales/i18n/de.json +3 -0
  595. package/src/modules/sales/i18n/en.json +3 -0
  596. package/src/modules/sales/i18n/es.json +3 -0
  597. package/src/modules/sales/i18n/pl.json +3 -0
  598. package/src/modules/staff/api/job-histories.ts +12 -2
  599. package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
  600. package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
  601. package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
  602. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
  603. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -2
  604. package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +8 -0
  605. package/src/modules/staff/backend/staff/team-roles/page.tsx +6 -2
  606. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
  607. package/src/modules/staff/backend/staff/teams/page.tsx +9 -3
  608. package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
  609. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -0
  610. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
  611. package/src/modules/staff/commands/job-histories.ts +42 -3
  612. package/src/modules/staff/components/LeaveRequestForm.tsx +2 -0
  613. package/src/modules/staff/components/TeamForm.tsx +2 -0
  614. package/src/modules/staff/components/TeamMemberForm.tsx +2 -0
  615. package/src/modules/staff/components/TeamRoleForm.tsx +2 -0
  616. package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
  617. package/src/modules/staff/data/validators.ts +6 -0
  618. package/src/modules/staff/i18n/de.json +1 -0
  619. package/src/modules/staff/i18n/en.json +1 -0
  620. package/src/modules/staff/i18n/es.json +1 -0
  621. package/src/modules/staff/i18n/pl.json +1 -0
  622. package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
  623. package/src/modules/translations/components/TranslationManager.tsx +13 -8
  624. package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
  625. package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
  626. package/src/modules/workflows/backend/definitions/page.tsx +20 -9
  627. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
  628. package/src/modules/workflows/components/formConfig.tsx +5 -0
  629. package/src/modules/workflows/di.ts +20 -0
  630. package/src/modules/workflows/i18n/de.json +1 -0
  631. package/src/modules/workflows/i18n/en.json +1 -0
  632. package/src/modules/workflows/i18n/es.json +1 -0
  633. package/src/modules/workflows/i18n/pl.json +1 -0
@@ -7,7 +7,9 @@ import { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupCompone
7
7
  import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
8
8
  import { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
9
9
  import { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'
10
- import { readApiResultOrThrow, apiCall } from '@open-mercato/ui/backend/utils/apiCall'
10
+ import { readApiResultOrThrow, apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
11
+ import { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'
12
+ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
11
13
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
12
14
  import { Button } from '@open-mercato/ui/primitives/button'
13
15
  import { Input } from '@open-mercato/ui/primitives/input'
@@ -41,6 +43,8 @@ type PriceOverrideDraft = {
41
43
  currencyCode?: string | null
42
44
  displayMode?: 'including-tax' | 'excluding-tax' | null
43
45
  amount?: string
46
+ /** The price row's version, for the per-price optimistic-lock header (#2332). */
47
+ updatedAt?: string | null
44
48
  }
45
49
 
46
50
  export type OfferFormValues = {
@@ -51,6 +55,7 @@ export type OfferFormValues = {
51
55
  defaultMediaId?: string | null
52
56
  isActive: boolean
53
57
  priceOverrides: PriceOverrideDraft[]
58
+ updatedAt?: string | null
54
59
  } & Record<string, unknown>
55
60
 
56
61
  type ChannelOfferFormProps = {
@@ -141,13 +146,15 @@ export function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }:
141
146
  const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())
142
147
  const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)
143
148
  const manualMediaSelections = React.useRef<Set<string>>(new Set())
144
- const initialPriceIdsRef = React.useRef<Set<string>>(new Set())
149
+ // Map of the loaded price-override id → its `updatedAt`, so deletes during the
150
+ // offer save can send the price's own optimistic-lock version (#2332).
151
+ const initialPriceVersionsRef = React.useRef<Map<string, string | null>>(new Map())
145
152
  const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)
146
153
  React.useEffect(() => {
147
154
  if (initialValues) {
148
- initialPriceIdsRef.current = collectPriceIds(initialValues.priceOverrides)
155
+ initialPriceVersionsRef.current = collectPriceVersions(initialValues.priceOverrides)
149
156
  } else {
150
- initialPriceIdsRef.current = new Set()
157
+ initialPriceVersionsRef.current = new Map()
151
158
  }
152
159
  }, [initialValues])
153
160
  const channelOffersHref = React.useMemo(
@@ -438,12 +445,16 @@ export function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }:
438
445
  if (!priceId) return true
439
446
  if (mode !== 'edit') return true
440
447
  try {
441
- await deleteCrud('catalog/prices', priceId, {
442
- errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),
443
- })
444
- initialPriceIdsRef.current.delete(priceId)
448
+ await withScopedApiRequestHeaders(
449
+ buildOptimisticLockHeader(draft.updatedAt),
450
+ () => deleteCrud('catalog/prices', priceId, {
451
+ errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),
452
+ }),
453
+ )
454
+ initialPriceVersionsRef.current.delete(priceId)
445
455
  return true
446
456
  } catch (err) {
457
+ if (surfaceRecordConflict(err, t)) return false
447
458
  console.error('sales.channels.pricing.remove', err)
448
459
  flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')
449
460
  return false
@@ -594,10 +605,11 @@ export function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }:
594
605
  }
595
606
  const submittedPriceIds = collectPriceIds(overrides)
596
607
  const deletedIdSet = new Set<string>()
597
- initialPriceIdsRef.current.forEach((id) => {
608
+ initialPriceVersionsRef.current.forEach((_version, id) => {
598
609
  if (!submittedPriceIds.has(id)) deletedIdSet.add(id)
599
610
  })
600
611
  const deletedIds = Array.from(deletedIdSet)
612
+ const deletedVersions = new Map(deletedIds.map((id) => [id, initialPriceVersionsRef.current.get(id) ?? null]))
601
613
  let savedId = offerId ?? null
602
614
  try {
603
615
  if (mode === 'create') {
@@ -612,6 +624,13 @@ export function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }:
612
624
  savedId = offerId
613
625
  }
614
626
  } catch (err) {
627
+ // Let an optimistic-lock 409 propagate untouched so CrudForm's
628
+ // extractOptimisticLockConflict still sees the top-level `code` /
629
+ // `currentUpdatedAt` / `expectedUpdatedAt` and surfaces the unified
630
+ // conflict bar. Re-wrapping via createCrudFormError below would drop them.
631
+ if (extractOptimisticLockConflict(err)) {
632
+ throw err
633
+ }
615
634
  const details = (err as { details?: unknown })?.details
616
635
  const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors
617
636
  const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'
@@ -634,15 +653,16 @@ export function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }:
634
653
  await syncPriceOverrides({
635
654
  overrides,
636
655
  deletedIds,
656
+ deletedVersions,
637
657
  offerId: savedId,
638
658
  channelId,
639
659
  productId,
640
660
  })
641
- initialPriceIdsRef.current = submittedPriceIds
661
+ initialPriceVersionsRef.current = collectPriceVersions(overrides)
642
662
  }
643
663
  flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')
644
664
  router.push(buildChannelOffersHref(channelId))
645
- }, [attachmentCache, initialPriceIdsRef, lockedChannelId, mode, offerId, router, selectedChannelId, t])
665
+ }, [attachmentCache, lockedChannelId, mode, offerId, router, selectedChannelId, t])
646
666
 
647
667
  const handleDelete = React.useCallback(async () => {
648
668
  if (!offerId) return
@@ -669,6 +689,7 @@ export function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }:
669
689
  fields={fields}
670
690
  groups={groups}
671
691
  initialValues={initialValues ?? undefined}
692
+ optimisticLockUpdatedAt={initialValues?.updatedAt}
672
693
  isLoading={loading}
673
694
  loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer…')}
674
695
  submitLabel={mode === 'create'
@@ -706,6 +727,11 @@ function mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: s
706
727
  : null,
707
728
  isActive: item.isActive === true || item.is_active === true,
708
729
  priceOverrides: [],
730
+ updatedAt: typeof item.updatedAt === 'string'
731
+ ? item.updatedAt
732
+ : typeof item.updated_at === 'string'
733
+ ? item.updated_at
734
+ : null,
709
735
  }
710
736
  mergeCustomFieldValues(values, item)
711
737
  return values
@@ -742,6 +768,11 @@ function mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {
742
768
  : typeof row.unit_price_gross === 'string'
743
769
  ? row.unit_price_gross
744
770
  : '',
771
+ updatedAt: typeof row.updatedAt === 'string'
772
+ ? row.updatedAt
773
+ : typeof row.updated_at === 'string'
774
+ ? row.updated_at
775
+ : null,
745
776
  }
746
777
  }
747
778
 
@@ -753,6 +784,17 @@ function collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<s
753
784
  return new Set(ids)
754
785
  }
755
786
 
787
+ function collectPriceVersions(source: PriceOverrideDraft[] | null | undefined): Map<string, string | null> {
788
+ const versions = new Map<string, string | null>()
789
+ if (!Array.isArray(source)) return versions
790
+ for (const entry of source) {
791
+ if (typeof entry?.priceId === 'string' && entry.priceId) {
792
+ versions.set(entry.priceId, typeof entry.updatedAt === 'string' ? entry.updatedAt : null)
793
+ }
794
+ }
795
+ return versions
796
+ }
797
+
756
798
  function mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {
757
799
  Object.assign(target, extractCustomFieldEntries(source ?? {}))
758
800
  }
@@ -766,11 +808,12 @@ function buildChannelOffersHref(channelId?: string | null): string {
766
808
  async function syncPriceOverrides(params: {
767
809
  overrides: PriceOverrideDraft[]
768
810
  deletedIds: string[]
811
+ deletedVersions: Map<string, string | null>
769
812
  offerId: string
770
813
  channelId: string
771
814
  productId: string
772
815
  }) {
773
- const { overrides, deletedIds, offerId, channelId, productId } = params
816
+ const { overrides, deletedIds, deletedVersions, offerId, channelId, productId } = params
774
817
  for (const draft of overrides) {
775
818
  if (!draft.priceKindId || !draft.amount) continue
776
819
  const amount = Number(draft.amount)
@@ -788,7 +831,14 @@ async function syncPriceOverrides(params: {
788
831
  payload.unitPriceNet = amount
789
832
  }
790
833
  if (draft.priceId) {
791
- await updateCrud('catalog/prices', { id: draft.priceId, ...payload })
834
+ // Send the PRICE's own version, overriding the offer header the parent
835
+ // CrudForm submit scope put on the stack (otherwise the price guard would
836
+ // compare the offer's `updated_at` and 409 falsely). #2332.
837
+ const priceId = draft.priceId
838
+ await withScopedApiRequestHeaders(
839
+ buildOptimisticLockHeader(draft.updatedAt),
840
+ () => updateCrud('catalog/prices', { id: priceId, ...payload }),
841
+ )
792
842
  } else {
793
843
  await createCrud('catalog/prices', payload)
794
844
  }
@@ -799,7 +849,10 @@ async function syncPriceOverrides(params: {
799
849
  for (const id of uniqueDeletedIds) {
800
850
  if (!id) continue
801
851
  try {
802
- await deleteCrud('catalog/prices', id)
852
+ await withScopedApiRequestHeaders(
853
+ buildOptimisticLockHeader(deletedVersions.get(id) ?? null),
854
+ () => deleteCrud('catalog/prices', id),
855
+ )
803
856
  } catch (err) {
804
857
  console.error('catalog.prices.delete', err)
805
858
  }
@@ -9,7 +9,8 @@ import { RowActions } from '@open-mercato/ui/backend/RowActions'
9
9
  import { Button } from '@open-mercato/ui/primitives/button'
10
10
  import { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'
11
11
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
12
- import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
12
+ import { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
13
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
13
14
  import { deleteCrud } from '@open-mercato/ui/backend/utils/crud'
14
15
  import { useT } from '@open-mercato/shared/lib/i18n/context'
15
16
  import { mapOfferRow, renderOfferPriceSummary, type OfferRow } from './offerTableUtils'
@@ -123,9 +124,11 @@ export function SalesChannelOffersPanel({ channelId, channelName }: { channelId:
123
124
 
124
125
  const handleDelete = React.useCallback(async (row: OfferRow) => {
125
126
  try {
126
- await deleteCrud('catalog/offers', row.id, {
127
- errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),
128
- })
127
+ await withScopedApiRequestHeaders(buildOptimisticLockHeader(row.updatedAt), () =>
128
+ deleteCrud('catalog/offers', row.id, {
129
+ errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),
130
+ }),
131
+ )
129
132
  flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')
130
133
  setReloadToken((token) => token + 1)
131
134
  } catch (err) {
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as React from 'react'
6
6
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
7
- import { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
7
+ import { apiCall, apiCallOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
8
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
8
9
  import { createCrud } from '@open-mercato/ui/backend/utils/crud'
9
10
  import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
10
11
  import { ErrorMessage, LoadingMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'
@@ -691,14 +692,17 @@ export function SalesDocumentAddressesSection({
691
692
  }
692
693
  await runGuardedMutation(
693
694
  () =>
694
- apiCallOrThrow(
695
- '/api/sales/document-addresses',
696
- {
697
- method: 'PUT',
698
- headers: { 'Content-Type': 'application/json' },
699
- body: JSON.stringify(payload),
700
- },
701
- { errorMessage: t('sales.documents.detail.addresses.saveError', 'Failed to update addresses.') },
695
+ // TODO(#2373-C): thread document updatedAt
696
+ withScopedApiRequestHeaders(buildOptimisticLockHeader(undefined), () =>
697
+ apiCallOrThrow(
698
+ '/api/sales/document-addresses',
699
+ {
700
+ method: 'PUT',
701
+ headers: { 'Content-Type': 'application/json' },
702
+ body: JSON.stringify(payload),
703
+ },
704
+ { errorMessage: t('sales.documents.detail.addresses.saveError', 'Failed to update addresses.') },
705
+ ),
702
706
  ),
703
707
  payload,
704
708
  )
@@ -750,14 +754,17 @@ export function SalesDocumentAddressesSection({
750
754
  const payload = { id, documentId, documentKind: kind }
751
755
  await runGuardedMutation(
752
756
  () =>
753
- apiCallOrThrow(
754
- '/api/sales/document-addresses',
755
- {
756
- method: 'DELETE',
757
- headers: { 'Content-Type': 'application/json' },
758
- body: JSON.stringify(payload),
759
- },
760
- { errorMessage: t('sales.documents.detail.addresses.deleteError', 'Failed to remove address.') },
757
+ // TODO(#2373-C): thread document updatedAt
758
+ withScopedApiRequestHeaders(buildOptimisticLockHeader(undefined), () =>
759
+ apiCallOrThrow(
760
+ '/api/sales/document-addresses',
761
+ {
762
+ method: 'DELETE',
763
+ headers: { 'Content-Type': 'application/json' },
764
+ body: JSON.stringify(payload),
765
+ },
766
+ { errorMessage: t('sales.documents.detail.addresses.deleteError', 'Failed to remove address.') },
767
+ ),
761
768
  ),
762
769
  payload,
763
770
  )
@@ -849,14 +856,17 @@ export function SalesDocumentAddressesSection({
849
856
  const endpoint = kind === 'order' ? '/api/sales/orders' : '/api/sales/quotes'
850
857
  const call = await runGuardedMutation(
851
858
  () =>
852
- apiCallOrThrow<Record<string, unknown>>(
853
- endpoint,
854
- {
855
- method: 'PUT',
856
- headers: { 'Content-Type': 'application/json' },
857
- body: JSON.stringify(payload),
858
- },
859
- { errorMessage: t('sales.documents.detail.updateError', 'Failed to update document.') },
859
+ // TODO(#2373-C): thread document updatedAt
860
+ withScopedApiRequestHeaders(buildOptimisticLockHeader(undefined), () =>
861
+ apiCallOrThrow<Record<string, unknown>>(
862
+ endpoint,
863
+ {
864
+ method: 'PUT',
865
+ headers: { 'Content-Type': 'application/json' },
866
+ body: JSON.stringify(payload),
867
+ },
868
+ { errorMessage: t('sales.documents.detail.updateError', 'Failed to update document.') },
869
+ ),
860
870
  ),
861
871
  payload,
862
872
  )
@@ -8,9 +8,11 @@ import { Badge } from '@open-mercato/ui/primitives/badge'
8
8
  import { DataTable } from '@open-mercato/ui/backend/DataTable'
9
9
  import { ErrorMessage, LoadingMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'
10
10
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
11
- import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
11
+ import { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
12
+ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
12
13
  import { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'
13
14
  import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
15
+ import { handleSectionMutationError } from './optimisticLock'
14
16
  import { RowActions } from '@open-mercato/ui/backend/RowActions'
15
17
  import { type DictionaryOption } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'
16
18
  import {
@@ -31,6 +33,7 @@ type SalesDocumentAdjustmentsSectionProps = {
31
33
  documentId: string
32
34
  kind: 'order' | 'quote'
33
35
  currencyCode: string | null | undefined
36
+ documentUpdatedAt?: string | null
34
37
  organizationId?: string | null
35
38
  tenantId?: string | null
36
39
  onActionChange?: (action: SectionAction | null) => void
@@ -64,6 +67,7 @@ export function SalesDocumentAdjustmentsSection({
64
67
  documentId,
65
68
  kind,
66
69
  currencyCode,
70
+ documentUpdatedAt,
67
71
  organizationId: orgFromProps,
68
72
  tenantId: tenantFromProps,
69
73
  onActionChange,
@@ -317,27 +321,43 @@ export function SalesDocumentAdjustmentsSection({
317
321
  }
318
322
 
319
323
  const action = values.id ? updateCrud : createCrud
320
- const result = await action(
321
- crudResourcePath,
322
- values.id ? { id: values.id, ...payload } : payload,
323
- {
324
- successMessage: values.id
325
- ? t('sales.documents.adjustments.updated', 'Adjustment updated.')
326
- : t('sales.documents.adjustments.created', 'Adjustment added.'),
327
- errorMessage: t('sales.documents.adjustments.errorSave', 'Failed to save adjustment.'),
324
+ try {
325
+ const result = await withScopedApiRequestHeaders(
326
+ buildOptimisticLockHeader(documentUpdatedAt),
327
+ () =>
328
+ action(
329
+ crudResourcePath,
330
+ values.id ? { id: values.id, ...payload } : payload,
331
+ {
332
+ successMessage: values.id
333
+ ? t('sales.documents.adjustments.updated', 'Adjustment updated.')
334
+ : t('sales.documents.adjustments.created', 'Adjustment added.'),
335
+ errorMessage: t('sales.documents.adjustments.errorSave', 'Failed to save adjustment.'),
336
+ }
337
+ )
338
+ )
339
+ if (result.ok) {
340
+ await loadAdjustments()
341
+ emitSalesDocumentTotalsRefresh({ documentId, kind })
342
+ setDialogOpen(false)
343
+ setActiveAdjustment(null)
328
344
  }
329
- )
330
- if (result.ok) {
331
- await loadAdjustments()
332
- emitSalesDocumentTotalsRefresh({ documentId, kind })
333
- setDialogOpen(false)
334
- setActiveAdjustment(null)
345
+ } catch (err) {
346
+ if (
347
+ handleSectionMutationError(err, t, () => void loadAdjustments())
348
+ ) {
349
+ setDialogOpen(false)
350
+ setActiveAdjustment(null)
351
+ return
352
+ }
353
+ throw err
335
354
  }
336
355
  },
337
356
  [
338
357
  currencyCode,
339
358
  documentId,
340
359
  documentKey,
360
+ documentUpdatedAt,
341
361
  kind,
342
362
  loadAdjustments,
343
363
  crudResourcePath,
@@ -350,25 +370,30 @@ export function SalesDocumentAdjustmentsSection({
350
370
  const handleDelete = React.useCallback(
351
371
  async (row: AdjustmentRow) => {
352
372
  try {
353
- const result = await deleteCrud(crudResourcePath, {
354
- body: {
355
- id: row.id,
356
- [documentKey]: documentId,
357
- organizationId: resolvedOrganizationId ?? undefined,
358
- tenantId: resolvedTenantId ?? undefined,
359
- },
360
- errorMessage: t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'),
361
- })
373
+ const result = await withScopedApiRequestHeaders(
374
+ buildOptimisticLockHeader(documentUpdatedAt),
375
+ () =>
376
+ deleteCrud(crudResourcePath, {
377
+ body: {
378
+ id: row.id,
379
+ [documentKey]: documentId,
380
+ organizationId: resolvedOrganizationId ?? undefined,
381
+ tenantId: resolvedTenantId ?? undefined,
382
+ },
383
+ errorMessage: t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'),
384
+ })
385
+ )
362
386
  if (result.ok) {
363
387
  await loadAdjustments()
364
388
  emitSalesDocumentTotalsRefresh({ documentId, kind })
365
389
  }
366
390
  } catch (err) {
391
+ if (handleSectionMutationError(err, t, () => void loadAdjustments())) return
367
392
  console.error('sales.document.adjustments.delete', err)
368
393
  flash(t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'), 'error')
369
394
  }
370
395
  },
371
- [crudResourcePath, documentId, documentKey, kind, loadAdjustments, resolvedOrganizationId, resolvedTenantId, t]
396
+ [crudResourcePath, documentId, documentKey, documentUpdatedAt, kind, loadAdjustments, resolvedOrganizationId, resolvedTenantId, t]
372
397
  )
373
398
 
374
399
  const columns = React.useMemo<ColumnDef<AdjustmentRow>[]>(
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
3
  import * as React from "react";
4
- import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
4
+ import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
5
+ import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
5
6
  import { deleteCrud } from "@open-mercato/ui/backend/utils/crud";
6
7
  import { normalizeCrudServerError } from "@open-mercato/ui/backend/utils/serverErrors";
7
8
  import { LoadingMessage, TabEmptyState } from "@open-mercato/ui/backend/detail";
@@ -19,6 +20,7 @@ import { useOrganizationScopeDetail } from "@open-mercato/shared/lib/frontend/us
19
20
  import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
20
21
  import { emitSalesDocumentTotalsRefresh } from "@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents";
21
22
  import { LineItemDialog } from "./LineItemDialog";
23
+ import { handleSectionMutationError } from "./optimisticLock";
22
24
  import type { SalesLineRecord } from "./lineItemTypes";
23
25
  import { formatMoney, normalizeNumber } from "./lineItemUtils";
24
26
  import type { SectionAction } from "@open-mercato/ui/backend/detail";
@@ -109,6 +111,7 @@ type SalesDocumentItemsSectionProps = {
109
111
  documentId: string;
110
112
  kind: "order" | "quote";
111
113
  currencyCode: string | null | undefined;
114
+ documentUpdatedAt?: string | null;
112
115
  organizationId?: string | null;
113
116
  tenantId?: string | null;
114
117
  onActionChange?: (action: SectionAction | null) => void;
@@ -119,6 +122,7 @@ export function SalesDocumentItemsSection({
119
122
  documentId,
120
123
  kind,
121
124
  currencyCode,
125
+ documentUpdatedAt,
122
126
  organizationId: orgFromProps,
123
127
  tenantId: tenantFromProps,
124
128
  onActionChange,
@@ -449,24 +453,29 @@ export function SalesDocumentItemsSection({
449
453
  });
450
454
  if (!confirmed) return;
451
455
  try {
452
- const result = await deleteCrud(resourcePath, {
453
- body: {
454
- id: line.id,
455
- [documentKey]: documentId,
456
- organizationId: resolvedOrganizationId ?? undefined,
457
- tenantId: resolvedTenantId ?? undefined,
458
- },
459
- errorMessage: t(
460
- "sales.documents.items.errorDelete",
461
- "Failed to delete line.",
462
- ),
463
- });
456
+ const result = await withScopedApiRequestHeaders(
457
+ buildOptimisticLockHeader(documentUpdatedAt),
458
+ () =>
459
+ deleteCrud(resourcePath, {
460
+ body: {
461
+ id: line.id,
462
+ [documentKey]: documentId,
463
+ organizationId: resolvedOrganizationId ?? undefined,
464
+ tenantId: resolvedTenantId ?? undefined,
465
+ },
466
+ errorMessage: t(
467
+ "sales.documents.items.errorDelete",
468
+ "Failed to delete line.",
469
+ ),
470
+ }),
471
+ );
464
472
  if (result.ok) {
465
473
  flash(t("sales.documents.items.deleted", "Line removed."), "success");
466
474
  await loadItems();
467
475
  emitSalesDocumentTotalsRefresh({ documentId, kind });
468
476
  }
469
477
  } catch (err) {
478
+ if (handleSectionMutationError(err, t, () => void loadItems())) return;
470
479
  console.error("sales.document.items.delete", err);
471
480
  const normalized = normalizeCrudServerError(err);
472
481
  const fallback = t(
@@ -480,6 +489,7 @@ export function SalesDocumentItemsSection({
480
489
  confirm,
481
490
  documentId,
482
491
  documentKey,
492
+ documentUpdatedAt,
483
493
  kind,
484
494
  loadItems,
485
495
  resolvedOrganizationId,
@@ -800,6 +810,7 @@ export function SalesDocumentItemsSection({
800
810
  kind={kind}
801
811
  documentId={documentId}
802
812
  currencyCode={currencyCode}
813
+ documentUpdatedAt={documentUpdatedAt}
803
814
  organizationId={resolvedOrganizationId}
804
815
  tenantId={resolvedTenantId}
805
816
  initialLine={lineForEdit}
@@ -12,9 +12,11 @@ import {
12
12
  type CrudCustomFieldRenderProps,
13
13
  } from "@open-mercato/ui/backend/CrudForm";
14
14
  import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
15
- import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
15
+ import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
16
+ import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
16
17
  import { createCrud, updateCrud } from "@open-mercato/ui/backend/utils/crud";
17
18
  import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
19
+ import { handleSectionMutationError } from "./optimisticLock";
18
20
  import {
19
21
  Dialog,
20
22
  DialogContent,
@@ -233,6 +235,7 @@ type SalesLineDialogProps = {
233
235
  kind: "order" | "quote";
234
236
  documentId: string;
235
237
  currencyCode: string | null | undefined;
238
+ documentUpdatedAt?: string | null;
236
239
  organizationId: string | null;
237
240
  tenantId: string | null;
238
241
  initialLine?: SalesLineRecord | null;
@@ -426,6 +429,7 @@ export function LineItemDialog({
426
429
  kind,
427
430
  documentId,
428
431
  currencyCode,
432
+ documentUpdatedAt,
429
433
  organizationId,
430
434
  tenantId,
431
435
  initialLine,
@@ -1445,21 +1449,33 @@ export function LineItemDialog({
1445
1449
 
1446
1450
  try {
1447
1451
  const action = editingId ? updateCrud : createCrud;
1448
- const result = await action(
1449
- resourcePath,
1450
- editingId ? { id: editingId, ...payload } : payload,
1451
- {
1452
- errorMessage: t(
1453
- "sales.documents.items.errorSave",
1454
- "Failed to save line.",
1452
+ const result = await withScopedApiRequestHeaders(
1453
+ buildOptimisticLockHeader(documentUpdatedAt),
1454
+ () =>
1455
+ action(
1456
+ resourcePath,
1457
+ editingId ? { id: editingId, ...payload } : payload,
1458
+ {
1459
+ errorMessage: t(
1460
+ "sales.documents.items.errorSave",
1461
+ "Failed to save line.",
1462
+ ),
1463
+ },
1455
1464
  ),
1456
- },
1457
1465
  );
1458
1466
  if (result.ok) {
1459
1467
  if (onSaved) await onSaved();
1460
1468
  closeDialog();
1461
1469
  }
1462
1470
  } catch (err) {
1471
+ if (
1472
+ handleSectionMutationError(err, t, () => {
1473
+ if (onSaved) void onSaved();
1474
+ })
1475
+ ) {
1476
+ closeDialog();
1477
+ return;
1478
+ }
1463
1479
  throw err;
1464
1480
  }
1465
1481
  },
@@ -1467,6 +1483,7 @@ export function LineItemDialog({
1467
1483
  currencyCode,
1468
1484
  documentId,
1469
1485
  documentKey,
1486
+ documentUpdatedAt,
1470
1487
  editingId,
1471
1488
  priceOptions,
1472
1489
  productOption,