@open-mercato/core 0.6.8-develop.7100.1.fbf66fca35 → 0.7.0

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 (967) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/api.js +1 -13
  3. package/dist/helpers/integration/api.js.map +2 -2
  4. package/dist/helpers/integration/communicationChannelsFixtures.js +0 -19
  5. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  6. package/dist/modules/api_keys/api/keys/route.js +1 -1
  7. package/dist/modules/api_keys/api/keys/route.js.map +2 -2
  8. package/dist/modules/api_keys/backend/api-keys/page.js +1 -3
  9. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  10. package/dist/modules/attachments/api/route.js +2 -2
  11. package/dist/modules/attachments/api/route.js.map +2 -2
  12. package/dist/modules/attachments/components/AttachmentLibrary.js +0 -2
  13. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  14. package/dist/modules/attachments/di.js +1 -11
  15. package/dist/modules/attachments/di.js.map +2 -2
  16. package/dist/modules/attachments/index.js.map +1 -1
  17. package/dist/modules/attachments/lib/scoped-upload-service.js +2 -15
  18. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  19. package/dist/modules/attachments/lib/upload-limits.js +2 -6
  20. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  21. package/dist/modules/audit_logs/backend/audit-logs/page.js +0 -6
  22. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  23. package/dist/modules/audit_logs/lib/display-helpers.js +11 -19
  24. package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
  25. package/dist/modules/audit_logs/services/actionLogService.js +12 -57
  26. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  27. package/dist/modules/auth/acl.js +5 -30
  28. package/dist/modules/auth/acl.js.map +2 -2
  29. package/dist/modules/auth/api/feature-check.js +2 -8
  30. package/dist/modules/auth/api/feature-check.js.map +2 -2
  31. package/dist/modules/auth/api/login.js +20 -4
  32. package/dist/modules/auth/api/login.js.map +2 -2
  33. package/dist/modules/auth/api/roles/acl/route.js +33 -28
  34. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  35. package/dist/modules/auth/api/routeError.js +11 -0
  36. package/dist/modules/auth/api/routeError.js.map +7 -0
  37. package/dist/modules/auth/api/session/refresh.js +1 -25
  38. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  39. package/dist/modules/auth/api/users/acl/route.js +73 -102
  40. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  41. package/dist/modules/auth/api/users/route.js +5 -13
  42. package/dist/modules/auth/api/users/route.js.map +2 -2
  43. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +1 -5
  44. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  45. package/dist/modules/auth/backend/roles/page.js +1 -3
  46. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  47. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +1 -5
  48. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  49. package/dist/modules/auth/backend/users/page.js +1 -2
  50. package/dist/modules/auth/backend/users/page.js.map +2 -2
  51. package/dist/modules/auth/components/AclEditor.js +30 -39
  52. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  53. package/dist/modules/auth/data/entities.js.map +2 -2
  54. package/dist/modules/auth/data/validators.js +1 -5
  55. package/dist/modules/auth/data/validators.js.map +2 -2
  56. package/dist/modules/auth/di.js +9 -35
  57. package/dist/modules/auth/di.js.map +2 -2
  58. package/dist/modules/auth/frontend/reset/[token]/page.js +0 -46
  59. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  60. package/dist/modules/auth/lib/grantChecks.js.map +2 -2
  61. package/dist/modules/auth/services/authService.js +2 -16
  62. package/dist/modules/auth/services/authService.js.map +2 -2
  63. package/dist/modules/auth/services/rbacService.js +24 -67
  64. package/dist/modules/auth/services/rbacService.js.map +3 -3
  65. package/dist/modules/business_rules/backend/logs/page.js +1 -3
  66. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  67. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js +6 -1
  68. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js.map +2 -2
  69. package/dist/modules/business_rules/backend/rules/create/page.meta.js +5 -1
  70. package/dist/modules/business_rules/backend/rules/create/page.meta.js.map +2 -2
  71. package/dist/modules/business_rules/backend/rules/page.js +1 -3
  72. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  73. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js +6 -1
  74. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js.map +2 -2
  75. package/dist/modules/business_rules/backend/sets/create/page.meta.js +5 -1
  76. package/dist/modules/business_rules/backend/sets/create/page.meta.js.map +2 -2
  77. package/dist/modules/business_rules/backend/sets/page.js +1 -3
  78. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  79. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  80. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  81. package/dist/modules/business_rules/lib/rule-evaluator.js +9 -10
  82. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  83. package/dist/modules/catalog/ai-agents.js +1 -1
  84. package/dist/modules/catalog/ai-agents.js.map +1 -1
  85. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  86. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  87. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +2 -5
  88. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  89. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +0 -2
  90. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  91. package/dist/modules/catalog/components/products/ProductsDataTable.js +1 -7
  92. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  93. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +0 -2
  94. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  95. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +1 -9
  96. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  97. package/dist/modules/communication_channels/api/post/test-seed/route.js +10 -95
  98. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  99. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +0 -3
  100. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  101. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +1 -14
  102. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  103. package/dist/modules/communication_channels/di.js +1 -7
  104. package/dist/modules/communication_channels/di.js.map +2 -2
  105. package/dist/modules/communication_channels/lib/email-capabilities.js +1 -4
  106. package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
  107. package/dist/modules/communication_channels/lib/test-seed.js +2 -41
  108. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  109. package/dist/modules/configs/lib/system-status.js +0 -9
  110. package/dist/modules/configs/lib/system-status.js.map +2 -2
  111. package/dist/modules/currencies/backend/currencies/page.js +1 -3
  112. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  113. package/dist/modules/currencies/backend/exchange-rates/page.js +1 -3
  114. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  115. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +0 -9
  116. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
  117. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +1 -3
  118. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  119. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js +84 -0
  120. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js.map +7 -0
  121. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js +7 -81
  122. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js.map +2 -2
  123. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +523 -0
  124. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +7 -0
  125. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js +731 -0
  126. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js.map +7 -0
  127. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +7 -727
  128. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  129. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +7 -521
  130. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  131. package/dist/modules/customer_accounts/extension-points.js +1 -1
  132. package/dist/modules/customer_accounts/extension-points.js.map +2 -2
  133. package/dist/modules/customer_accounts/lib/portalUrl.js +69 -0
  134. package/dist/modules/customer_accounts/lib/portalUrl.js.map +7 -0
  135. package/dist/modules/customer_accounts/services/domainMappingService.js +0 -10
  136. package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
  137. package/dist/modules/customers/ai-tools/companies-pack.js +1 -4
  138. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  139. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +2 -13
  140. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
  141. package/dist/modules/customers/ai-tools/deals-pack.js +6 -52
  142. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  143. package/dist/modules/customers/ai-tools/people-pack.js +1 -4
  144. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  145. package/dist/modules/customers/api/activities/route.js +6 -48
  146. package/dist/modules/customers/api/activities/route.js.map +2 -2
  147. package/dist/modules/customers/api/companies/[id]/people/route.js +64 -20
  148. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  149. package/dist/modules/customers/api/companies/[id]/route.js +94 -17
  150. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  151. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +5 -8
  152. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
  153. package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
  154. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  155. package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
  156. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  157. package/dist/modules/customers/api/deals/[id]/route.js +25 -8
  158. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  159. package/dist/modules/customers/api/deals/[id]/stats/route.js +22 -3
  160. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  161. package/dist/modules/customers/api/deals/aggregate/route.js +4 -11
  162. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  163. package/dist/modules/customers/api/deals/map/route.js +1 -2
  164. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  165. package/dist/modules/customers/api/deals/route.js +1 -38
  166. package/dist/modules/customers/api/deals/route.js.map +2 -2
  167. package/dist/modules/customers/api/entity-roles-factory.js +4 -4
  168. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  169. package/dist/modules/customers/api/interactions/route.js +1 -3
  170. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  171. package/dist/modules/customers/api/interactions/tasks/route.js +4 -27
  172. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  173. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +3 -4
  174. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  175. package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
  176. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  177. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
  178. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  179. package/dist/modules/customers/api/people/[id]/route.js +10 -11
  180. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  181. package/dist/modules/customers/api/people/check-phone/route.js +9 -51
  182. package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
  183. package/dist/modules/customers/api/todos/route.js +5 -30
  184. package/dist/modules/customers/api/todos/route.js.map +2 -2
  185. package/dist/modules/customers/backend/customers/companies/page.js +4 -6
  186. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  187. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -6
  188. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  189. package/dist/modules/customers/backend/customers/deals/page.js +4 -7
  190. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  191. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +13 -4
  192. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
  193. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +14 -85
  194. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
  195. package/dist/modules/customers/backend/customers/people/page.js +4 -6
  196. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  197. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +3 -9
  198. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
  199. package/dist/modules/customers/commands/deals.js +34 -21
  200. package/dist/modules/customers/commands/deals.js.map +2 -2
  201. package/dist/modules/customers/commands/interactions.js.map +1 -1
  202. package/dist/modules/customers/commands/personCompanyLinks.js +2 -131
  203. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  204. package/dist/modules/customers/components/CustomerTodosTable.js +0 -1
  205. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  206. package/dist/modules/customers/components/DealsKpiStrip.js +6 -7
  207. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  208. package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
  209. package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
  210. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
  211. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  212. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  213. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  214. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
  215. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  216. package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
  217. package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
  218. package/dist/modules/customers/components/calendar/EventPeekPopover.js +2 -3
  219. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
  220. package/dist/modules/customers/components/calendar/editor/PeopleField.js +5 -40
  221. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  222. package/dist/modules/customers/components/calendar/editor/hooks.js +1 -2
  223. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  224. package/dist/modules/customers/components/calendar/types.js +1 -1
  225. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  226. package/dist/modules/customers/components/detail/AssignRoleDialog.js +33 -28
  227. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
  228. package/dist/modules/customers/components/detail/CompanyKpiBar.js +4 -5
  229. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  230. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +1 -3
  231. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  232. package/dist/modules/customers/components/detail/DealForm.js +7 -19
  233. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  234. package/dist/modules/customers/components/detail/DealsSection.js +5 -6
  235. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  236. package/dist/modules/customers/components/detail/EntityTagsDialog.js +11 -35
  237. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  238. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +1 -3
  239. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  240. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +13 -19
  241. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  242. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
  243. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  244. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
  245. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  246. package/dist/modules/customers/components/detail/utils.js +5 -5
  247. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  248. package/dist/modules/customers/data/entities.js.map +1 -1
  249. package/dist/modules/customers/data/validators.js +3 -32
  250. package/dist/modules/customers/data/validators.js.map +2 -2
  251. package/dist/modules/customers/events.js +0 -5
  252. package/dist/modules/customers/events.js.map +2 -2
  253. package/dist/modules/customers/lib/calendar/conflicts.js +2 -8
  254. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  255. package/dist/modules/customers/lib/calendar/editorPayload.js +2 -3
  256. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  257. package/dist/modules/customers/lib/calendar/mapItem.js +3 -8
  258. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  259. package/dist/modules/customers/lib/dealStatus.js +0 -30
  260. package/dist/modules/customers/lib/dealStatus.js.map +2 -2
  261. package/dist/modules/customers/lib/findPeopleByAddresses.js +0 -1
  262. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
  263. package/dist/modules/customers/lib/personCompanies.js +2 -100
  264. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  265. package/dist/modules/customers/lib/todoCompatibility.js +0 -12
  266. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  267. package/dist/modules/dashboards/lib/widgetScope.js +1 -6
  268. package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
  269. package/dist/modules/data_sync/backend/data-sync/page.js +1 -3
  270. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  271. package/dist/modules/data_sync/lib/sync-engine.js +6 -72
  272. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  273. package/dist/modules/data_sync/workers/sync-export.js +1 -5
  274. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  275. package/dist/modules/data_sync/workers/sync-import.js +1 -5
  276. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  277. package/dist/modules/devices/acl.js +1 -9
  278. package/dist/modules/devices/acl.js.map +2 -2
  279. package/dist/modules/devices/api/admin/devices/[id]/route.js +32 -5
  280. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
  281. package/dist/modules/devices/api/admin/devices/route.js +1 -14
  282. package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
  283. package/dist/modules/devices/api/deviceList.js +12 -99
  284. package/dist/modules/devices/api/deviceList.js.map +2 -2
  285. package/dist/modules/devices/api/openapi.js +1 -3
  286. package/dist/modules/devices/api/openapi.js.map +2 -2
  287. package/dist/modules/devices/api/route.js +1 -9
  288. package/dist/modules/devices/api/route.js.map +2 -2
  289. package/dist/modules/devices/backend/devices/[id]/page.js +26 -10
  290. package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
  291. package/dist/modules/devices/backend/devices/create/page.js +1 -17
  292. package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
  293. package/dist/modules/devices/backend/devices/page.js +34 -28
  294. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  295. package/dist/modules/devices/setup.js +2 -6
  296. package/dist/modules/devices/setup.js.map +2 -2
  297. package/dist/modules/directory/backend/directory/organizations/page.js +1 -2
  298. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  299. package/dist/modules/directory/backend/directory/tenants/page.js +1 -2
  300. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  301. package/dist/modules/directory/di.js +0 -9
  302. package/dist/modules/directory/di.js.map +2 -2
  303. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  304. package/dist/modules/entities/api/records.js +2 -4
  305. package/dist/modules/entities/api/records.js.map +2 -2
  306. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +1 -3
  307. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  308. package/dist/modules/eudr/api/plots/route.js +1 -5
  309. package/dist/modules/eudr/api/plots/route.js.map +2 -2
  310. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +3 -1
  311. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +2 -2
  312. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +1 -0
  313. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +2 -2
  314. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +0 -3
  315. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  316. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +4 -1
  317. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +2 -2
  318. package/dist/modules/eudr/backend/eudr/page.meta.js +2 -2
  319. package/dist/modules/eudr/backend/eudr/page.meta.js.map +2 -2
  320. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +8 -2
  321. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +2 -2
  322. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +3 -1
  323. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +2 -2
  324. package/dist/modules/eudr/backend/eudr/plots/create/page.js +8 -2
  325. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +2 -2
  326. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +1 -0
  327. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +2 -2
  328. package/dist/modules/eudr/backend/eudr/plots/page.js +0 -3
  329. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  330. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +4 -1
  331. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +2 -2
  332. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +3 -1
  333. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +2 -2
  334. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +1 -0
  335. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +2 -2
  336. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +0 -3
  337. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  338. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +4 -1
  339. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +2 -2
  340. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +3 -1
  341. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +2 -2
  342. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +1 -0
  343. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +2 -2
  344. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +0 -3
  345. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  346. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +4 -1
  347. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +2 -2
  348. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +2 -0
  349. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +2 -2
  350. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +3 -1
  351. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +2 -2
  352. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +1 -0
  353. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +2 -2
  354. package/dist/modules/eudr/backend/eudr/statements/page.js +30 -28
  355. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  356. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +4 -1
  357. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +2 -2
  358. package/dist/modules/eudr/commands/statements.js +8 -3
  359. package/dist/modules/eudr/commands/statements.js.map +2 -2
  360. package/dist/modules/eudr/components/crudErrorI18n.js +21 -1
  361. package/dist/modules/eudr/components/crudErrorI18n.js.map +2 -2
  362. package/dist/modules/eudr/components/formConfig.js +6 -2
  363. package/dist/modules/eudr/components/formConfig.js.map +2 -2
  364. package/dist/modules/eudr/data/validators.js +1 -4
  365. package/dist/modules/eudr/data/validators.js.map +2 -2
  366. package/dist/modules/eudr/lib/statement-lifecycle.js +9 -1
  367. package/dist/modules/eudr/lib/statement-lifecycle.js.map +2 -2
  368. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +0 -1
  369. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  370. package/dist/modules/feature_toggles/components/OverridesTable.js +0 -1
  371. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  372. package/dist/modules/feature_toggles/defaults.json +8 -0
  373. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +0 -3
  374. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  375. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +0 -3
  376. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  377. package/dist/modules/inbox_ops/lib/htmlToPlainText.js +12 -1
  378. package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
  379. package/dist/modules/integrations/api/[id]/credentials/route.js +1 -6
  380. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  381. package/dist/modules/integrations/backend/integrations/[id]/page.js +29 -38
  382. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  383. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +9 -36
  384. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  385. package/dist/modules/integrations/data/validators.js +3 -11
  386. package/dist/modules/integrations/data/validators.js.map +2 -2
  387. package/dist/modules/integrations/lib/credentials-masking.js +2 -6
  388. package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
  389. package/dist/modules/messages/api/[id]/route.js +1 -29
  390. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  391. package/dist/modules/messages/api/openapi.js +2 -17
  392. package/dist/modules/messages/api/openapi.js.map +2 -2
  393. package/dist/modules/messages/api/route.js +2 -17
  394. package/dist/modules/messages/api/route.js.map +2 -2
  395. package/dist/modules/messages/components/MessagesInboxPageClient.js +14 -7
  396. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  397. package/dist/modules/messages/components/inboxFilters.js +0 -15
  398. package/dist/modules/messages/components/inboxFilters.js.map +2 -2
  399. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +1 -11
  400. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
  401. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +1 -3
  402. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
  403. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +1 -2
  404. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
  405. package/dist/modules/messages/components/messageListLabels.js +2 -14
  406. package/dist/modules/messages/components/messageListLabels.js.map +2 -2
  407. package/dist/modules/messages/data/validators.js +4 -18
  408. package/dist/modules/messages/data/validators.js.map +2 -2
  409. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +6 -4
  410. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  411. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -3
  412. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  413. package/dist/modules/payment_gateways/lib/webhook-processor.js +0 -7
  414. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
  415. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +0 -3
  416. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  417. package/dist/modules/push_notifications/backend/push_notifications/page.js +1 -3
  418. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  419. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
  420. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
  421. package/dist/modules/query_index/lib/engine.js +51 -150
  422. package/dist/modules/query_index/lib/engine.js.map +2 -2
  423. package/dist/modules/query_index/lib/search-tokens.js +3 -79
  424. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  425. package/dist/modules/resources/backend/resources/resource-types/page.js +1 -3
  426. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  427. package/dist/modules/resources/backend/resources/resources/page.js +1 -3
  428. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  429. package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -3
  430. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  431. package/dist/modules/sales/backend/sales/channels/page.js +0 -3
  432. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  433. package/dist/modules/sales/backend/sales/documents/[id]/page.js +8 -10
  434. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  435. package/dist/modules/sales/commands/documents.js +1 -79
  436. package/dist/modules/sales/commands/documents.js.map +2 -2
  437. package/dist/modules/sales/components/PriceWithCurrency.js +5 -7
  438. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  439. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +0 -3
  440. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  441. package/dist/modules/sales/components/documents/AdjustmentsSection.js +6 -8
  442. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  443. package/dist/modules/sales/components/documents/ItemsSection.js +22 -51
  444. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  445. package/dist/modules/sales/components/documents/LineItemDialog.js +19 -84
  446. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  447. package/dist/modules/sales/components/documents/PaymentsSection.js +9 -23
  448. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  449. package/dist/modules/sales/components/documents/ReturnsSection.js +6 -8
  450. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  451. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +14 -68
  452. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  453. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +5 -6
  454. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  455. package/dist/modules/sales/components/documents/ShipmentDialog.js +4 -5
  456. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  457. package/dist/modules/sales/components/documents/ShipmentsSection.js +6 -8
  458. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  459. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  460. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  461. package/dist/modules/sales/data/entities.js +2 -8
  462. package/dist/modules/sales/data/entities.js.map +2 -2
  463. package/dist/modules/sales/extension-points.js +0 -1
  464. package/dist/modules/sales/extension-points.js.map +2 -2
  465. package/dist/modules/sales/setup.js +0 -2
  466. package/dist/modules/sales/setup.js.map +2 -2
  467. package/dist/modules/sales/widgets/injection/document-history/widget.client.js +44 -2
  468. package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
  469. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +2 -10
  470. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
  471. package/dist/modules/sales/widgets/injection-table.js +7 -4
  472. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  473. package/dist/modules/staff/backend/staff/leave-requests/page.js +0 -3
  474. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  475. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +0 -3
  476. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  477. package/dist/modules/staff/backend/staff/team-members/page.js +0 -3
  478. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  479. package/dist/modules/staff/backend/staff/team-roles/page.js +0 -3
  480. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  481. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +0 -3
  482. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  483. package/dist/modules/staff/backend/staff/teams/page.js +0 -3
  484. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  485. package/dist/modules/staff/backend/staff/timesheets/page.js +18 -29
  486. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  487. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +0 -3
  488. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  489. package/dist/modules/sync_excel/lib/adapters/customers.js +0 -1
  490. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  491. package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
  492. package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
  493. package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
  494. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  495. package/dist/modules/warranty_claims/api/portal/claims/route.js +9 -12
  496. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  497. package/dist/modules/warranty_claims/backend/page.js +0 -3
  498. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  499. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +0 -3
  500. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  501. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +0 -3
  502. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  503. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +0 -3
  504. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  505. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +0 -3
  506. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  507. package/dist/modules/wms/api/warehouses/route.js +9 -13
  508. package/dist/modules/wms/api/warehouses/route.js.map +2 -2
  509. package/dist/modules/wms/api/zones/route.js +2 -15
  510. package/dist/modules/wms/api/zones/route.js.map +2 -2
  511. package/dist/modules/wms/commands/configuration.js +9 -121
  512. package/dist/modules/wms/commands/configuration.js.map +2 -2
  513. package/dist/modules/wms/commands/inventory-actions.js +0 -3
  514. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  515. package/dist/modules/wms/commands/shared.js +1 -9
  516. package/dist/modules/wms/commands/shared.js.map +2 -2
  517. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +111 -76
  518. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
  519. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +0 -1
  520. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  521. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +20 -16
  522. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  523. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +10 -6
  524. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  525. package/dist/modules/wms/components/backend/WmsLotsListPage.js +0 -1
  526. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  527. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +11 -7
  528. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  529. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +10 -6
  530. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  531. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +20 -27
  532. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  533. package/dist/modules/workflows/backend/definitions/page.js +1 -3
  534. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  535. package/dist/modules/workflows/backend/events/page.js +1 -3
  536. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  537. package/dist/modules/workflows/backend/instances/page.js +1 -3
  538. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  539. package/dist/modules/workflows/backend/tasks/page.js +1 -3
  540. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  541. package/dist/modules/workflows/lib/activity-executor.js +0 -4
  542. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  543. package/package.json +10 -9
  544. package/src/helpers/integration/api.ts +1 -33
  545. package/src/helpers/integration/communicationChannelsFixtures.ts +1 -69
  546. package/src/modules/api_keys/api/keys/route.ts +1 -3
  547. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -4
  548. package/src/modules/attachments/AGENTS.md +0 -15
  549. package/src/modules/attachments/api/route.ts +2 -2
  550. package/src/modules/attachments/components/AttachmentLibrary.tsx +0 -3
  551. package/src/modules/attachments/di.ts +0 -16
  552. package/src/modules/attachments/i18n/de.json +0 -5
  553. package/src/modules/attachments/i18n/en.json +0 -5
  554. package/src/modules/attachments/i18n/es.json +0 -5
  555. package/src/modules/attachments/i18n/ko.json +0 -5
  556. package/src/modules/attachments/i18n/pl.json +0 -5
  557. package/src/modules/attachments/index.ts +0 -10
  558. package/src/modules/attachments/lib/scoped-upload-service.ts +0 -46
  559. package/src/modules/attachments/lib/upload-limits.ts +2 -6
  560. package/src/modules/audit_logs/backend/audit-logs/page.tsx +0 -8
  561. package/src/modules/audit_logs/lib/display-helpers.tsx +32 -42
  562. package/src/modules/audit_logs/services/actionLogService.ts +11 -74
  563. package/src/modules/auth/acl.ts +6 -30
  564. package/src/modules/auth/api/feature-check.ts +3 -10
  565. package/src/modules/auth/api/login.ts +24 -9
  566. package/src/modules/auth/api/roles/acl/route.ts +39 -42
  567. package/src/modules/auth/api/routeError.ts +30 -0
  568. package/src/modules/auth/api/session/refresh.ts +1 -32
  569. package/src/modules/auth/api/users/acl/route.ts +101 -185
  570. package/src/modules/auth/api/users/route.ts +5 -18
  571. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +2 -5
  572. package/src/modules/auth/backend/roles/page.tsx +2 -4
  573. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +2 -5
  574. package/src/modules/auth/backend/users/page.tsx +2 -3
  575. package/src/modules/auth/components/AclEditor.tsx +33 -63
  576. package/src/modules/auth/data/entities.ts +1 -4
  577. package/src/modules/auth/data/validators.ts +0 -5
  578. package/src/modules/auth/di.ts +16 -46
  579. package/src/modules/auth/frontend/reset/[token]/page.tsx +0 -74
  580. package/src/modules/auth/i18n/de.json +0 -389
  581. package/src/modules/auth/i18n/en.json +0 -389
  582. package/src/modules/auth/i18n/es.json +0 -389
  583. package/src/modules/auth/i18n/ko.json +0 -389
  584. package/src/modules/auth/i18n/pl.json +2 -391
  585. package/src/modules/auth/lib/grantChecks.ts +0 -6
  586. package/src/modules/auth/services/authService.ts +2 -18
  587. package/src/modules/auth/services/rbacService.ts +24 -110
  588. package/src/modules/business_rules/backend/logs/page.tsx +1 -4
  589. package/src/modules/business_rules/backend/rules/[id]/page.meta.ts +5 -0
  590. package/src/modules/business_rules/backend/rules/create/page.meta.ts +5 -1
  591. package/src/modules/business_rules/backend/rules/page.tsx +1 -4
  592. package/src/modules/business_rules/backend/sets/[id]/page.meta.ts +5 -0
  593. package/src/modules/business_rules/backend/sets/create/page.meta.ts +5 -1
  594. package/src/modules/business_rules/backend/sets/page.tsx +1 -4
  595. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  596. package/src/modules/business_rules/lib/rule-evaluator.ts +9 -10
  597. package/src/modules/catalog/ai-agents.ts +1 -1
  598. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  599. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +5 -12
  600. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +0 -3
  601. package/src/modules/catalog/components/products/ProductsDataTable.tsx +0 -7
  602. package/src/modules/catalog/i18n/de.json +0 -1
  603. package/src/modules/catalog/i18n/en.json +0 -1
  604. package/src/modules/catalog/i18n/es.json +0 -1
  605. package/src/modules/catalog/i18n/ko.json +0 -1
  606. package/src/modules/catalog/i18n/pl.json +0 -1
  607. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +0 -4
  608. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +1 -17
  609. package/src/modules/communication_channels/api/post/test-seed/route.ts +16 -155
  610. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +0 -4
  611. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +1 -38
  612. package/src/modules/communication_channels/di.ts +0 -7
  613. package/src/modules/communication_channels/lib/adapter.ts +0 -14
  614. package/src/modules/communication_channels/lib/email-capabilities.ts +0 -4
  615. package/src/modules/communication_channels/lib/test-seed.ts +4 -64
  616. package/src/modules/configs/i18n/de.json +0 -2
  617. package/src/modules/configs/i18n/en.json +0 -2
  618. package/src/modules/configs/i18n/es.json +0 -2
  619. package/src/modules/configs/i18n/ko.json +0 -2
  620. package/src/modules/configs/i18n/pl.json +0 -2
  621. package/src/modules/configs/lib/system-status.ts +0 -9
  622. package/src/modules/currencies/backend/currencies/page.tsx +1 -4
  623. package/src/modules/currencies/backend/exchange-rates/page.tsx +1 -4
  624. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +0 -7
  625. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +1 -4
  626. package/src/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.tsx +138 -0
  627. package/src/modules/customer_accounts/backend/customer_accounts/settings/page.tsx +8 -132
  628. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +598 -0
  629. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.tsx +838 -0
  630. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +6 -838
  631. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +6 -590
  632. package/src/modules/customer_accounts/extension-points.ts +1 -1
  633. package/src/modules/customer_accounts/lib/portalUrl.ts +112 -0
  634. package/src/modules/customer_accounts/services/domainMappingService.ts +0 -10
  635. package/src/modules/customers/ai-tools/companies-pack.ts +1 -4
  636. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +2 -17
  637. package/src/modules/customers/ai-tools/deals-pack.ts +1 -66
  638. package/src/modules/customers/ai-tools/people-pack.ts +1 -4
  639. package/src/modules/customers/api/activities/route.ts +0 -45
  640. package/src/modules/customers/api/companies/[id]/people/route.ts +73 -24
  641. package/src/modules/customers/api/companies/[id]/route.ts +107 -24
  642. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +8 -16
  643. package/src/modules/customers/api/deals/[id]/companies/route.ts +1 -4
  644. package/src/modules/customers/api/deals/[id]/people/route.ts +1 -4
  645. package/src/modules/customers/api/deals/[id]/route.ts +28 -17
  646. package/src/modules/customers/api/deals/[id]/stats/route.ts +25 -10
  647. package/src/modules/customers/api/deals/aggregate/route.ts +4 -14
  648. package/src/modules/customers/api/deals/map/route.ts +0 -1
  649. package/src/modules/customers/api/deals/route.ts +1 -50
  650. package/src/modules/customers/api/entity-roles-factory.ts +4 -8
  651. package/src/modules/customers/api/interactions/route.ts +2 -8
  652. package/src/modules/customers/api/interactions/tasks/route.ts +1 -24
  653. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +4 -12
  654. package/src/modules/customers/api/people/[id]/companies/context.ts +1 -4
  655. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +1 -4
  656. package/src/modules/customers/api/people/[id]/route.ts +11 -16
  657. package/src/modules/customers/api/people/check-phone/route.ts +10 -75
  658. package/src/modules/customers/api/todos/route.ts +2 -27
  659. package/src/modules/customers/backend/customers/companies/page.tsx +4 -7
  660. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +2 -7
  661. package/src/modules/customers/backend/customers/deals/page.tsx +4 -10
  662. package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +14 -5
  663. package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +27 -109
  664. package/src/modules/customers/backend/customers/people/page.tsx +4 -7
  665. package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +4 -12
  666. package/src/modules/customers/commands/deals.ts +59 -34
  667. package/src/modules/customers/commands/interactions.ts +1 -1
  668. package/src/modules/customers/commands/personCompanyLinks.ts +8 -224
  669. package/src/modules/customers/components/CustomerTodosTable.tsx +0 -2
  670. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  671. package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
  672. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
  673. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  674. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
  675. package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
  676. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +2 -4
  677. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +5 -61
  678. package/src/modules/customers/components/calendar/editor/hooks.ts +1 -7
  679. package/src/modules/customers/components/calendar/types.ts +2 -2
  680. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +12 -7
  681. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +4 -5
  682. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +1 -8
  683. package/src/modules/customers/components/detail/DealForm.tsx +2 -22
  684. package/src/modules/customers/components/detail/DealsSection.tsx +5 -11
  685. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +12 -58
  686. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +1 -8
  687. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +14 -23
  688. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
  689. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
  690. package/src/modules/customers/components/detail/types.ts +1 -1
  691. package/src/modules/customers/components/detail/utils.ts +5 -15
  692. package/src/modules/customers/data/entities.ts +1 -1
  693. package/src/modules/customers/data/validators.ts +9 -50
  694. package/src/modules/customers/events.ts +0 -5
  695. package/src/modules/customers/i18n/de.json +1 -9
  696. package/src/modules/customers/i18n/en.json +1 -9
  697. package/src/modules/customers/i18n/es.json +1 -9
  698. package/src/modules/customers/i18n/ko.json +1 -9
  699. package/src/modules/customers/i18n/pl.json +1 -9
  700. package/src/modules/customers/lib/calendar/conflicts.ts +2 -10
  701. package/src/modules/customers/lib/calendar/editorPayload.ts +3 -4
  702. package/src/modules/customers/lib/calendar/mapItem.ts +3 -8
  703. package/src/modules/customers/lib/dealStatus.ts +0 -42
  704. package/src/modules/customers/lib/findPeopleByAddresses.ts +6 -8
  705. package/src/modules/customers/lib/personCompanies.ts +1 -136
  706. package/src/modules/customers/lib/todoCompatibility.ts +1 -19
  707. package/src/modules/dashboards/i18n/es.json +4 -4
  708. package/src/modules/dashboards/i18n/pl.json +7 -7
  709. package/src/modules/dashboards/lib/widgetScope.ts +0 -6
  710. package/src/modules/data_sync/AGENTS.md +1 -1
  711. package/src/modules/data_sync/backend/data-sync/page.tsx +1 -4
  712. package/src/modules/data_sync/lib/adapter.ts +0 -36
  713. package/src/modules/data_sync/lib/sync-engine.ts +5 -113
  714. package/src/modules/data_sync/workers/sync-export.ts +0 -4
  715. package/src/modules/data_sync/workers/sync-import.ts +0 -4
  716. package/src/modules/devices/AGENTS.md +1 -20
  717. package/src/modules/devices/acl.ts +1 -9
  718. package/src/modules/devices/api/admin/devices/[id]/route.ts +34 -5
  719. package/src/modules/devices/api/admin/devices/route.ts +1 -14
  720. package/src/modules/devices/api/deviceList.ts +11 -135
  721. package/src/modules/devices/api/openapi.ts +1 -9
  722. package/src/modules/devices/api/route.ts +1 -9
  723. package/src/modules/devices/backend/devices/[id]/page.tsx +32 -18
  724. package/src/modules/devices/backend/devices/create/page.tsx +1 -17
  725. package/src/modules/devices/backend/devices/page.tsx +45 -44
  726. package/src/modules/devices/i18n/de.json +2 -3
  727. package/src/modules/devices/i18n/en.json +2 -3
  728. package/src/modules/devices/i18n/es.json +2 -3
  729. package/src/modules/devices/i18n/ko.json +2 -3
  730. package/src/modules/devices/i18n/pl.json +2 -3
  731. package/src/modules/devices/setup.ts +2 -6
  732. package/src/modules/directory/backend/directory/organizations/page.tsx +1 -3
  733. package/src/modules/directory/backend/directory/tenants/page.tsx +1 -3
  734. package/src/modules/directory/di.ts +2 -14
  735. package/src/modules/directory/utils/organizationScope.ts +15 -4
  736. package/src/modules/entities/api/records.ts +0 -2
  737. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +1 -4
  738. package/src/modules/eudr/api/plots/route.ts +0 -4
  739. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +2 -0
  740. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +1 -0
  741. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +4 -1
  742. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +0 -4
  743. package/src/modules/eudr/backend/eudr/page.meta.ts +2 -2
  744. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +2 -0
  745. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +8 -2
  746. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +1 -0
  747. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +8 -2
  748. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +4 -1
  749. package/src/modules/eudr/backend/eudr/plots/page.tsx +0 -4
  750. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +2 -0
  751. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +1 -0
  752. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +4 -1
  753. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +0 -4
  754. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +2 -0
  755. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +1 -0
  756. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +4 -1
  757. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +0 -4
  758. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +2 -0
  759. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +2 -0
  760. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +1 -0
  761. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +4 -1
  762. package/src/modules/eudr/backend/eudr/statements/page.tsx +32 -30
  763. package/src/modules/eudr/commands/statements.ts +7 -2
  764. package/src/modules/eudr/components/crudErrorI18n.ts +31 -0
  765. package/src/modules/eudr/components/formConfig.tsx +9 -1
  766. package/src/modules/eudr/data/validators.ts +1 -16
  767. package/src/modules/eudr/i18n/de.json +3 -2
  768. package/src/modules/eudr/i18n/en.json +3 -2
  769. package/src/modules/eudr/i18n/es.json +3 -2
  770. package/src/modules/eudr/i18n/ko.json +3 -2
  771. package/src/modules/eudr/i18n/pl.json +3 -2
  772. package/src/modules/eudr/lib/statement-lifecycle.ts +8 -0
  773. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +1 -2
  774. package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -2
  775. package/src/modules/feature_toggles/defaults.json +8 -0
  776. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +0 -4
  777. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +0 -4
  778. package/src/modules/inbox_ops/lib/htmlToPlainText.ts +17 -1
  779. package/src/modules/integrations/api/[id]/credentials/route.ts +4 -6
  780. package/src/modules/integrations/backend/integrations/[id]/page.tsx +31 -61
  781. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +9 -44
  782. package/src/modules/integrations/data/validators.ts +2 -12
  783. package/src/modules/integrations/i18n/de.json +0 -1
  784. package/src/modules/integrations/i18n/en.json +0 -1
  785. package/src/modules/integrations/i18n/es.json +0 -1
  786. package/src/modules/integrations/i18n/ko.json +0 -1
  787. package/src/modules/integrations/i18n/pl.json +0 -1
  788. package/src/modules/integrations/lib/credentials-masking.ts +6 -10
  789. package/src/modules/messages/api/[id]/route.ts +1 -55
  790. package/src/modules/messages/api/openapi.ts +0 -20
  791. package/src/modules/messages/api/route.ts +2 -31
  792. package/src/modules/messages/components/MessagesInboxPageClient.tsx +16 -9
  793. package/src/modules/messages/components/inboxFilters.ts +0 -36
  794. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +1 -14
  795. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +1 -3
  796. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +1 -2
  797. package/src/modules/messages/components/message-detail/types.ts +0 -3
  798. package/src/modules/messages/components/messageListLabels.ts +3 -52
  799. package/src/modules/messages/data/validators.ts +4 -43
  800. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +6 -4
  801. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -4
  802. package/src/modules/payment_gateways/lib/webhook-processor.ts +0 -11
  803. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +0 -4
  804. package/src/modules/push_notifications/backend/push_notifications/page.tsx +1 -4
  805. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
  806. package/src/modules/query_index/lib/engine.ts +61 -249
  807. package/src/modules/query_index/lib/search-tokens.ts +3 -135
  808. package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -4
  809. package/src/modules/resources/backend/resources/resources/page.tsx +1 -4
  810. package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -4
  811. package/src/modules/sales/backend/sales/channels/page.tsx +0 -4
  812. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +8 -14
  813. package/src/modules/sales/commands/documents.ts +0 -93
  814. package/src/modules/sales/components/PriceWithCurrency.tsx +5 -17
  815. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +0 -4
  816. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +5 -6
  817. package/src/modules/sales/components/documents/ItemsSection.tsx +18 -56
  818. package/src/modules/sales/components/documents/LineItemDialog.tsx +21 -138
  819. package/src/modules/sales/components/documents/PaymentsSection.tsx +9 -20
  820. package/src/modules/sales/components/documents/ReturnsSection.tsx +5 -6
  821. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +14 -106
  822. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +5 -6
  823. package/src/modules/sales/components/documents/ShipmentDialog.tsx +4 -5
  824. package/src/modules/sales/components/documents/ShipmentsSection.tsx +5 -6
  825. package/src/modules/sales/components/documents/lineItemUtils.ts +2 -7
  826. package/src/modules/sales/data/entities.ts +0 -6
  827. package/src/modules/sales/extension-points.ts +0 -1
  828. package/src/modules/sales/i18n/de.json +37 -8
  829. package/src/modules/sales/i18n/en.json +37 -8
  830. package/src/modules/sales/i18n/es.json +37 -8
  831. package/src/modules/sales/i18n/ko.json +37 -8
  832. package/src/modules/sales/i18n/pl.json +37 -8
  833. package/src/modules/sales/migrations/.snapshot-open-mercato.json +0 -60
  834. package/src/modules/sales/setup.ts +0 -2
  835. package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +42 -2
  836. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +1 -9
  837. package/src/modules/sales/widgets/injection-table.ts +7 -4
  838. package/src/modules/staff/backend/staff/leave-requests/page.tsx +0 -4
  839. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +0 -4
  840. package/src/modules/staff/backend/staff/team-members/page.tsx +0 -6
  841. package/src/modules/staff/backend/staff/team-roles/page.tsx +0 -4
  842. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +0 -4
  843. package/src/modules/staff/backend/staff/teams/page.tsx +0 -4
  844. package/src/modules/staff/backend/staff/timesheets/page.tsx +1 -12
  845. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +0 -4
  846. package/src/modules/sync_excel/lib/adapters/customers.ts +0 -5
  847. package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
  848. package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
  849. package/src/modules/warranty_claims/api/portal/claims/route.ts +9 -12
  850. package/src/modules/warranty_claims/backend/page.tsx +0 -4
  851. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +0 -4
  852. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +0 -4
  853. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +0 -4
  854. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +0 -4
  855. package/src/modules/wms/api/warehouses/route.ts +9 -13
  856. package/src/modules/wms/api/zones/route.ts +0 -16
  857. package/src/modules/wms/commands/configuration.ts +10 -159
  858. package/src/modules/wms/commands/inventory-actions.ts +0 -3
  859. package/src/modules/wms/commands/shared.ts +0 -17
  860. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +141 -95
  861. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +0 -2
  862. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +30 -26
  863. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +21 -17
  864. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +0 -2
  865. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +17 -13
  866. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +16 -12
  867. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -36
  868. package/src/modules/wms/i18n/de.json +0 -2
  869. package/src/modules/wms/i18n/en.json +0 -2
  870. package/src/modules/wms/i18n/es.json +0 -2
  871. package/src/modules/wms/i18n/ko.json +0 -2
  872. package/src/modules/wms/i18n/pl.json +0 -2
  873. package/src/modules/workflows/backend/definitions/page.tsx +1 -4
  874. package/src/modules/workflows/backend/events/page.tsx +1 -4
  875. package/src/modules/workflows/backend/instances/page.tsx +1 -4
  876. package/src/modules/workflows/backend/tasks/page.tsx +1 -4
  877. package/src/modules/workflows/lib/activity-executor.ts +0 -9
  878. package/dist/modules/api_keys/di.js +0 -9
  879. package/dist/modules/api_keys/di.js.map +0 -7
  880. package/dist/modules/api_keys/services/principalService.js +0 -31
  881. package/dist/modules/api_keys/services/principalService.js.map +0 -7
  882. package/dist/modules/attachments/lib/attachment-service.js +0 -313
  883. package/dist/modules/attachments/lib/attachment-service.js.map +0 -7
  884. package/dist/modules/auth/api/reset/validate.js +0 -55
  885. package/dist/modules/auth/api/reset/validate.js.map +0 -7
  886. package/dist/modules/auth/commands/acl.js +0 -254
  887. package/dist/modules/auth/commands/acl.js.map +0 -7
  888. package/dist/modules/auth/lib/userIdFilter.js +0 -16
  889. package/dist/modules/auth/lib/userIdFilter.js.map +0 -7
  890. package/dist/modules/auth/services/principalService.js +0 -200
  891. package/dist/modules/auth/services/principalService.js.map +0 -7
  892. package/dist/modules/auth/services/roleOrganizationScope.js +0 -41
  893. package/dist/modules/auth/services/roleOrganizationScope.js.map +0 -7
  894. package/dist/modules/communication_channels/lib/outbound-recipient.js +0 -33
  895. package/dist/modules/communication_channels/lib/outbound-recipient.js.map +0 -7
  896. package/dist/modules/communication_channels/lib/resolve-channel-type.js +0 -51
  897. package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +0 -7
  898. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +0 -18
  899. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +0 -7
  900. package/dist/modules/customers/lib/calendar/participantIdentity.js +0 -9
  901. package/dist/modules/customers/lib/calendar/participantIdentity.js.map +0 -7
  902. package/dist/modules/customers/lib/closureStage.js +0 -45
  903. package/dist/modules/customers/lib/closureStage.js.map +0 -7
  904. package/dist/modules/customers/lib/detailReadAccess.js +0 -12
  905. package/dist/modules/customers/lib/detailReadAccess.js.map +0 -7
  906. package/dist/modules/data_sync/lib/abandoned-run.js +0 -19
  907. package/dist/modules/data_sync/lib/abandoned-run.js.map +0 -7
  908. package/dist/modules/devices/api/deviceSerialization.js +0 -46
  909. package/dist/modules/devices/api/deviceSerialization.js.map +0 -7
  910. package/dist/modules/devices/backend/devices/useDeviceUserLabels.js +0 -34
  911. package/dist/modules/devices/backend/devices/useDeviceUserLabels.js.map +0 -7
  912. package/dist/modules/devices/backend/devices/userOptions.js +0 -52
  913. package/dist/modules/devices/backend/devices/userOptions.js.map +0 -7
  914. package/dist/modules/directory/services/organizationHierarchyService.js +0 -29
  915. package/dist/modules/directory/services/organizationHierarchyService.js.map +0 -7
  916. package/dist/modules/directory/services/organizationScopeService.js +0 -56
  917. package/dist/modules/directory/services/organizationScopeService.js.map +0 -7
  918. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +0 -55
  919. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +0 -7
  920. package/dist/modules/messages/lib/channel-sender-identity.js +0 -26
  921. package/dist/modules/messages/lib/channel-sender-identity.js.map +0 -7
  922. package/dist/modules/messages/lib/composeSourceChannelType.js +0 -41
  923. package/dist/modules/messages/lib/composeSourceChannelType.js.map +0 -7
  924. package/dist/modules/query_index/lib/search-entity-policy.js +0 -14
  925. package/dist/modules/query_index/lib/search-entity-policy.js.map +0 -7
  926. package/dist/modules/sales/components/documents/lineItemShipmentLock.js +0 -54
  927. package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +0 -7
  928. package/dist/modules/sales/lib/salesChannelsToggleSeed.js +0 -33
  929. package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +0 -7
  930. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +0 -32
  931. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +0 -7
  932. package/dist/modules/wms/api/warehouseSearch.js +0 -21
  933. package/dist/modules/wms/api/warehouseSearch.js.map +0 -7
  934. package/dist/modules/wms/components/backend/WarehouseEditDialog.js +0 -158
  935. package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +0 -7
  936. package/dist/modules/wms/components/backend/warehouseFormOptions.js +0 -66
  937. package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +0 -7
  938. package/src/modules/api_keys/di.ts +0 -7
  939. package/src/modules/api_keys/services/principalService.ts +0 -33
  940. package/src/modules/attachments/lib/attachment-service.ts +0 -468
  941. package/src/modules/auth/api/reset/validate.ts +0 -57
  942. package/src/modules/auth/commands/acl.ts +0 -495
  943. package/src/modules/auth/lib/userIdFilter.ts +0 -31
  944. package/src/modules/auth/services/principalService.ts +0 -266
  945. package/src/modules/auth/services/roleOrganizationScope.ts +0 -70
  946. package/src/modules/communication_channels/lib/outbound-recipient.ts +0 -71
  947. package/src/modules/communication_channels/lib/resolve-channel-type.ts +0 -99
  948. package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +0 -21
  949. package/src/modules/customers/lib/calendar/participantIdentity.ts +0 -17
  950. package/src/modules/customers/lib/closureStage.ts +0 -76
  951. package/src/modules/customers/lib/detailReadAccess.ts +0 -35
  952. package/src/modules/data_sync/lib/abandoned-run.ts +0 -56
  953. package/src/modules/devices/api/deviceSerialization.ts +0 -50
  954. package/src/modules/devices/backend/devices/useDeviceUserLabels.ts +0 -45
  955. package/src/modules/devices/backend/devices/userOptions.ts +0 -99
  956. package/src/modules/directory/services/organizationHierarchyService.ts +0 -34
  957. package/src/modules/directory/services/organizationScopeService.ts +0 -85
  958. package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +0 -84
  959. package/src/modules/messages/lib/channel-sender-identity.ts +0 -55
  960. package/src/modules/messages/lib/composeSourceChannelType.ts +0 -95
  961. package/src/modules/query_index/lib/search-entity-policy.ts +0 -46
  962. package/src/modules/sales/components/documents/lineItemShipmentLock.ts +0 -74
  963. package/src/modules/sales/lib/salesChannelsToggleSeed.ts +0 -42
  964. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +0 -87
  965. package/src/modules/wms/api/warehouseSearch.ts +0 -23
  966. package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +0 -216
  967. package/src/modules/wms/components/backend/warehouseFormOptions.ts +0 -72
@@ -8,11 +8,6 @@ import {
8
8
  CustomerDeal,
9
9
  CustomerPipelineStage
10
10
  } from "../data/entities.js";
11
- import {
12
- dealClosureOutcomeFromStatus,
13
- loadClosurePipelineStageSnapshot
14
- } from "../lib/closureStage.js";
15
- import { canonicalDealStatus, isClosedDealStatus } from "../lib/dealStatus.js";
16
11
  import {
17
12
  assertTenantScope
18
13
  } from "./types.js";
@@ -34,7 +29,7 @@ const listDealsInput = z.object({
34
29
  const listDealsTool = defineApiBackedAiTool({
35
30
  name: "customers.list_deals",
36
31
  displayName: "List deals",
37
- description: 'Search / list deals for the caller tenant + organization. Optional filters include linked person / company / pipeline stage. Returns { items, total, totalIsCapped, limit, offset }. When totalIsCapped is true, total is a floor ("at least N", render it as "N+"), and pagination is exhausted only when a page returns fewer than limit items \u2014 never when offset reaches total.',
32
+ description: "Search / list deals for the caller tenant + organization. Optional filters include linked person / company / pipeline stage.",
38
33
  inputSchema: listDealsInput,
39
34
  requiredFeatures: ["customers.deals.view"],
40
35
  toOperation: (input, ctx) => {
@@ -88,9 +83,6 @@ const listDealsTool = defineApiBackedAiTool({
88
83
  };
89
84
  }),
90
85
  total: typeof data.total === "number" ? data.total : 0,
91
- // A capped count reports a floor: phrase the total as "at least N" and
92
- // never treat it as proof that pagination is exhausted.
93
- totalIsCapped: data.totalIsCapped === true,
94
86
  limit,
95
87
  offset
96
88
  };
@@ -306,72 +298,34 @@ const updateDealStageTool = {
306
298
  afterPipelineStageLabel = stage?.label ?? input.toPipelineStageId;
307
299
  } else if (input.toStage) {
308
300
  afterStatus = input.toStage;
309
- const organizationId = deal.organizationId ?? ctx.organizationId ?? null;
310
- const outcome = dealClosureOutcomeFromStatus(input.toStage);
311
- if (outcome && organizationId) {
312
- const terminalStage = await loadClosurePipelineStageSnapshot(em, {
313
- pipelineId: deal.pipelineId ?? null,
314
- closureOutcome: outcome,
315
- tenantId,
316
- organizationId
317
- });
318
- if (terminalStage) {
319
- afterPipelineStageId = terminalStage.id;
320
- afterPipelineStageLabel = terminalStage.label;
321
- }
322
- }
323
301
  }
324
302
  const beforeStatus = deal.status ?? null;
325
303
  const beforePipelineStageId = deal.pipelineStageId ?? null;
326
304
  const beforePipelineStageLabel = deal.pipelineStage ?? beforePipelineStageId;
327
- const beforeClosureOutcome = deal.closureOutcome ?? null;
328
- const beforeLossReasonId = deal.lossReasonId ?? null;
329
- const beforeLossNotes = deal.lossNotes ?? null;
330
- const requestedOutcome = dealClosureOutcomeFromStatus(input.toStage);
331
- const clearsClosure = input.toPipelineStageId === void 0 && input.toStage !== void 0 && !requestedOutcome && !isClosedDealStatus(canonicalDealStatus(input.toStage));
332
- const afterClosureOutcome = clearsClosure ? null : requestedOutcome ?? beforeClosureOutcome;
333
- const closureOutcomeCleared = beforeClosureOutcome !== null && afterClosureOutcome === null;
334
- const afterLossReasonId = closureOutcomeCleared ? null : beforeLossReasonId;
335
- const afterLossNotes = closureOutcomeCleared ? null : beforeLossNotes;
336
305
  return {
337
306
  recordId: deal.id,
338
307
  entityType: "customers.deal",
339
308
  recordVersion: recordVersionFromUpdatedAt(deal.updatedAt),
340
309
  before: {
341
310
  status: beforeStatus,
342
- pipelineStageId: beforePipelineStageId,
343
- closureOutcome: beforeClosureOutcome,
344
- lossReasonId: beforeLossReasonId,
345
- lossNotes: beforeLossNotes
311
+ pipelineStageId: beforePipelineStageId
346
312
  },
347
313
  after: {
348
314
  status: afterStatus,
349
- pipelineStageId: afterPipelineStageId,
350
- closureOutcome: afterClosureOutcome,
351
- lossReasonId: afterLossReasonId,
352
- lossNotes: afterLossNotes
315
+ pipelineStageId: afterPipelineStageId
353
316
  },
354
317
  display: {
355
318
  fieldLabels: {
356
319
  status: "Status",
357
- pipelineStageId: "Pipeline stage",
358
- closureOutcome: "Closure outcome",
359
- lossReasonId: "Loss reason",
360
- lossNotes: "Loss notes"
320
+ pipelineStageId: "Pipeline stage"
361
321
  },
362
322
  before: {
363
323
  ...beforeStatus ? { status: titleStatus(beforeStatus) } : {},
364
- ...beforePipelineStageLabel ? { pipelineStageId: beforePipelineStageLabel } : {},
365
- ...beforeClosureOutcome ? { closureOutcome: titleStatus(beforeClosureOutcome) } : {},
366
- ...beforeLossReasonId ? { lossReasonId: beforeLossReasonId } : {},
367
- ...beforeLossNotes ? { lossNotes: beforeLossNotes } : {}
324
+ ...beforePipelineStageLabel ? { pipelineStageId: beforePipelineStageLabel } : {}
368
325
  },
369
326
  after: {
370
327
  ...afterStatus ? { status: titleStatus(afterStatus) } : {},
371
- ...afterPipelineStageLabel ? { pipelineStageId: afterPipelineStageLabel } : {},
372
- ...afterClosureOutcome ? { closureOutcome: titleStatus(afterClosureOutcome) } : closureOutcomeCleared ? { closureOutcome: "\u2014" } : {},
373
- ...afterLossReasonId ? { lossReasonId: afterLossReasonId } : {},
374
- ...afterLossNotes ? { lossNotes: afterLossNotes } : {}
328
+ ...afterPipelineStageLabel ? { pipelineStageId: afterPipelineStageLabel } : {}
375
329
  }
376
330
  }
377
331
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/ai-tools/deals-pack.ts"],
4
- "sourcesContent": ["/**\n * `customers.list_deals` + `customers.get_deal` (Phase 1 WS-C, Step 3.9).\n * `customers.update_deal_stage` mutation tool (Phase 3 WS-C, Step 5.13).\n *\n * Phase 3a of `.ai/specs/implemented/2026-04-27-ai-tools-api-backed-dry-refactor.md`:\n * `customers.list_deals` is now an API-backed wrapper over\n * `GET /api/customers/deals`. Tool name, schema, requiredFeatures, and output\n * shape are unchanged.\n *\n * Phase 3c of the same spec migrates `customers.get_deal` to the documented\n * aggregate detail route. The handler issues 1 call without `includeRelated`\n * (`GET /customers/deals/<id>`) and 3 bounded calls with `includeRelated`\n * (deal detail + activities + comments by `dealId`). The 3-call cap matches\n * the spec's residual N+1 budget; deeper aggregation can earn a first-class\n * API later without touching the AI surface.\n */\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { defineApiBackedAiTool } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool'\nimport {\n createAiApiOperationRunner,\n type AiApiOperationRequest,\n type AiToolExecutionContext,\n} from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n CustomerDeal,\n CustomerPipelineStage,\n} from '../data/entities'\nimport {\n dealClosureOutcomeFromStatus,\n loadClosurePipelineStageSnapshot,\n} from '../lib/closureStage'\nimport { canonicalDealStatus, isClosedDealStatus } from '../lib/dealStatus'\nimport {\n assertTenantScope,\n type CustomersAiToolDefinition,\n type CustomersToolContext,\n type CustomersToolLoadBeforeSingleRecord,\n} from './types'\n\nfunction resolveEm(ctx: CustomersToolContext | AiToolExecutionContext): EntityManager {\n return ctx.container.resolve<EntityManager>('em')\n}\n\nfunction buildScope(ctx: CustomersToolContext | AiToolExecutionContext, tenantId: string) {\n return { tenantId, organizationId: ctx.organizationId }\n}\n\nconst listDealsInput = z\n .object({\n q: z.string().trim().optional().describe('Search text matched against deal title / description. Omit or leave empty to list all.'),\n limit: z.number().int().min(1).max(100).optional().describe('Maximum rows to return (default 50, max 100).'),\n offset: z.number().int().min(0).optional().describe('Number of rows to skip (default 0).'),\n personId: z.string().uuid().optional().describe('Return only deals linked to this person entity id.'),\n companyId: z.string().uuid().optional().describe('Return only deals linked to this company entity id.'),\n pipelineStageId: z.string().uuid().optional().describe('Return only deals at this pipeline stage.'),\n status: z.string().optional().describe('Filter by deal status (e.g. \"open\", \"won\", \"lost\").'),\n })\n .passthrough()\n\ntype ListDealsInput = z.infer<typeof listDealsInput>\n\ntype ListDealsApiItem = {\n id?: string\n title?: string | null\n description?: string | null\n status?: string | null\n pipeline_id?: string | null\n pipelineId?: string | null\n pipeline_stage_id?: string | null\n pipelineStageId?: string | null\n value_amount?: string | number | null\n valueAmount?: string | number | null\n value_currency?: string | null\n valueCurrency?: string | null\n probability?: number | null\n owner_user_id?: string | null\n ownerUserId?: string | null\n expected_close_at?: string | null\n expectedCloseAt?: string | null\n source?: string | null\n organization_id?: string | null\n organizationId?: string | null\n tenant_id?: string | null\n tenantId?: string | null\n created_at?: string | null\n createdAt?: string | null\n}\n\ntype ListDealsApiResponse = {\n items?: ListDealsApiItem[]\n total?: number\n}\n\ntype ListDealsOutput = {\n items: Array<Record<string, unknown>>\n total: number\n limit: number\n offset: number\n}\n\nconst listDealsTool = defineApiBackedAiTool<ListDealsInput, ListDealsApiResponse, ListDealsOutput>({\n name: 'customers.list_deals',\n displayName: 'List deals',\n description:\n 'Search / list deals for the caller tenant + organization. Optional filters include linked person / company / pipeline stage. Returns { items, total, totalIsCapped, limit, offset }. When totalIsCapped is true, total is a floor (\"at least N\", render it as \"N+\"), and pagination is exhausted only when a page returns fewer than limit items \u2014 never when offset reaches total.',\n inputSchema: listDealsInput,\n requiredFeatures: ['customers.deals.view'],\n toOperation: (input, ctx) => {\n assertTenantScope(ctx as unknown as CustomersToolContext)\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const page = Math.floor(offset / limit) + 1\n\n const query: Record<string, string | number | boolean | null | undefined> = {\n page,\n pageSize: limit,\n }\n if (input.q?.trim()) query.search = input.q.trim()\n if (input.personId) query.personId = input.personId\n if (input.companyId) query.companyId = input.companyId\n if (input.pipelineStageId) query.pipelineStageId = input.pipelineStageId\n if (input.status) query.status = input.status\n\n const operation: AiApiOperationRequest = {\n method: 'GET',\n path: '/customers/deals',\n query,\n }\n return operation\n },\n mapResponse: (response, input) => {\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const data = (response.data ?? {}) as ListDealsApiResponse\n const rawItems: ListDealsApiItem[] = Array.isArray(data.items) ? data.items : []\n return {\n items: rawItems.map((row) => {\n const expectedCloseRaw = row.expected_close_at ?? row.expectedCloseAt ?? null\n const expectedCloseAt = expectedCloseRaw ? new Date(String(expectedCloseRaw)).toISOString() : null\n const createdAtRaw = row.created_at ?? row.createdAt ?? null\n const createdAt = createdAtRaw ? new Date(String(createdAtRaw)).toISOString() : null\n return {\n id: row.id,\n title: row.title ?? null,\n description: row.description ?? null,\n status: row.status ?? null,\n pipelineId: row.pipeline_id ?? row.pipelineId ?? null,\n pipelineStageId: row.pipeline_stage_id ?? row.pipelineStageId ?? null,\n valueAmount: row.value_amount ?? row.valueAmount ?? null,\n valueCurrency: row.value_currency ?? row.valueCurrency ?? null,\n probability: row.probability ?? null,\n ownerUserId: row.owner_user_id ?? row.ownerUserId ?? null,\n expectedCloseAt,\n source: row.source ?? null,\n organizationId: row.organization_id ?? row.organizationId ?? null,\n tenantId: row.tenant_id ?? row.tenantId ?? null,\n createdAt,\n }\n }),\n total: typeof data.total === 'number' ? data.total : 0,\n // A capped count reports a floor: phrase the total as \"at least N\" and\n // never treat it as proof that pagination is exhausted.\n totalIsCapped: (data as { totalIsCapped?: boolean }).totalIsCapped === true,\n limit,\n offset,\n }\n },\n}) as unknown as CustomersAiToolDefinition\n\nconst getDealInput = z.object({\n dealId: z.string().uuid().describe('Deal id (UUID).'),\n includeRelated: z\n .boolean()\n .optional()\n .describe('When true, include notes, activities, linked people and companies (each capped at 100).'),\n})\n\ntype GetDealInput = z.infer<typeof getDealInput>\n\nfunction toIsoDeal(value: unknown): string | null {\n if (!value) return null\n const dt = value instanceof Date ? value : new Date(String(value))\n if (Number.isNaN(dt.getTime())) return null\n return dt.toISOString()\n}\n\nconst getDealTool: CustomersAiToolDefinition = {\n name: 'customers.get_deal',\n displayName: 'Get deal',\n description:\n 'Fetch a deal by id with fields and (optionally) notes, activities, linked people, and linked companies. Returns { found: false } when outside tenant/org scope.',\n inputSchema: getDealInput,\n requiredFeatures: ['customers.deals.view'],\n tags: ['read', 'customers'],\n handler: async (rawInput, ctx) => {\n const { tenantId: _tenantId } = assertTenantScope(ctx)\n void _tenantId\n const input: GetDealInput = getDealInput.parse(rawInput)\n const includeRelated = !!input.includeRelated\n const runner = createAiApiOperationRunner(ctx as unknown as AiToolExecutionContext)\n\n const detailResponse = await runner.run<Record<string, unknown>>({\n method: 'GET',\n path: `/customers/deals/${input.dealId}`,\n })\n if (!detailResponse.success) {\n if (detailResponse.statusCode === 404 || detailResponse.statusCode === 403) {\n return { found: false as const, dealId: input.dealId }\n }\n throw new Error(detailResponse.error ?? `Failed to fetch deal ${input.dealId}`)\n }\n const detail = (detailResponse.data ?? {}) as Record<string, unknown>\n const dealRow = (detail.deal ?? null) as Record<string, unknown> | null\n if (!dealRow) {\n return { found: false as const, dealId: input.dealId }\n }\n const customFields = (detail.customFields ?? {}) as Record<string, unknown>\n const peopleRows = Array.isArray(detail.people) ? (detail.people as Array<Record<string, unknown>>) : []\n const companiesRows = Array.isArray(detail.companies)\n ? (detail.companies as Array<Record<string, unknown>>)\n : []\n\n let related: Record<string, unknown> | null = null\n if (includeRelated) {\n const [activitiesResponse, commentsResponse] = await Promise.all([\n runner.run<{ items?: Array<Record<string, unknown>>; total?: number }>({\n method: 'GET',\n path: '/customers/activities',\n query: { dealId: input.dealId, page: 1, pageSize: 100, sortField: 'occurredAt', sortDir: 'desc' },\n }),\n runner.run<{ items?: Array<Record<string, unknown>>; total?: number }>({\n method: 'GET',\n path: '/customers/comments',\n query: { dealId: input.dealId, page: 1, pageSize: 100 },\n }),\n ])\n const activities =\n activitiesResponse.success && Array.isArray(activitiesResponse.data?.items)\n ? (activitiesResponse.data!.items as Array<Record<string, unknown>>)\n : []\n const comments =\n commentsResponse.success && Array.isArray(commentsResponse.data?.items)\n ? (commentsResponse.data!.items as Array<Record<string, unknown>>)\n : []\n\n related = {\n activities: activities.map((activity) => ({\n id: activity.id,\n activityType: activity.activityType ?? activity.activity_type ?? null,\n subject: activity.subject ?? null,\n body: activity.body ?? null,\n occurredAt: toIsoDeal(activity.occurredAt ?? activity.occurred_at),\n createdAt: toIsoDeal(activity.createdAt ?? activity.created_at),\n })),\n notes: comments.map((comment) => ({\n id: comment.id,\n body: comment.body,\n authorUserId: comment.authorUserId ?? comment.author_user_id ?? null,\n createdAt: toIsoDeal(comment.createdAt ?? comment.created_at),\n })),\n people: peopleRows\n .map((person) => {\n if (!person || typeof person !== 'object') return null\n const id = typeof person.id === 'string' ? person.id : null\n if (!id) return null\n const subtitle = typeof person.subtitle === 'string' ? person.subtitle : null\n const label = typeof person.label === 'string' ? person.label : ''\n const entry: {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n participantRole: string | null\n } = {\n id,\n displayName: label,\n primaryEmail: subtitle && subtitle.includes('@') ? subtitle : null,\n primaryPhone: subtitle && !subtitle.includes('@') ? subtitle : null,\n participantRole: null as string | null,\n }\n return entry\n })\n .filter(\n (value): value is {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n participantRole: string | null\n } => value !== null,\n ),\n companies: companiesRows\n .map((company) => {\n if (!company || typeof company !== 'object') return null\n const id = typeof company.id === 'string' ? company.id : null\n if (!id) return null\n const label = typeof company.label === 'string' ? company.label : ''\n const entry: {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n } = {\n id,\n displayName: label,\n primaryEmail: null as string | null,\n primaryPhone: null as string | null,\n }\n return entry\n })\n .filter(\n (value): value is {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n } => value !== null,\n ),\n }\n }\n\n return {\n found: true as const,\n deal: {\n id: dealRow.id,\n title: typeof dealRow.title === 'string' ? dealRow.title : '',\n description: dealRow.description ?? null,\n status: dealRow.status ?? null,\n pipelineId: dealRow.pipelineId ?? null,\n pipelineStageId: dealRow.pipelineStageId ?? null,\n valueAmount: dealRow.valueAmount ?? null,\n valueCurrency: dealRow.valueCurrency ?? null,\n probability: dealRow.probability ?? null,\n ownerUserId: dealRow.ownerUserId ?? null,\n expectedCloseAt: toIsoDeal(dealRow.expectedCloseAt),\n source: dealRow.source ?? null,\n organizationId: dealRow.organizationId ?? null,\n tenantId: dealRow.tenantId ?? null,\n createdAt: toIsoDeal(dealRow.createdAt),\n updatedAt: toIsoDeal(dealRow.updatedAt),\n },\n customFields,\n related,\n }\n },\n}\n\n/**\n * Mutation tool: move a deal to a different pipeline stage. Step 5.13 \u2014 first\n * mutation-capable flow on the pending-action contract.\n *\n * Accepts either `toPipelineStageId` (UUID \u2014 preferred, tenant-scoped stage\n * record) or `toStage` (free-form string that maps to `CustomerDeal.status`\n * for pipeline roots like `open`/`won`/`lost`). Exactly one must be provided.\n *\n * The handler delegates to the existing `customers.deals.update` command so\n * all side effects (audit log, `customers.deal.updated` event, query index\n * refresh, notifications) stay identical to a direct API write.\n */\n// LLMs frequently emit `\"\"` for \"not provided\" \u2014 coerce blanks (and surrounding\n// whitespace) to `undefined` BEFORE the per-field validators run so the\n// `.uuid()` check on `toPipelineStageId` does not blow up on an empty string\n// the caller actually meant as \"skip this field\".\nconst blankToUndefined = (value: unknown): unknown => {\n if (typeof value !== 'string') return value\n const trimmed = value.trim()\n return trimmed.length === 0 ? undefined : trimmed\n}\n\nconst updateDealStageInput = z\n .object({\n dealId: z.string().uuid().describe('Deal id (UUID) to update.'),\n toPipelineStageId: z\n .preprocess(blankToUndefined, z.string().uuid().optional())\n .describe('Target pipeline stage id (UUID). Preferred \u2014 tenant-scoped stage record.'),\n toStage: z\n .preprocess(blankToUndefined, z.string().min(1).max(50).optional())\n .describe(\n 'Target status slug (e.g. \"open\", \"won\", \"lost\"). Used when the deal does not belong to a managed pipeline.',\n ),\n })\n .refine(\n (value) => Boolean(value.toPipelineStageId) !== Boolean(value.toStage),\n {\n message: 'Provide exactly one of toPipelineStageId or toStage.',\n path: ['toPipelineStageId'],\n },\n )\n\ntype UpdateDealStageInput = z.infer<typeof updateDealStageInput>\n\nfunction recordVersionFromUpdatedAt(updatedAt: Date | null | undefined): string | null {\n if (!updatedAt) return null\n const value = updatedAt instanceof Date ? updatedAt : new Date(updatedAt)\n if (Number.isNaN(value.getTime())) return null\n return value.toISOString()\n}\n\nfunction titleStatus(value: string | null | undefined): string | undefined {\n if (!value) return undefined\n return value\n .split(/[_\\s-]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n}\n\nasync function loadDealWithStage(\n em: EntityManager,\n ctx: CustomersToolContext,\n tenantId: string,\n dealId: string,\n): Promise<CustomerDeal | null> {\n const where: Record<string, unknown> = { id: dealId, tenantId, deletedAt: null }\n if (ctx.organizationId) where.organizationId = ctx.organizationId\n const deal = await findOneWithDecryption<CustomerDeal>(\n em,\n CustomerDeal,\n where as FilterQuery<CustomerDeal>,\n undefined,\n buildScope(ctx, tenantId),\n )\n if (!deal || deal.tenantId !== tenantId) return null\n if (ctx.organizationId && deal.organizationId !== ctx.organizationId) return null\n return deal\n}\n\nasync function loadPipelineStage(\n em: EntityManager,\n ctx: CustomersToolContext,\n tenantId: string,\n stageId: string,\n organizationId: string,\n): Promise<CustomerPipelineStage | null> {\n return findOneWithDecryption<CustomerPipelineStage>(\n em,\n CustomerPipelineStage,\n {\n id: stageId,\n tenantId,\n organizationId,\n },\n undefined,\n buildScope(ctx, tenantId),\n )\n}\n\nconst updateDealStageTool: CustomersAiToolDefinition = {\n name: 'customers.update_deal_stage',\n displayName: 'Update deal stage',\n description:\n 'Move a deal to a different pipeline stage (by stage id) or change its top-level status (e.g. \"open\", \"won\", \"lost\"). Mutation tool \u2014 flows through the AI pending-action approval gate.',\n inputSchema: updateDealStageInput as z.ZodType<unknown>,\n requiredFeatures: ['customers.deals.manage'],\n tags: ['write', 'customers'],\n isMutation: true,\n loadBeforeRecord: async (rawInput, ctx): Promise<CustomersToolLoadBeforeSingleRecord | null> => {\n const { tenantId } = assertTenantScope(ctx)\n const input: UpdateDealStageInput = updateDealStageInput.parse(rawInput)\n const em = resolveEm(ctx)\n const deal = await loadDealWithStage(em, ctx, tenantId, input.dealId)\n if (!deal) return null\n let afterStatus = deal.status ?? null\n let afterPipelineStageId = deal.pipelineStageId ?? null\n let afterPipelineStageLabel = deal.pipelineStage ?? null\n if (input.toPipelineStageId) {\n const organizationId = deal.organizationId ?? ctx.organizationId ?? null\n const stage = organizationId\n ? await loadPipelineStage(em, ctx, tenantId, input.toPipelineStageId, organizationId)\n : null\n afterPipelineStageId = input.toPipelineStageId\n afterPipelineStageLabel = stage?.label ?? input.toPipelineStageId\n } else if (input.toStage) {\n afterStatus = input.toStage\n // The update command derives a closure outcome from terminal status spellings and\n // relocates the deal to the pipeline's terminal stage (#5107) \u2014 preview that same\n // projection so the approval card states the full blast radius.\n const organizationId = deal.organizationId ?? ctx.organizationId ?? null\n const outcome = dealClosureOutcomeFromStatus(input.toStage)\n if (outcome && organizationId) {\n const terminalStage = await loadClosurePipelineStageSnapshot(em, {\n pipelineId: deal.pipelineId ?? null,\n closureOutcome: outcome,\n tenantId,\n organizationId,\n })\n if (terminalStage) {\n afterPipelineStageId = terminalStage.id\n afterPipelineStageLabel = terminalStage.label\n }\n }\n }\n const beforeStatus = deal.status ?? null\n const beforePipelineStageId = deal.pipelineStageId ?? null\n const beforePipelineStageLabel = deal.pipelineStage ?? beforePipelineStageId\n const beforeClosureOutcome = deal.closureOutcome ?? null\n const beforeLossReasonId = deal.lossReasonId ?? null\n const beforeLossNotes = deal.lossNotes ?? null\n // Mirror the update command exactly (#5107): a status-only write derives the closure\n // outcome for terminal spellings, clears outcome plus loss columns for non-closed\n // non-terminal ones (reopen), and leaves `closed` and stage-only writes untouched.\n // `toStage` is free-form model text, so canonicalize before the `closed` check \u2014 the\n // command does the same, and the two must stay in lockstep or the approval card would\n // preview a different write than the one that lands.\n const requestedOutcome = dealClosureOutcomeFromStatus(input.toStage)\n const clearsClosure =\n input.toPipelineStageId === undefined &&\n input.toStage !== undefined &&\n !requestedOutcome &&\n !isClosedDealStatus(canonicalDealStatus(input.toStage))\n const afterClosureOutcome = clearsClosure\n ? null\n : requestedOutcome ?? beforeClosureOutcome\n const closureOutcomeCleared = beforeClosureOutcome !== null && afterClosureOutcome === null\n const afterLossReasonId = closureOutcomeCleared ? null : beforeLossReasonId\n const afterLossNotes = closureOutcomeCleared ? null : beforeLossNotes\n return {\n recordId: deal.id,\n entityType: 'customers.deal',\n recordVersion: recordVersionFromUpdatedAt(deal.updatedAt),\n before: {\n status: beforeStatus,\n pipelineStageId: beforePipelineStageId,\n closureOutcome: beforeClosureOutcome,\n lossReasonId: beforeLossReasonId,\n lossNotes: beforeLossNotes,\n },\n after: {\n status: afterStatus,\n pipelineStageId: afterPipelineStageId,\n closureOutcome: afterClosureOutcome,\n lossReasonId: afterLossReasonId,\n lossNotes: afterLossNotes,\n },\n display: {\n fieldLabels: {\n status: 'Status',\n pipelineStageId: 'Pipeline stage',\n closureOutcome: 'Closure outcome',\n lossReasonId: 'Loss reason',\n lossNotes: 'Loss notes',\n },\n before: {\n ...(beforeStatus ? { status: titleStatus(beforeStatus) } : {}),\n ...(beforePipelineStageLabel ? { pipelineStageId: beforePipelineStageLabel } : {}),\n ...(beforeClosureOutcome ? { closureOutcome: titleStatus(beforeClosureOutcome) } : {}),\n ...(beforeLossReasonId ? { lossReasonId: beforeLossReasonId } : {}),\n ...(beforeLossNotes ? { lossNotes: beforeLossNotes } : {}),\n },\n after: {\n ...(afterStatus ? { status: titleStatus(afterStatus) } : {}),\n ...(afterPipelineStageLabel ? { pipelineStageId: afterPipelineStageLabel } : {}),\n ...(afterClosureOutcome\n ? { closureOutcome: titleStatus(afterClosureOutcome) }\n : closureOutcomeCleared\n ? { closureOutcome: '\u2014' }\n : {}),\n ...(afterLossReasonId ? { lossReasonId: afterLossReasonId } : {}),\n ...(afterLossNotes ? { lossNotes: afterLossNotes } : {}),\n },\n },\n }\n },\n handler: async (rawInput, ctx) => {\n const { tenantId } = assertTenantScope(ctx)\n const input: UpdateDealStageInput = updateDealStageInput.parse(rawInput)\n const em = resolveEm(ctx)\n const deal = await loadDealWithStage(em, ctx, tenantId, input.dealId)\n if (!deal) {\n throw new Error(`Deal \"${input.dealId}\" is not accessible to the caller.`)\n }\n const organizationId = deal.organizationId\n if (!organizationId) {\n throw new Error(`Deal \"${input.dealId}\" has no organization scope.`)\n }\n\n const before = {\n status: deal.status ?? null,\n pipelineStage: deal.pipelineStage ?? null,\n pipelineStageId: deal.pipelineStageId ?? null,\n }\n\n const body: Record<string, unknown> = {\n id: deal.id,\n tenantId,\n organizationId,\n }\n if (input.toPipelineStageId) {\n const stage = await loadPipelineStage(em, ctx, tenantId, input.toPipelineStageId, organizationId)\n if (!stage) {\n throw new Error('Pipeline stage not found.')\n }\n body.pipelineStageId = input.toPipelineStageId\n } else if (input.toStage) {\n body.status = input.toStage\n }\n\n const runner = createAiApiOperationRunner(ctx as unknown as AiToolExecutionContext)\n const response = await runner.run({\n method: 'PUT',\n path: '/customers/deals',\n body,\n })\n if (!response.success) {\n throw new Error(response.error ?? `Failed to update deal \"${deal.id}\"`)\n }\n\n const after = await loadDealWithStage(em, ctx, tenantId, deal.id)\n return {\n recordId: deal.id,\n commandName: 'customers.deals.update',\n before,\n after: after\n ? {\n status: after.status ?? null,\n pipelineStage: after.pipelineStage ?? null,\n pipelineStageId: after.pipelineStageId ?? null,\n }\n : null,\n }\n },\n}\n\nexport const dealsAiTools: CustomersAiToolDefinition[] = [listDealsTool, getDealTool, updateDealStageTool]\n\nexport default dealsAiTools\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * `customers.list_deals` + `customers.get_deal` (Phase 1 WS-C, Step 3.9).\n * `customers.update_deal_stage` mutation tool (Phase 3 WS-C, Step 5.13).\n *\n * Phase 3a of `.ai/specs/implemented/2026-04-27-ai-tools-api-backed-dry-refactor.md`:\n * `customers.list_deals` is now an API-backed wrapper over\n * `GET /api/customers/deals`. Tool name, schema, requiredFeatures, and output\n * shape are unchanged.\n *\n * Phase 3c of the same spec migrates `customers.get_deal` to the documented\n * aggregate detail route. The handler issues 1 call without `includeRelated`\n * (`GET /customers/deals/<id>`) and 3 bounded calls with `includeRelated`\n * (deal detail + activities + comments by `dealId`). The 3-call cap matches\n * the spec's residual N+1 budget; deeper aggregation can earn a first-class\n * API later without touching the AI surface.\n */\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { defineApiBackedAiTool } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool'\nimport {\n createAiApiOperationRunner,\n type AiApiOperationRequest,\n type AiToolExecutionContext,\n} from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n CustomerDeal,\n CustomerPipelineStage,\n} from '../data/entities'\nimport {\n assertTenantScope,\n type CustomersAiToolDefinition,\n type CustomersToolContext,\n type CustomersToolLoadBeforeSingleRecord,\n} from './types'\n\nfunction resolveEm(ctx: CustomersToolContext | AiToolExecutionContext): EntityManager {\n return ctx.container.resolve<EntityManager>('em')\n}\n\nfunction buildScope(ctx: CustomersToolContext | AiToolExecutionContext, tenantId: string) {\n return { tenantId, organizationId: ctx.organizationId }\n}\n\nconst listDealsInput = z\n .object({\n q: z.string().trim().optional().describe('Search text matched against deal title / description. Omit or leave empty to list all.'),\n limit: z.number().int().min(1).max(100).optional().describe('Maximum rows to return (default 50, max 100).'),\n offset: z.number().int().min(0).optional().describe('Number of rows to skip (default 0).'),\n personId: z.string().uuid().optional().describe('Return only deals linked to this person entity id.'),\n companyId: z.string().uuid().optional().describe('Return only deals linked to this company entity id.'),\n pipelineStageId: z.string().uuid().optional().describe('Return only deals at this pipeline stage.'),\n status: z.string().optional().describe('Filter by deal status (e.g. \"open\", \"won\", \"lost\").'),\n })\n .passthrough()\n\ntype ListDealsInput = z.infer<typeof listDealsInput>\n\ntype ListDealsApiItem = {\n id?: string\n title?: string | null\n description?: string | null\n status?: string | null\n pipeline_id?: string | null\n pipelineId?: string | null\n pipeline_stage_id?: string | null\n pipelineStageId?: string | null\n value_amount?: string | number | null\n valueAmount?: string | number | null\n value_currency?: string | null\n valueCurrency?: string | null\n probability?: number | null\n owner_user_id?: string | null\n ownerUserId?: string | null\n expected_close_at?: string | null\n expectedCloseAt?: string | null\n source?: string | null\n organization_id?: string | null\n organizationId?: string | null\n tenant_id?: string | null\n tenantId?: string | null\n created_at?: string | null\n createdAt?: string | null\n}\n\ntype ListDealsApiResponse = {\n items?: ListDealsApiItem[]\n total?: number\n}\n\ntype ListDealsOutput = {\n items: Array<Record<string, unknown>>\n total: number\n limit: number\n offset: number\n}\n\nconst listDealsTool = defineApiBackedAiTool<ListDealsInput, ListDealsApiResponse, ListDealsOutput>({\n name: 'customers.list_deals',\n displayName: 'List deals',\n description:\n 'Search / list deals for the caller tenant + organization. Optional filters include linked person / company / pipeline stage.',\n inputSchema: listDealsInput,\n requiredFeatures: ['customers.deals.view'],\n toOperation: (input, ctx) => {\n assertTenantScope(ctx as unknown as CustomersToolContext)\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const page = Math.floor(offset / limit) + 1\n\n const query: Record<string, string | number | boolean | null | undefined> = {\n page,\n pageSize: limit,\n }\n if (input.q?.trim()) query.search = input.q.trim()\n if (input.personId) query.personId = input.personId\n if (input.companyId) query.companyId = input.companyId\n if (input.pipelineStageId) query.pipelineStageId = input.pipelineStageId\n if (input.status) query.status = input.status\n\n const operation: AiApiOperationRequest = {\n method: 'GET',\n path: '/customers/deals',\n query,\n }\n return operation\n },\n mapResponse: (response, input) => {\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const data = (response.data ?? {}) as ListDealsApiResponse\n const rawItems: ListDealsApiItem[] = Array.isArray(data.items) ? data.items : []\n return {\n items: rawItems.map((row) => {\n const expectedCloseRaw = row.expected_close_at ?? row.expectedCloseAt ?? null\n const expectedCloseAt = expectedCloseRaw ? new Date(String(expectedCloseRaw)).toISOString() : null\n const createdAtRaw = row.created_at ?? row.createdAt ?? null\n const createdAt = createdAtRaw ? new Date(String(createdAtRaw)).toISOString() : null\n return {\n id: row.id,\n title: row.title ?? null,\n description: row.description ?? null,\n status: row.status ?? null,\n pipelineId: row.pipeline_id ?? row.pipelineId ?? null,\n pipelineStageId: row.pipeline_stage_id ?? row.pipelineStageId ?? null,\n valueAmount: row.value_amount ?? row.valueAmount ?? null,\n valueCurrency: row.value_currency ?? row.valueCurrency ?? null,\n probability: row.probability ?? null,\n ownerUserId: row.owner_user_id ?? row.ownerUserId ?? null,\n expectedCloseAt,\n source: row.source ?? null,\n organizationId: row.organization_id ?? row.organizationId ?? null,\n tenantId: row.tenant_id ?? row.tenantId ?? null,\n createdAt,\n }\n }),\n total: typeof data.total === 'number' ? data.total : 0,\n limit,\n offset,\n }\n },\n}) as unknown as CustomersAiToolDefinition\n\nconst getDealInput = z.object({\n dealId: z.string().uuid().describe('Deal id (UUID).'),\n includeRelated: z\n .boolean()\n .optional()\n .describe('When true, include notes, activities, linked people and companies (each capped at 100).'),\n})\n\ntype GetDealInput = z.infer<typeof getDealInput>\n\nfunction toIsoDeal(value: unknown): string | null {\n if (!value) return null\n const dt = value instanceof Date ? value : new Date(String(value))\n if (Number.isNaN(dt.getTime())) return null\n return dt.toISOString()\n}\n\nconst getDealTool: CustomersAiToolDefinition = {\n name: 'customers.get_deal',\n displayName: 'Get deal',\n description:\n 'Fetch a deal by id with fields and (optionally) notes, activities, linked people, and linked companies. Returns { found: false } when outside tenant/org scope.',\n inputSchema: getDealInput,\n requiredFeatures: ['customers.deals.view'],\n tags: ['read', 'customers'],\n handler: async (rawInput, ctx) => {\n const { tenantId: _tenantId } = assertTenantScope(ctx)\n void _tenantId\n const input: GetDealInput = getDealInput.parse(rawInput)\n const includeRelated = !!input.includeRelated\n const runner = createAiApiOperationRunner(ctx as unknown as AiToolExecutionContext)\n\n const detailResponse = await runner.run<Record<string, unknown>>({\n method: 'GET',\n path: `/customers/deals/${input.dealId}`,\n })\n if (!detailResponse.success) {\n if (detailResponse.statusCode === 404 || detailResponse.statusCode === 403) {\n return { found: false as const, dealId: input.dealId }\n }\n throw new Error(detailResponse.error ?? `Failed to fetch deal ${input.dealId}`)\n }\n const detail = (detailResponse.data ?? {}) as Record<string, unknown>\n const dealRow = (detail.deal ?? null) as Record<string, unknown> | null\n if (!dealRow) {\n return { found: false as const, dealId: input.dealId }\n }\n const customFields = (detail.customFields ?? {}) as Record<string, unknown>\n const peopleRows = Array.isArray(detail.people) ? (detail.people as Array<Record<string, unknown>>) : []\n const companiesRows = Array.isArray(detail.companies)\n ? (detail.companies as Array<Record<string, unknown>>)\n : []\n\n let related: Record<string, unknown> | null = null\n if (includeRelated) {\n const [activitiesResponse, commentsResponse] = await Promise.all([\n runner.run<{ items?: Array<Record<string, unknown>>; total?: number }>({\n method: 'GET',\n path: '/customers/activities',\n query: { dealId: input.dealId, page: 1, pageSize: 100, sortField: 'occurredAt', sortDir: 'desc' },\n }),\n runner.run<{ items?: Array<Record<string, unknown>>; total?: number }>({\n method: 'GET',\n path: '/customers/comments',\n query: { dealId: input.dealId, page: 1, pageSize: 100 },\n }),\n ])\n const activities =\n activitiesResponse.success && Array.isArray(activitiesResponse.data?.items)\n ? (activitiesResponse.data!.items as Array<Record<string, unknown>>)\n : []\n const comments =\n commentsResponse.success && Array.isArray(commentsResponse.data?.items)\n ? (commentsResponse.data!.items as Array<Record<string, unknown>>)\n : []\n\n related = {\n activities: activities.map((activity) => ({\n id: activity.id,\n activityType: activity.activityType ?? activity.activity_type ?? null,\n subject: activity.subject ?? null,\n body: activity.body ?? null,\n occurredAt: toIsoDeal(activity.occurredAt ?? activity.occurred_at),\n createdAt: toIsoDeal(activity.createdAt ?? activity.created_at),\n })),\n notes: comments.map((comment) => ({\n id: comment.id,\n body: comment.body,\n authorUserId: comment.authorUserId ?? comment.author_user_id ?? null,\n createdAt: toIsoDeal(comment.createdAt ?? comment.created_at),\n })),\n people: peopleRows\n .map((person) => {\n if (!person || typeof person !== 'object') return null\n const id = typeof person.id === 'string' ? person.id : null\n if (!id) return null\n const subtitle = typeof person.subtitle === 'string' ? person.subtitle : null\n const label = typeof person.label === 'string' ? person.label : ''\n const entry: {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n participantRole: string | null\n } = {\n id,\n displayName: label,\n primaryEmail: subtitle && subtitle.includes('@') ? subtitle : null,\n primaryPhone: subtitle && !subtitle.includes('@') ? subtitle : null,\n participantRole: null as string | null,\n }\n return entry\n })\n .filter(\n (value): value is {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n participantRole: string | null\n } => value !== null,\n ),\n companies: companiesRows\n .map((company) => {\n if (!company || typeof company !== 'object') return null\n const id = typeof company.id === 'string' ? company.id : null\n if (!id) return null\n const label = typeof company.label === 'string' ? company.label : ''\n const entry: {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n } = {\n id,\n displayName: label,\n primaryEmail: null as string | null,\n primaryPhone: null as string | null,\n }\n return entry\n })\n .filter(\n (value): value is {\n id: string\n displayName: string\n primaryEmail: string | null\n primaryPhone: string | null\n } => value !== null,\n ),\n }\n }\n\n return {\n found: true as const,\n deal: {\n id: dealRow.id,\n title: typeof dealRow.title === 'string' ? dealRow.title : '',\n description: dealRow.description ?? null,\n status: dealRow.status ?? null,\n pipelineId: dealRow.pipelineId ?? null,\n pipelineStageId: dealRow.pipelineStageId ?? null,\n valueAmount: dealRow.valueAmount ?? null,\n valueCurrency: dealRow.valueCurrency ?? null,\n probability: dealRow.probability ?? null,\n ownerUserId: dealRow.ownerUserId ?? null,\n expectedCloseAt: toIsoDeal(dealRow.expectedCloseAt),\n source: dealRow.source ?? null,\n organizationId: dealRow.organizationId ?? null,\n tenantId: dealRow.tenantId ?? null,\n createdAt: toIsoDeal(dealRow.createdAt),\n updatedAt: toIsoDeal(dealRow.updatedAt),\n },\n customFields,\n related,\n }\n },\n}\n\n/**\n * Mutation tool: move a deal to a different pipeline stage. Step 5.13 \u2014 first\n * mutation-capable flow on the pending-action contract.\n *\n * Accepts either `toPipelineStageId` (UUID \u2014 preferred, tenant-scoped stage\n * record) or `toStage` (free-form string that maps to `CustomerDeal.status`\n * for pipeline roots like `open`/`won`/`lost`). Exactly one must be provided.\n *\n * The handler delegates to the existing `customers.deals.update` command so\n * all side effects (audit log, `customers.deal.updated` event, query index\n * refresh, notifications) stay identical to a direct API write.\n */\n// LLMs frequently emit `\"\"` for \"not provided\" \u2014 coerce blanks (and surrounding\n// whitespace) to `undefined` BEFORE the per-field validators run so the\n// `.uuid()` check on `toPipelineStageId` does not blow up on an empty string\n// the caller actually meant as \"skip this field\".\nconst blankToUndefined = (value: unknown): unknown => {\n if (typeof value !== 'string') return value\n const trimmed = value.trim()\n return trimmed.length === 0 ? undefined : trimmed\n}\n\nconst updateDealStageInput = z\n .object({\n dealId: z.string().uuid().describe('Deal id (UUID) to update.'),\n toPipelineStageId: z\n .preprocess(blankToUndefined, z.string().uuid().optional())\n .describe('Target pipeline stage id (UUID). Preferred \u2014 tenant-scoped stage record.'),\n toStage: z\n .preprocess(blankToUndefined, z.string().min(1).max(50).optional())\n .describe(\n 'Target status slug (e.g. \"open\", \"won\", \"lost\"). Used when the deal does not belong to a managed pipeline.',\n ),\n })\n .refine(\n (value) => Boolean(value.toPipelineStageId) !== Boolean(value.toStage),\n {\n message: 'Provide exactly one of toPipelineStageId or toStage.',\n path: ['toPipelineStageId'],\n },\n )\n\ntype UpdateDealStageInput = z.infer<typeof updateDealStageInput>\n\nfunction recordVersionFromUpdatedAt(updatedAt: Date | null | undefined): string | null {\n if (!updatedAt) return null\n const value = updatedAt instanceof Date ? updatedAt : new Date(updatedAt)\n if (Number.isNaN(value.getTime())) return null\n return value.toISOString()\n}\n\nfunction titleStatus(value: string | null | undefined): string | undefined {\n if (!value) return undefined\n return value\n .split(/[_\\s-]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n}\n\nasync function loadDealWithStage(\n em: EntityManager,\n ctx: CustomersToolContext,\n tenantId: string,\n dealId: string,\n): Promise<CustomerDeal | null> {\n const where: Record<string, unknown> = { id: dealId, tenantId, deletedAt: null }\n if (ctx.organizationId) where.organizationId = ctx.organizationId\n const deal = await findOneWithDecryption<CustomerDeal>(\n em,\n CustomerDeal,\n where as FilterQuery<CustomerDeal>,\n undefined,\n buildScope(ctx, tenantId),\n )\n if (!deal || deal.tenantId !== tenantId) return null\n if (ctx.organizationId && deal.organizationId !== ctx.organizationId) return null\n return deal\n}\n\nasync function loadPipelineStage(\n em: EntityManager,\n ctx: CustomersToolContext,\n tenantId: string,\n stageId: string,\n organizationId: string,\n): Promise<CustomerPipelineStage | null> {\n return findOneWithDecryption<CustomerPipelineStage>(\n em,\n CustomerPipelineStage,\n {\n id: stageId,\n tenantId,\n organizationId,\n },\n undefined,\n buildScope(ctx, tenantId),\n )\n}\n\nconst updateDealStageTool: CustomersAiToolDefinition = {\n name: 'customers.update_deal_stage',\n displayName: 'Update deal stage',\n description:\n 'Move a deal to a different pipeline stage (by stage id) or change its top-level status (e.g. \"open\", \"won\", \"lost\"). Mutation tool \u2014 flows through the AI pending-action approval gate.',\n inputSchema: updateDealStageInput as z.ZodType<unknown>,\n requiredFeatures: ['customers.deals.manage'],\n tags: ['write', 'customers'],\n isMutation: true,\n loadBeforeRecord: async (rawInput, ctx): Promise<CustomersToolLoadBeforeSingleRecord | null> => {\n const { tenantId } = assertTenantScope(ctx)\n const input: UpdateDealStageInput = updateDealStageInput.parse(rawInput)\n const em = resolveEm(ctx)\n const deal = await loadDealWithStage(em, ctx, tenantId, input.dealId)\n if (!deal) return null\n let afterStatus = deal.status ?? null\n let afterPipelineStageId = deal.pipelineStageId ?? null\n let afterPipelineStageLabel = deal.pipelineStage ?? null\n if (input.toPipelineStageId) {\n const organizationId = deal.organizationId ?? ctx.organizationId ?? null\n const stage = organizationId\n ? await loadPipelineStage(em, ctx, tenantId, input.toPipelineStageId, organizationId)\n : null\n afterPipelineStageId = input.toPipelineStageId\n afterPipelineStageLabel = stage?.label ?? input.toPipelineStageId\n } else if (input.toStage) {\n afterStatus = input.toStage\n }\n const beforeStatus = deal.status ?? null\n const beforePipelineStageId = deal.pipelineStageId ?? null\n const beforePipelineStageLabel = deal.pipelineStage ?? beforePipelineStageId\n return {\n recordId: deal.id,\n entityType: 'customers.deal',\n recordVersion: recordVersionFromUpdatedAt(deal.updatedAt),\n before: {\n status: beforeStatus,\n pipelineStageId: beforePipelineStageId,\n },\n after: {\n status: afterStatus,\n pipelineStageId: afterPipelineStageId,\n },\n display: {\n fieldLabels: {\n status: 'Status',\n pipelineStageId: 'Pipeline stage',\n },\n before: {\n ...(beforeStatus ? { status: titleStatus(beforeStatus) } : {}),\n ...(beforePipelineStageLabel ? { pipelineStageId: beforePipelineStageLabel } : {}),\n },\n after: {\n ...(afterStatus ? { status: titleStatus(afterStatus) } : {}),\n ...(afterPipelineStageLabel ? { pipelineStageId: afterPipelineStageLabel } : {}),\n },\n },\n }\n },\n handler: async (rawInput, ctx) => {\n const { tenantId } = assertTenantScope(ctx)\n const input: UpdateDealStageInput = updateDealStageInput.parse(rawInput)\n const em = resolveEm(ctx)\n const deal = await loadDealWithStage(em, ctx, tenantId, input.dealId)\n if (!deal) {\n throw new Error(`Deal \"${input.dealId}\" is not accessible to the caller.`)\n }\n const organizationId = deal.organizationId\n if (!organizationId) {\n throw new Error(`Deal \"${input.dealId}\" has no organization scope.`)\n }\n\n const before = {\n status: deal.status ?? null,\n pipelineStage: deal.pipelineStage ?? null,\n pipelineStageId: deal.pipelineStageId ?? null,\n }\n\n const body: Record<string, unknown> = {\n id: deal.id,\n tenantId,\n organizationId,\n }\n if (input.toPipelineStageId) {\n const stage = await loadPipelineStage(em, ctx, tenantId, input.toPipelineStageId, organizationId)\n if (!stage) {\n throw new Error('Pipeline stage not found.')\n }\n body.pipelineStageId = input.toPipelineStageId\n } else if (input.toStage) {\n body.status = input.toStage\n }\n\n const runner = createAiApiOperationRunner(ctx as unknown as AiToolExecutionContext)\n const response = await runner.run({\n method: 'PUT',\n path: '/customers/deals',\n body,\n })\n if (!response.success) {\n throw new Error(response.error ?? `Failed to update deal \"${deal.id}\"`)\n }\n\n const after = await loadDealWithStage(em, ctx, tenantId, deal.id)\n return {\n recordId: deal.id,\n commandName: 'customers.deals.update',\n before,\n after: after\n ? {\n status: after.status ?? null,\n pipelineStage: after.pipelineStage ?? null,\n pipelineStageId: after.pipelineStageId ?? null,\n }\n : null,\n }\n },\n}\n\nexport const dealsAiTools: CustomersAiToolDefinition[] = [listDealsTool, getDealTool, updateDealStageTool]\n\nexport default dealsAiTools\n"],
5
+ "mappings": "AAiBA,SAAS,SAAS;AAClB,SAAS,6BAA6B;AACtC;AAAA,EACE;AAAA,OAGK;AACP,SAAS,6BAA6B;AACtC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,OAIK;AAEP,SAAS,UAAU,KAAmE;AACpF,SAAO,IAAI,UAAU,QAAuB,IAAI;AAClD;AAEA,SAAS,WAAW,KAAoD,UAAkB;AACxF,SAAO,EAAE,UAAU,gBAAgB,IAAI,eAAe;AACxD;AAEA,MAAM,iBAAiB,EACpB,OAAO;AAAA,EACN,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,wFAAwF;AAAA,EACjI,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,EAC3G,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EACzF,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,EACpG,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,qDAAqD;AAAA,EACtG,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,EAClG,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qDAAqD;AAC9F,CAAC,EACA,YAAY;AA2Cf,MAAM,gBAAgB,sBAA6E;AAAA,EACjG,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aACE;AAAA,EACF,aAAa;AAAA,EACb,kBAAkB,CAAC,sBAAsB;AAAA,EACzC,aAAa,CAAC,OAAO,QAAQ;AAC3B,sBAAkB,GAAsC;AACxD,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,SAAS,MAAM,UAAU;AAC/B,UAAM,OAAO,KAAK,MAAM,SAAS,KAAK,IAAI;AAE1C,UAAM,QAAsE;AAAA,MAC1E;AAAA,MACA,UAAU;AAAA,IACZ;AACA,QAAI,MAAM,GAAG,KAAK,EAAG,OAAM,SAAS,MAAM,EAAE,KAAK;AACjD,QAAI,MAAM,SAAU,OAAM,WAAW,MAAM;AAC3C,QAAI,MAAM,UAAW,OAAM,YAAY,MAAM;AAC7C,QAAI,MAAM,gBAAiB,OAAM,kBAAkB,MAAM;AACzD,QAAI,MAAM,OAAQ,OAAM,SAAS,MAAM;AAEvC,UAAM,YAAmC;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EACA,aAAa,CAAC,UAAU,UAAU;AAChC,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,SAAS,MAAM,UAAU;AAC/B,UAAM,OAAQ,SAAS,QAAQ,CAAC;AAChC,UAAM,WAA+B,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AAC/E,WAAO;AAAA,MACL,OAAO,SAAS,IAAI,CAAC,QAAQ;AAC3B,cAAM,mBAAmB,IAAI,qBAAqB,IAAI,mBAAmB;AACzE,cAAM,kBAAkB,mBAAmB,IAAI,KAAK,OAAO,gBAAgB,CAAC,EAAE,YAAY,IAAI;AAC9F,cAAM,eAAe,IAAI,cAAc,IAAI,aAAa;AACxD,cAAM,YAAY,eAAe,IAAI,KAAK,OAAO,YAAY,CAAC,EAAE,YAAY,IAAI;AAChF,eAAO;AAAA,UACL,IAAI,IAAI;AAAA,UACR,OAAO,IAAI,SAAS;AAAA,UACpB,aAAa,IAAI,eAAe;AAAA,UAChC,QAAQ,IAAI,UAAU;AAAA,UACtB,YAAY,IAAI,eAAe,IAAI,cAAc;AAAA,UACjD,iBAAiB,IAAI,qBAAqB,IAAI,mBAAmB;AAAA,UACjE,aAAa,IAAI,gBAAgB,IAAI,eAAe;AAAA,UACpD,eAAe,IAAI,kBAAkB,IAAI,iBAAiB;AAAA,UAC1D,aAAa,IAAI,eAAe;AAAA,UAChC,aAAa,IAAI,iBAAiB,IAAI,eAAe;AAAA,UACrD;AAAA,UACA,QAAQ,IAAI,UAAU;AAAA,UACtB,gBAAgB,IAAI,mBAAmB,IAAI,kBAAkB;AAAA,UAC7D,UAAU,IAAI,aAAa,IAAI,YAAY;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAED,MAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,iBAAiB;AAAA,EACpD,gBAAgB,EACb,QAAQ,EACR,SAAS,EACT,SAAS,yFAAyF;AACvG,CAAC;AAID,SAAS,UAAU,OAA+B;AAChD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,KAAK,iBAAiB,OAAO,QAAQ,IAAI,KAAK,OAAO,KAAK,CAAC;AACjE,MAAI,OAAO,MAAM,GAAG,QAAQ,CAAC,EAAG,QAAO;AACvC,SAAO,GAAG,YAAY;AACxB;AAEA,MAAM,cAAyC;AAAA,EAC7C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aACE;AAAA,EACF,aAAa;AAAA,EACb,kBAAkB,CAAC,sBAAsB;AAAA,EACzC,MAAM,CAAC,QAAQ,WAAW;AAAA,EAC1B,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,EAAE,UAAU,UAAU,IAAI,kBAAkB,GAAG;AACrD,SAAK;AACL,UAAM,QAAsB,aAAa,MAAM,QAAQ;AACvD,UAAM,iBAAiB,CAAC,CAAC,MAAM;AAC/B,UAAM,SAAS,2BAA2B,GAAwC;AAElF,UAAM,iBAAiB,MAAM,OAAO,IAA6B;AAAA,MAC/D,QAAQ;AAAA,MACR,MAAM,oBAAoB,MAAM,MAAM;AAAA,IACxC,CAAC;AACD,QAAI,CAAC,eAAe,SAAS;AAC3B,UAAI,eAAe,eAAe,OAAO,eAAe,eAAe,KAAK;AAC1E,eAAO,EAAE,OAAO,OAAgB,QAAQ,MAAM,OAAO;AAAA,MACvD;AACA,YAAM,IAAI,MAAM,eAAe,SAAS,wBAAwB,MAAM,MAAM,EAAE;AAAA,IAChF;AACA,UAAM,SAAU,eAAe,QAAQ,CAAC;AACxC,UAAM,UAAW,OAAO,QAAQ;AAChC,QAAI,CAAC,SAAS;AACZ,aAAO,EAAE,OAAO,OAAgB,QAAQ,MAAM,OAAO;AAAA,IACvD;AACA,UAAM,eAAgB,OAAO,gBAAgB,CAAC;AAC9C,UAAM,aAAa,MAAM,QAAQ,OAAO,MAAM,IAAK,OAAO,SAA4C,CAAC;AACvG,UAAM,gBAAgB,MAAM,QAAQ,OAAO,SAAS,IAC/C,OAAO,YACR,CAAC;AAEL,QAAI,UAA0C;AAC9C,QAAI,gBAAgB;AAClB,YAAM,CAAC,oBAAoB,gBAAgB,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC/D,OAAO,IAAgE;AAAA,UACrE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAO,EAAE,QAAQ,MAAM,QAAQ,MAAM,GAAG,UAAU,KAAK,WAAW,cAAc,SAAS,OAAO;AAAA,QAClG,CAAC;AAAA,QACD,OAAO,IAAgE;AAAA,UACrE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAO,EAAE,QAAQ,MAAM,QAAQ,MAAM,GAAG,UAAU,IAAI;AAAA,QACxD,CAAC;AAAA,MACH,CAAC;AACD,YAAM,aACJ,mBAAmB,WAAW,MAAM,QAAQ,mBAAmB,MAAM,KAAK,IACrE,mBAAmB,KAAM,QAC1B,CAAC;AACP,YAAM,WACJ,iBAAiB,WAAW,MAAM,QAAQ,iBAAiB,MAAM,KAAK,IACjE,iBAAiB,KAAM,QACxB,CAAC;AAEP,gBAAU;AAAA,QACR,YAAY,WAAW,IAAI,CAAC,cAAc;AAAA,UACxC,IAAI,SAAS;AAAA,UACb,cAAc,SAAS,gBAAgB,SAAS,iBAAiB;AAAA,UACjE,SAAS,SAAS,WAAW;AAAA,UAC7B,MAAM,SAAS,QAAQ;AAAA,UACvB,YAAY,UAAU,SAAS,cAAc,SAAS,WAAW;AAAA,UACjE,WAAW,UAAU,SAAS,aAAa,SAAS,UAAU;AAAA,QAChE,EAAE;AAAA,QACF,OAAO,SAAS,IAAI,CAAC,aAAa;AAAA,UAChC,IAAI,QAAQ;AAAA,UACZ,MAAM,QAAQ;AAAA,UACd,cAAc,QAAQ,gBAAgB,QAAQ,kBAAkB;AAAA,UAChE,WAAW,UAAU,QAAQ,aAAa,QAAQ,UAAU;AAAA,QAC9D,EAAE;AAAA,QACF,QAAQ,WACL,IAAI,CAAC,WAAW;AACf,cAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,gBAAM,KAAK,OAAO,OAAO,OAAO,WAAW,OAAO,KAAK;AACvD,cAAI,CAAC,GAAI,QAAO;AAChB,gBAAM,WAAW,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW;AACzE,gBAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,gBAAM,QAMF;AAAA,YACF;AAAA,YACA,aAAa;AAAA,YACb,cAAc,YAAY,SAAS,SAAS,GAAG,IAAI,WAAW;AAAA,YAC9D,cAAc,YAAY,CAAC,SAAS,SAAS,GAAG,IAAI,WAAW;AAAA,YAC/D,iBAAiB;AAAA,UACnB;AACA,iBAAO;AAAA,QACT,CAAC,EACA;AAAA,UACC,CAAC,UAMI,UAAU;AAAA,QACjB;AAAA,QACF,WAAW,cACR,IAAI,CAAC,YAAY;AAChB,cAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,gBAAM,KAAK,OAAO,QAAQ,OAAO,WAAW,QAAQ,KAAK;AACzD,cAAI,CAAC,GAAI,QAAO;AAChB,gBAAM,QAAQ,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ;AAClE,gBAAM,QAKF;AAAA,YACF;AAAA,YACA,aAAa;AAAA,YACb,cAAc;AAAA,YACd,cAAc;AAAA,UAChB;AACA,iBAAO;AAAA,QACT,CAAC,EACA;AAAA,UACC,CAAC,UAKI,UAAU;AAAA,QACjB;AAAA,MACJ;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,QACJ,IAAI,QAAQ;AAAA,QACZ,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ;AAAA,QAC3D,aAAa,QAAQ,eAAe;AAAA,QACpC,QAAQ,QAAQ,UAAU;AAAA,QAC1B,YAAY,QAAQ,cAAc;AAAA,QAClC,iBAAiB,QAAQ,mBAAmB;AAAA,QAC5C,aAAa,QAAQ,eAAe;AAAA,QACpC,eAAe,QAAQ,iBAAiB;AAAA,QACxC,aAAa,QAAQ,eAAe;AAAA,QACpC,aAAa,QAAQ,eAAe;AAAA,QACpC,iBAAiB,UAAU,QAAQ,eAAe;AAAA,QAClD,QAAQ,QAAQ,UAAU;AAAA,QAC1B,gBAAgB,QAAQ,kBAAkB;AAAA,QAC1C,UAAU,QAAQ,YAAY;AAAA,QAC9B,WAAW,UAAU,QAAQ,SAAS;AAAA,QACtC,WAAW,UAAU,QAAQ,SAAS;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAkBA,MAAM,mBAAmB,CAAC,UAA4B;AACpD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,WAAW,IAAI,SAAY;AAC5C;AAEA,MAAM,uBAAuB,EAC1B,OAAO;AAAA,EACN,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,2BAA2B;AAAA,EAC9D,mBAAmB,EAChB,WAAW,kBAAkB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,EACzD,SAAS,+EAA0E;AAAA,EACtF,SAAS,EACN,WAAW,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,CAAC,EACjE;AAAA,IACC;AAAA,EACF;AACJ,CAAC,EACA;AAAA,EACC,CAAC,UAAU,QAAQ,MAAM,iBAAiB,MAAM,QAAQ,MAAM,OAAO;AAAA,EACrE;AAAA,IACE,SAAS;AAAA,IACT,MAAM,CAAC,mBAAmB;AAAA,EAC5B;AACF;AAIF,SAAS,2BAA2B,WAAmD;AACrF,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,QAAQ,qBAAqB,OAAO,YAAY,IAAI,KAAK,SAAS;AACxE,MAAI,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC1C,SAAO,MAAM,YAAY;AAC3B;AAEA,SAAS,YAAY,OAAsD;AACzE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MACJ,MAAM,SAAS,EACf,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AACb;AAEA,eAAe,kBACb,IACA,KACA,UACA,QAC8B;AAC9B,QAAM,QAAiC,EAAE,IAAI,QAAQ,UAAU,WAAW,KAAK;AAC/E,MAAI,IAAI,eAAgB,OAAM,iBAAiB,IAAI;AACnD,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,QAAQ;AAAA,EAC1B;AACA,MAAI,CAAC,QAAQ,KAAK,aAAa,SAAU,QAAO;AAChD,MAAI,IAAI,kBAAkB,KAAK,mBAAmB,IAAI,eAAgB,QAAO;AAC7E,SAAO;AACT;AAEA,eAAe,kBACb,IACA,KACA,UACA,SACA,gBACuC;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,IACA,WAAW,KAAK,QAAQ;AAAA,EAC1B;AACF;AAEA,MAAM,sBAAiD;AAAA,EACrD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aACE;AAAA,EACF,aAAa;AAAA,EACb,kBAAkB,CAAC,wBAAwB;AAAA,EAC3C,MAAM,CAAC,SAAS,WAAW;AAAA,EAC3B,YAAY;AAAA,EACZ,kBAAkB,OAAO,UAAU,QAA6D;AAC9F,UAAM,EAAE,SAAS,IAAI,kBAAkB,GAAG;AAC1C,UAAM,QAA8B,qBAAqB,MAAM,QAAQ;AACvE,UAAM,KAAK,UAAU,GAAG;AACxB,UAAM,OAAO,MAAM,kBAAkB,IAAI,KAAK,UAAU,MAAM,MAAM;AACpE,QAAI,CAAC,KAAM,QAAO;AAClB,QAAI,cAAc,KAAK,UAAU;AACjC,QAAI,uBAAuB,KAAK,mBAAmB;AACnD,QAAI,0BAA0B,KAAK,iBAAiB;AACpD,QAAI,MAAM,mBAAmB;AAC3B,YAAM,iBAAiB,KAAK,kBAAkB,IAAI,kBAAkB;AACpE,YAAM,QAAQ,iBACV,MAAM,kBAAkB,IAAI,KAAK,UAAU,MAAM,mBAAmB,cAAc,IAClF;AACJ,6BAAuB,MAAM;AAC7B,gCAA0B,OAAO,SAAS,MAAM;AAAA,IAClD,WAAW,MAAM,SAAS;AACxB,oBAAc,MAAM;AAAA,IACtB;AACA,UAAM,eAAe,KAAK,UAAU;AACpC,UAAM,wBAAwB,KAAK,mBAAmB;AACtD,UAAM,2BAA2B,KAAK,iBAAiB;AACvD,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,MACZ,eAAe,2BAA2B,KAAK,SAAS;AAAA,MACxD,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB;AAAA,MACA,SAAS;AAAA,QACP,aAAa;AAAA,UACX,QAAQ;AAAA,UACR,iBAAiB;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,UACN,GAAI,eAAe,EAAE,QAAQ,YAAY,YAAY,EAAE,IAAI,CAAC;AAAA,UAC5D,GAAI,2BAA2B,EAAE,iBAAiB,yBAAyB,IAAI,CAAC;AAAA,QAClF;AAAA,QACA,OAAO;AAAA,UACL,GAAI,cAAc,EAAE,QAAQ,YAAY,WAAW,EAAE,IAAI,CAAC;AAAA,UAC1D,GAAI,0BAA0B,EAAE,iBAAiB,wBAAwB,IAAI,CAAC;AAAA,QAChF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,EAAE,SAAS,IAAI,kBAAkB,GAAG;AAC1C,UAAM,QAA8B,qBAAqB,MAAM,QAAQ;AACvE,UAAM,KAAK,UAAU,GAAG;AACxB,UAAM,OAAO,MAAM,kBAAkB,IAAI,KAAK,UAAU,MAAM,MAAM;AACpE,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,SAAS,MAAM,MAAM,oCAAoC;AAAA,IAC3E;AACA,UAAM,iBAAiB,KAAK;AAC5B,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,SAAS,MAAM,MAAM,8BAA8B;AAAA,IACrE;AAEA,UAAM,SAAS;AAAA,MACb,QAAQ,KAAK,UAAU;AAAA,MACvB,eAAe,KAAK,iBAAiB;AAAA,MACrC,iBAAiB,KAAK,mBAAmB;AAAA,IAC3C;AAEA,UAAM,OAAgC;AAAA,MACpC,IAAI,KAAK;AAAA,MACT;AAAA,MACA;AAAA,IACF;AACA,QAAI,MAAM,mBAAmB;AAC3B,YAAM,QAAQ,MAAM,kBAAkB,IAAI,KAAK,UAAU,MAAM,mBAAmB,cAAc;AAChG,UAAI,CAAC,OAAO;AACV,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AACA,WAAK,kBAAkB,MAAM;AAAA,IAC/B,WAAW,MAAM,SAAS;AACxB,WAAK,SAAS,MAAM;AAAA,IACtB;AAEA,UAAM,SAAS,2BAA2B,GAAwC;AAClF,UAAM,WAAW,MAAM,OAAO,IAAI;AAAA,MAChC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS,SAAS;AACrB,YAAM,IAAI,MAAM,SAAS,SAAS,0BAA0B,KAAK,EAAE,GAAG;AAAA,IACxE;AAEA,UAAM,QAAQ,MAAM,kBAAkB,IAAI,KAAK,UAAU,KAAK,EAAE;AAChE,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,aAAa;AAAA,MACb;AAAA,MACA,OAAO,QACH;AAAA,QACE,QAAQ,MAAM,UAAU;AAAA,QACxB,eAAe,MAAM,iBAAiB;AAAA,QACtC,iBAAiB,MAAM,mBAAmB;AAAA,MAC5C,IACA;AAAA,IACN;AAAA,EACF;AACF;AAEO,MAAM,eAA4C,CAAC,eAAe,aAAa,mBAAmB;AAEzG,IAAO,qBAAQ;",
6
6
  "names": []
7
7
  }
@@ -26,7 +26,7 @@ const listPeopleInput = z.object({
26
26
  const listPeopleTool = defineApiBackedAiTool({
27
27
  name: "customers.list_people",
28
28
  displayName: "List people",
29
- description: 'Search / list people (CRM persons) for the caller tenant + organization. Returns { items, total, totalIsCapped, limit, offset }. When totalIsCapped is true, total is a floor ("at least N", render it as "N+"), and pagination is exhausted only when a page returns fewer than limit items \u2014 never when offset reaches total.',
29
+ description: "Search / list people (CRM persons) for the caller tenant + organization. Returns { items, total, limit, offset }.",
30
30
  inputSchema: listPeopleInput,
31
31
  requiredFeatures: ["customers.people.view"],
32
32
  toOperation: async (input, ctx) => {
@@ -73,9 +73,6 @@ const listPeopleTool = defineApiBackedAiTool({
73
73
  return {
74
74
  items: rawItems.map((row) => toCustomerListSummary(row)),
75
75
  total: typeof data.total === "number" ? data.total : 0,
76
- // A capped count reports a floor: phrase the total as "at least N" and
77
- // never treat it as proof that pagination is exhausted.
78
- totalIsCapped: data.totalIsCapped === true,
79
76
  limit,
80
77
  offset
81
78
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/ai-tools/people-pack.ts"],
4
- "sourcesContent": ["/**\n * `customers.list_people` + `customers.get_person` (Phase 1 WS-C, Step 3.9).\n *\n * Read-only tools scoped to `ctx.tenantId` / `ctx.organizationId` that wrap\n * the existing customers query engine + encryption helpers. Mutation tools\n * are deferred to Step 5.13+ under the pending-action contract.\n *\n * Phase 3a of `.ai/specs/implemented/2026-04-27-ai-tools-api-backed-dry-refactor.md`:\n * `customers.list_people` is now an API-backed wrapper over\n * `GET /api/customers/people`. The `companyId` AI input has no inclusion\n * equivalent on the route (the route exposes `excludeLinkedCompanyId` only)\n * so it is pre-resolved against `CustomerPersonProfile.company` and threaded\n * through the route's `ids` filter.\n *\n * Phase 3c of the same spec migrates `customers.get_person` to a single\n * in-process call to `GET /api/customers/people/<id>?include=...` (the\n * documented aggregate detail route). Tool name, schema, requiredFeatures,\n * and output shape are unchanged.\n */\nimport { z } from 'zod'\nimport { defineApiBackedAiTool } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool'\nimport {\n createAiApiOperationRunner,\n type AiApiOperationRequest,\n type AiToolExecutionContext,\n} from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n CustomerPersonProfile,\n} from '../data/entities'\nimport { assertTenantScope, type CustomersAiToolDefinition, type CustomersToolContext } from './types'\nimport {\n buildRelatedRecords,\n buildScope,\n resolveEm,\n toCustomerListSummary,\n toIso,\n type CustomerRelatedRecords,\n} from './_shared'\n\nconst NIL_UUID = '00000000-0000-0000-0000-000000000000'\n\nconst listPeopleInput = z\n .object({\n q: z.string().trim().optional().describe('Optional search text matched against display name / email / phone. Omit or leave empty to list all.'),\n limit: z.number().int().min(1).max(100).optional().describe('Maximum rows to return (default 50, max 100).'),\n offset: z.number().int().min(0).optional().describe('Number of rows to skip (default 0).'),\n tags: z.array(z.string().uuid()).optional().describe('Restrict to persons carrying at least one of these tag ids.'),\n companyId: z.string().uuid().optional().describe('Restrict to persons linked to the given company entity.'),\n })\n .passthrough()\n\ntype ListPeopleInput = z.infer<typeof listPeopleInput>\n\ntype ListPeopleApiItem = {\n id?: string\n display_name?: string | null\n displayName?: string | null\n primary_email?: string | null\n primaryEmail?: string | null\n primary_phone?: string | null\n primaryPhone?: string | null\n status?: string | null\n lifecycle_stage?: string | null\n lifecycleStage?: string | null\n source?: string | null\n owner_user_id?: string | null\n ownerUserId?: string | null\n organization_id?: string | null\n organizationId?: string | null\n tenant_id?: string | null\n tenantId?: string | null\n created_at?: string | null\n createdAt?: string | null\n}\n\ntype ListPeopleApiResponse = {\n items?: ListPeopleApiItem[]\n total?: number\n}\n\ntype ListPeopleOutput = {\n items: Array<Record<string, unknown>>\n total: number\n limit: number\n offset: number\n}\n\nconst listPeopleTool = defineApiBackedAiTool<ListPeopleInput, ListPeopleApiResponse, ListPeopleOutput>({\n name: 'customers.list_people',\n displayName: 'List people',\n description:\n 'Search / list people (CRM persons) for the caller tenant + organization. Returns { items, total, totalIsCapped, limit, offset }. When totalIsCapped is true, total is a floor (\"at least N\", render it as \"N+\"), and pagination is exhausted only when a page returns fewer than limit items \u2014 never when offset reaches total.',\n inputSchema: listPeopleInput,\n requiredFeatures: ['customers.people.view'],\n toOperation: async (input, ctx) => {\n const { tenantId } = assertTenantScope(ctx as unknown as CustomersToolContext)\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const page = Math.floor(offset / limit) + 1\n\n const query: Record<string, string | number | boolean | null | undefined> = {\n page,\n pageSize: limit,\n }\n if (input.q?.trim()) query.search = input.q.trim()\n if (input.tags && input.tags.length > 0) query.tagIds = input.tags.join(',')\n\n if (input.companyId) {\n const em = resolveEm(ctx)\n const profiles = await findWithDecryption<CustomerPersonProfile>(\n em,\n CustomerPersonProfile,\n { tenantId, company: input.companyId } as never,\n undefined,\n buildScope(ctx, tenantId),\n )\n const ids = profiles\n .map((profile) => {\n const entity = (profile as { entity?: unknown }).entity\n if (!entity) return null\n if (typeof entity === 'string') return entity\n const candidate = (entity as { id?: unknown }).id\n return typeof candidate === 'string' ? candidate : null\n })\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n // Empty match \u2014 feed a non-existent uuid so the route returns\n // { items: [], total: 0 } without us bypassing the API.\n query.ids = ids.length ? ids.join(',') : NIL_UUID\n }\n\n const operation: AiApiOperationRequest = {\n method: 'GET',\n path: '/customers/people',\n query,\n }\n return operation\n },\n mapResponse: (response, input) => {\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const data = (response.data ?? {}) as ListPeopleApiResponse\n const rawItems: ListPeopleApiItem[] = Array.isArray(data.items) ? data.items : []\n return {\n items: rawItems.map((row) => toCustomerListSummary(row)),\n total: typeof data.total === 'number' ? data.total : 0,\n // A capped count reports a floor: phrase the total as \"at least N\" and\n // never treat it as proof that pagination is exhausted.\n totalIsCapped: (data as { totalIsCapped?: boolean }).totalIsCapped === true,\n limit,\n offset,\n }\n },\n}) as unknown as CustomersAiToolDefinition\n\nconst getPersonInput = z.object({\n personId: z.string().uuid().describe('Person entity id (UUID).'),\n includeRelated: z\n .boolean()\n .optional()\n .describe('When true, include notes, activities, deals, addresses, tasks, and tags (each capped at 100).'),\n})\n\ntype GetPersonInput = z.infer<typeof getPersonInput>\n\ntype ApiPersonDetailRow = Record<string, unknown> | null | undefined\n\nconst getPersonTool: CustomersAiToolDefinition = {\n name: 'customers.get_person',\n displayName: 'Get person',\n description:\n 'Fetch a person customer record by id with profile fields and (optionally) notes, activities, deals, addresses, tasks, tags, and custom fields. Returns { found: false } when the record is outside tenant/org scope or missing.',\n inputSchema: getPersonInput,\n requiredFeatures: ['customers.people.view'],\n tags: ['read', 'customers'],\n handler: async (rawInput, ctx) => {\n const { tenantId } = assertTenantScope(ctx)\n const input: GetPersonInput = getPersonInput.parse(rawInput)\n const includeRelated = !!input.includeRelated\n\n const operation: AiApiOperationRequest = {\n method: 'GET',\n path: `/customers/people/${input.personId}`,\n }\n if (includeRelated) {\n operation.query = { include: 'addresses,comments,activities,interactions,deals,todos' }\n }\n\n const runner = createAiApiOperationRunner(ctx as unknown as AiToolExecutionContext)\n const response = await runner.run<Record<string, unknown>>(operation)\n if (!response.success) {\n if (response.statusCode === 404 || response.statusCode === 403) {\n return { found: false as const, personId: input.personId }\n }\n throw new Error(response.error ?? `Failed to fetch person ${input.personId}`)\n }\n const data = (response.data ?? {}) as Record<string, unknown>\n const personRow = (data.person ?? null) as ApiPersonDetailRow\n if (!personRow) {\n return { found: false as const, personId: input.personId }\n }\n const profileRow = (data.profile ?? null) as ApiPersonDetailRow\n const customFields = (data.customFields ?? {}) as Record<string, unknown>\n\n let related: CustomerRelatedRecords | null = null\n if (includeRelated) {\n related = buildRelatedRecords(data)\n }\n\n return {\n found: true as const,\n person: {\n id: personRow.id,\n displayName: personRow.displayName ?? null,\n description: personRow.description ?? null,\n primaryEmail: personRow.primaryEmail ?? null,\n primaryPhone: personRow.primaryPhone ?? null,\n status: personRow.status ?? null,\n lifecycleStage: personRow.lifecycleStage ?? null,\n source: personRow.source ?? null,\n ownerUserId: personRow.ownerUserId ?? null,\n organizationId: personRow.organizationId ?? null,\n tenantId: personRow.tenantId ?? null,\n createdAt: toIso(personRow.createdAt),\n updatedAt: toIso(personRow.updatedAt),\n },\n profile: profileRow\n ? {\n id: profileRow.id,\n firstName: profileRow.firstName ?? null,\n lastName: profileRow.lastName ?? null,\n preferredName: profileRow.preferredName ?? null,\n jobTitle: profileRow.jobTitle ?? null,\n department: profileRow.department ?? null,\n seniority: profileRow.seniority ?? null,\n timezone: profileRow.timezone ?? null,\n linkedInUrl: profileRow.linkedInUrl ?? null,\n twitterUrl: profileRow.twitterUrl ?? null,\n companyEntityId: profileRow.companyEntityId ?? null,\n }\n : null,\n customFields,\n related,\n }\n },\n}\n\nexport const peopleAiTools: CustomersAiToolDefinition[] = [listPeopleTool, getPersonTool]\n\nexport default peopleAiTools\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * `customers.list_people` + `customers.get_person` (Phase 1 WS-C, Step 3.9).\n *\n * Read-only tools scoped to `ctx.tenantId` / `ctx.organizationId` that wrap\n * the existing customers query engine + encryption helpers. Mutation tools\n * are deferred to Step 5.13+ under the pending-action contract.\n *\n * Phase 3a of `.ai/specs/implemented/2026-04-27-ai-tools-api-backed-dry-refactor.md`:\n * `customers.list_people` is now an API-backed wrapper over\n * `GET /api/customers/people`. The `companyId` AI input has no inclusion\n * equivalent on the route (the route exposes `excludeLinkedCompanyId` only)\n * so it is pre-resolved against `CustomerPersonProfile.company` and threaded\n * through the route's `ids` filter.\n *\n * Phase 3c of the same spec migrates `customers.get_person` to a single\n * in-process call to `GET /api/customers/people/<id>?include=...` (the\n * documented aggregate detail route). Tool name, schema, requiredFeatures,\n * and output shape are unchanged.\n */\nimport { z } from 'zod'\nimport { defineApiBackedAiTool } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool'\nimport {\n createAiApiOperationRunner,\n type AiApiOperationRequest,\n type AiToolExecutionContext,\n} from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n CustomerPersonProfile,\n} from '../data/entities'\nimport { assertTenantScope, type CustomersAiToolDefinition, type CustomersToolContext } from './types'\nimport {\n buildRelatedRecords,\n buildScope,\n resolveEm,\n toCustomerListSummary,\n toIso,\n type CustomerRelatedRecords,\n} from './_shared'\n\nconst NIL_UUID = '00000000-0000-0000-0000-000000000000'\n\nconst listPeopleInput = z\n .object({\n q: z.string().trim().optional().describe('Optional search text matched against display name / email / phone. Omit or leave empty to list all.'),\n limit: z.number().int().min(1).max(100).optional().describe('Maximum rows to return (default 50, max 100).'),\n offset: z.number().int().min(0).optional().describe('Number of rows to skip (default 0).'),\n tags: z.array(z.string().uuid()).optional().describe('Restrict to persons carrying at least one of these tag ids.'),\n companyId: z.string().uuid().optional().describe('Restrict to persons linked to the given company entity.'),\n })\n .passthrough()\n\ntype ListPeopleInput = z.infer<typeof listPeopleInput>\n\ntype ListPeopleApiItem = {\n id?: string\n display_name?: string | null\n displayName?: string | null\n primary_email?: string | null\n primaryEmail?: string | null\n primary_phone?: string | null\n primaryPhone?: string | null\n status?: string | null\n lifecycle_stage?: string | null\n lifecycleStage?: string | null\n source?: string | null\n owner_user_id?: string | null\n ownerUserId?: string | null\n organization_id?: string | null\n organizationId?: string | null\n tenant_id?: string | null\n tenantId?: string | null\n created_at?: string | null\n createdAt?: string | null\n}\n\ntype ListPeopleApiResponse = {\n items?: ListPeopleApiItem[]\n total?: number\n}\n\ntype ListPeopleOutput = {\n items: Array<Record<string, unknown>>\n total: number\n limit: number\n offset: number\n}\n\nconst listPeopleTool = defineApiBackedAiTool<ListPeopleInput, ListPeopleApiResponse, ListPeopleOutput>({\n name: 'customers.list_people',\n displayName: 'List people',\n description:\n 'Search / list people (CRM persons) for the caller tenant + organization. Returns { items, total, limit, offset }.',\n inputSchema: listPeopleInput,\n requiredFeatures: ['customers.people.view'],\n toOperation: async (input, ctx) => {\n const { tenantId } = assertTenantScope(ctx as unknown as CustomersToolContext)\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const page = Math.floor(offset / limit) + 1\n\n const query: Record<string, string | number | boolean | null | undefined> = {\n page,\n pageSize: limit,\n }\n if (input.q?.trim()) query.search = input.q.trim()\n if (input.tags && input.tags.length > 0) query.tagIds = input.tags.join(',')\n\n if (input.companyId) {\n const em = resolveEm(ctx)\n const profiles = await findWithDecryption<CustomerPersonProfile>(\n em,\n CustomerPersonProfile,\n { tenantId, company: input.companyId } as never,\n undefined,\n buildScope(ctx, tenantId),\n )\n const ids = profiles\n .map((profile) => {\n const entity = (profile as { entity?: unknown }).entity\n if (!entity) return null\n if (typeof entity === 'string') return entity\n const candidate = (entity as { id?: unknown }).id\n return typeof candidate === 'string' ? candidate : null\n })\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n // Empty match \u2014 feed a non-existent uuid so the route returns\n // { items: [], total: 0 } without us bypassing the API.\n query.ids = ids.length ? ids.join(',') : NIL_UUID\n }\n\n const operation: AiApiOperationRequest = {\n method: 'GET',\n path: '/customers/people',\n query,\n }\n return operation\n },\n mapResponse: (response, input) => {\n const limit = input.limit ?? 50\n const offset = input.offset ?? 0\n const data = (response.data ?? {}) as ListPeopleApiResponse\n const rawItems: ListPeopleApiItem[] = Array.isArray(data.items) ? data.items : []\n return {\n items: rawItems.map((row) => toCustomerListSummary(row)),\n total: typeof data.total === 'number' ? data.total : 0,\n limit,\n offset,\n }\n },\n}) as unknown as CustomersAiToolDefinition\n\nconst getPersonInput = z.object({\n personId: z.string().uuid().describe('Person entity id (UUID).'),\n includeRelated: z\n .boolean()\n .optional()\n .describe('When true, include notes, activities, deals, addresses, tasks, and tags (each capped at 100).'),\n})\n\ntype GetPersonInput = z.infer<typeof getPersonInput>\n\ntype ApiPersonDetailRow = Record<string, unknown> | null | undefined\n\nconst getPersonTool: CustomersAiToolDefinition = {\n name: 'customers.get_person',\n displayName: 'Get person',\n description:\n 'Fetch a person customer record by id with profile fields and (optionally) notes, activities, deals, addresses, tasks, tags, and custom fields. Returns { found: false } when the record is outside tenant/org scope or missing.',\n inputSchema: getPersonInput,\n requiredFeatures: ['customers.people.view'],\n tags: ['read', 'customers'],\n handler: async (rawInput, ctx) => {\n const { tenantId } = assertTenantScope(ctx)\n const input: GetPersonInput = getPersonInput.parse(rawInput)\n const includeRelated = !!input.includeRelated\n\n const operation: AiApiOperationRequest = {\n method: 'GET',\n path: `/customers/people/${input.personId}`,\n }\n if (includeRelated) {\n operation.query = { include: 'addresses,comments,activities,interactions,deals,todos' }\n }\n\n const runner = createAiApiOperationRunner(ctx as unknown as AiToolExecutionContext)\n const response = await runner.run<Record<string, unknown>>(operation)\n if (!response.success) {\n if (response.statusCode === 404 || response.statusCode === 403) {\n return { found: false as const, personId: input.personId }\n }\n throw new Error(response.error ?? `Failed to fetch person ${input.personId}`)\n }\n const data = (response.data ?? {}) as Record<string, unknown>\n const personRow = (data.person ?? null) as ApiPersonDetailRow\n if (!personRow) {\n return { found: false as const, personId: input.personId }\n }\n const profileRow = (data.profile ?? null) as ApiPersonDetailRow\n const customFields = (data.customFields ?? {}) as Record<string, unknown>\n\n let related: CustomerRelatedRecords | null = null\n if (includeRelated) {\n related = buildRelatedRecords(data)\n }\n\n return {\n found: true as const,\n person: {\n id: personRow.id,\n displayName: personRow.displayName ?? null,\n description: personRow.description ?? null,\n primaryEmail: personRow.primaryEmail ?? null,\n primaryPhone: personRow.primaryPhone ?? null,\n status: personRow.status ?? null,\n lifecycleStage: personRow.lifecycleStage ?? null,\n source: personRow.source ?? null,\n ownerUserId: personRow.ownerUserId ?? null,\n organizationId: personRow.organizationId ?? null,\n tenantId: personRow.tenantId ?? null,\n createdAt: toIso(personRow.createdAt),\n updatedAt: toIso(personRow.updatedAt),\n },\n profile: profileRow\n ? {\n id: profileRow.id,\n firstName: profileRow.firstName ?? null,\n lastName: profileRow.lastName ?? null,\n preferredName: profileRow.preferredName ?? null,\n jobTitle: profileRow.jobTitle ?? null,\n department: profileRow.department ?? null,\n seniority: profileRow.seniority ?? null,\n timezone: profileRow.timezone ?? null,\n linkedInUrl: profileRow.linkedInUrl ?? null,\n twitterUrl: profileRow.twitterUrl ?? null,\n companyEntityId: profileRow.companyEntityId ?? null,\n }\n : null,\n customFields,\n related,\n }\n },\n}\n\nexport const peopleAiTools: CustomersAiToolDefinition[] = [listPeopleTool, getPersonTool]\n\nexport default peopleAiTools\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -180,21 +180,7 @@ function mapLegacyActivity(activity) {
180
180
  customValues: null
181
181
  };
182
182
  }
183
- async function listCanonicalActivities(em, container, auth, selectedOrganizationId, tenantId, organizationIds, query, options, isUnrestricted) {
184
- if (organizationIds && organizationIds.length === 0 && !isUnrestricted) {
185
- return {
186
- items: [],
187
- total: 0,
188
- bridgeIds: /* @__PURE__ */ new Set()
189
- };
190
- }
191
- if (organizationIds === null && !isUnrestricted) {
192
- return {
193
- items: [],
194
- total: 0,
195
- bridgeIds: /* @__PURE__ */ new Set()
196
- };
197
- }
183
+ async function listCanonicalActivities(em, container, auth, selectedOrganizationId, tenantId, organizationIds, query, options) {
198
184
  const where = {
199
185
  tenantId,
200
186
  interactionType: { $ne: "task" }
@@ -247,13 +233,7 @@ async function listCanonicalActivities(em, container, auth, selectedOrganization
247
233
  bridgeIds: new Set(rows.map((row) => row.id))
248
234
  };
249
235
  }
250
- async function listLegacyActivities(em, tenantId, organizationIds, query, options, selectedOrganizationId, isUnrestricted) {
251
- if (organizationIds && organizationIds.length === 0 && !isUnrestricted) {
252
- return { items: [], total: 0 };
253
- }
254
- if (organizationIds === null && !isUnrestricted) {
255
- return { items: [], total: 0 };
256
- }
236
+ async function listLegacyActivities(em, tenantId, organizationIds, query, options, selectedOrganizationId) {
257
237
  const where = { tenantId };
258
238
  if (organizationIds && organizationIds.length > 0) {
259
239
  where.organizationId = { $in: organizationIds };
@@ -289,30 +269,12 @@ async function GET(request) {
289
269
  em,
290
270
  organizationIds,
291
271
  container,
292
- selectedOrganizationId,
293
- scope
272
+ selectedOrganizationId
294
273
  } = await resolveCustomersRequestContext(request);
295
274
  const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId);
296
275
  if (!flags.legacyAdapters) {
297
276
  return await legacyAdaptersDisabledResponse();
298
277
  }
299
- const isUnrestricted = auth.isSuperAdmin === true || scope?.allowedIds === null;
300
- if (!isUnrestricted && (!organizationIds || organizationIds.length === 0)) {
301
- logger.warn("activities.list collapsed organization scope \u2014 returning empty page", {
302
- tenantId: auth.tenantId,
303
- organizationIds,
304
- scope
305
- });
306
- return withAdapterHeaders(
307
- NextResponse.json({
308
- items: [],
309
- total: 0,
310
- page: query.page,
311
- pageSize: query.pageSize,
312
- totalPages: 1
313
- })
314
- );
315
- }
316
278
  const sortDir = query.sortDir ?? "desc";
317
279
  const result = flags.unified ? await listCanonicalActivities(
318
280
  em,
@@ -321,9 +283,7 @@ async function GET(request) {
321
283
  selectedOrganizationId,
322
284
  auth.tenantId,
323
285
  organizationIds,
324
- query,
325
- void 0,
326
- isUnrestricted
286
+ query
327
287
  ) : await (async () => {
328
288
  const windowSize = Math.min(
329
289
  MERGED_ACTIVITY_FETCH_CAP,
@@ -337,8 +297,7 @@ async function GET(request) {
337
297
  organizationIds,
338
298
  windowedQuery,
339
299
  { paginate: true },
340
- selectedOrganizationId,
341
- isUnrestricted
300
+ selectedOrganizationId
342
301
  ),
343
302
  listCanonicalActivities(
344
303
  em,
@@ -352,8 +311,7 @@ async function GET(request) {
352
311
  includeDeleted: true,
353
312
  paginate: true,
354
313
  source: CUSTOMER_INTERACTION_ACTIVITY_ADAPTER_SOURCE
355
- },
356
- isUnrestricted
314
+ }
357
315
  )
358
316
  ]);
359
317
  const merged = sortActivityItems(