@open-mercato/core 0.5.1-develop.2663.2c29774b5b → 0.5.1-develop.2681.c559bb2bc3

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 (687) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/action_log/index.js +8 -0
  3. package/dist/generated/entities/action_log/index.js.map +2 -2
  4. package/dist/generated/entities/customer_company_billing/index.js +23 -0
  5. package/dist/generated/entities/customer_company_billing/index.js.map +7 -0
  6. package/dist/generated/entities/customer_deal/index.js +8 -0
  7. package/dist/generated/entities/customer_deal/index.js.map +2 -2
  8. package/dist/generated/entities/customer_deal_stage_transition/index.js +31 -0
  9. package/dist/generated/entities/customer_deal_stage_transition/index.js.map +7 -0
  10. package/dist/generated/entities/customer_dictionary_kind_setting/index.js +21 -0
  11. package/dist/generated/entities/customer_dictionary_kind_setting/index.js.map +7 -0
  12. package/dist/generated/entities/customer_entity/index.js +8 -0
  13. package/dist/generated/entities/customer_entity/index.js.map +2 -2
  14. package/dist/generated/entities/customer_entity_role/index.js +23 -0
  15. package/dist/generated/entities/customer_entity_role/index.js.map +7 -0
  16. package/dist/generated/entities/customer_interaction/index.js +23 -1
  17. package/dist/generated/entities/customer_interaction/index.js.map +2 -2
  18. package/dist/generated/entities/customer_label/index.js +19 -0
  19. package/dist/generated/entities/customer_label/index.js.map +7 -0
  20. package/dist/generated/entities/customer_label_assignment/index.js +17 -0
  21. package/dist/generated/entities/customer_label_assignment/index.js.map +7 -0
  22. package/dist/generated/entities/customer_person_company_link/index.js +21 -0
  23. package/dist/generated/entities/customer_person_company_link/index.js.map +7 -0
  24. package/dist/generated/entities/customer_person_company_role/index.js +17 -0
  25. package/dist/generated/entities/customer_person_company_role/index.js.map +7 -0
  26. package/dist/generated/entities/dictionary_entry/index.js +4 -0
  27. package/dist/generated/entities/dictionary_entry/index.js.map +2 -2
  28. package/dist/generated/entities.ids.generated.js +9 -1
  29. package/dist/generated/entities.ids.generated.js.map +2 -2
  30. package/dist/generated/entity-fields-registry.js +116 -1
  31. package/dist/generated/entity-fields-registry.js.map +2 -2
  32. package/dist/modules/attachments/api/route.js +46 -8
  33. package/dist/modules/attachments/api/route.js.map +2 -2
  34. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +208 -0
  35. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +7 -0
  36. package/dist/modules/audit_logs/api/audit-logs/actions/route.js +52 -6
  37. package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
  38. package/dist/modules/audit_logs/cli.js +62 -0
  39. package/dist/modules/audit_logs/cli.js.map +7 -0
  40. package/dist/modules/audit_logs/data/entities.js +21 -1
  41. package/dist/modules/audit_logs/data/entities.js.map +2 -2
  42. package/dist/modules/audit_logs/data/validators.js +9 -1
  43. package/dist/modules/audit_logs/data/validators.js.map +2 -2
  44. package/dist/modules/audit_logs/lib/changeRows.js +34 -0
  45. package/dist/modules/audit_logs/lib/changeRows.js.map +7 -0
  46. package/dist/modules/audit_logs/lib/display-helpers.js +2 -20
  47. package/dist/modules/audit_logs/lib/display-helpers.js.map +3 -3
  48. package/dist/modules/audit_logs/lib/projections.js +58 -0
  49. package/dist/modules/audit_logs/lib/projections.js.map +7 -0
  50. package/dist/modules/audit_logs/migrations/Migration20260412160533.js +21 -0
  51. package/dist/modules/audit_logs/migrations/Migration20260412160533.js.map +7 -0
  52. package/dist/modules/audit_logs/services/actionLogService.js +313 -79
  53. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  54. package/dist/modules/customers/acl.js +3 -1
  55. package/dist/modules/customers/acl.js.map +2 -2
  56. package/dist/modules/customers/api/activities/route.js +4 -0
  57. package/dist/modules/customers/api/activities/route.js.map +2 -2
  58. package/dist/modules/customers/api/assignable-staff/route.js +208 -0
  59. package/dist/modules/customers/api/assignable-staff/route.js.map +7 -0
  60. package/dist/modules/customers/api/companies/[id]/people/route.js +205 -0
  61. package/dist/modules/customers/api/companies/[id]/people/route.js.map +7 -0
  62. package/dist/modules/customers/api/companies/[id]/roles/route.js +22 -0
  63. package/dist/modules/customers/api/companies/[id]/roles/route.js.map +7 -0
  64. package/dist/modules/customers/api/companies/[id]/route.js +374 -32
  65. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  66. package/dist/modules/customers/api/companies/route.js +82 -7
  67. package/dist/modules/customers/api/companies/route.js.map +2 -2
  68. package/dist/modules/customers/api/deals/[id]/companies/route.js +172 -0
  69. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +7 -0
  70. package/dist/modules/customers/api/deals/[id]/people/route.js +156 -0
  71. package/dist/modules/customers/api/deals/[id]/people/route.js.map +7 -0
  72. package/dist/modules/customers/api/deals/[id]/route.js +459 -53
  73. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  74. package/dist/modules/customers/api/deals/[id]/stats/route.js +195 -0
  75. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +7 -0
  76. package/dist/modules/customers/api/deals/route.js +20 -10
  77. package/dist/modules/customers/api/deals/route.js.map +3 -3
  78. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +105 -4
  79. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  80. package/dist/modules/customers/api/dictionaries/[kind]/route.js +118 -42
  81. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  82. package/dist/modules/customers/api/dictionaries/context.js +30 -6
  83. package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
  84. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +207 -0
  85. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +7 -0
  86. package/dist/modules/customers/api/entity-roles-factory.js +471 -0
  87. package/dist/modules/customers/api/entity-roles-factory.js.map +7 -0
  88. package/dist/modules/customers/api/interactions/conflicts/route.js +158 -0
  89. package/dist/modules/customers/api/interactions/conflicts/route.js.map +7 -0
  90. package/dist/modules/customers/api/interactions/counts/route.js +92 -0
  91. package/dist/modules/customers/api/interactions/counts/route.js.map +7 -0
  92. package/dist/modules/customers/api/interactions/route.js +83 -4
  93. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  94. package/dist/modules/customers/api/labels/assign/route.js +189 -0
  95. package/dist/modules/customers/api/labels/assign/route.js.map +7 -0
  96. package/dist/modules/customers/api/labels/auth.js +17 -0
  97. package/dist/modules/customers/api/labels/auth.js.map +7 -0
  98. package/dist/modules/customers/api/labels/route.js +281 -0
  99. package/dist/modules/customers/api/labels/route.js.map +7 -0
  100. package/dist/modules/customers/api/labels/table-errors.js +38 -0
  101. package/dist/modules/customers/api/labels/table-errors.js.map +7 -0
  102. package/dist/modules/customers/api/labels/unassign/route.js +184 -0
  103. package/dist/modules/customers/api/labels/unassign/route.js.map +7 -0
  104. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +292 -0
  105. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +7 -0
  106. package/dist/modules/customers/api/people/[id]/companies/context.js +66 -0
  107. package/dist/modules/customers/api/people/[id]/companies/context.js.map +7 -0
  108. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +334 -0
  109. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +7 -0
  110. package/dist/modules/customers/api/people/[id]/companies/route.js +205 -0
  111. package/dist/modules/customers/api/people/[id]/companies/route.js.map +7 -0
  112. package/dist/modules/customers/api/people/[id]/roles/route.js +22 -0
  113. package/dist/modules/customers/api/people/[id]/roles/route.js.map +7 -0
  114. package/dist/modules/customers/api/people/[id]/route.js +134 -21
  115. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  116. package/dist/modules/customers/api/people/route.js +122 -23
  117. package/dist/modules/customers/api/people/route.js.map +2 -2
  118. package/dist/modules/customers/api/todos/route.js +4 -0
  119. package/dist/modules/customers/api/todos/route.js.map +2 -2
  120. package/dist/modules/customers/api/utils.js +22 -0
  121. package/dist/modules/customers/api/utils.js.map +2 -2
  122. package/dist/modules/customers/backend/config/customers/page.js +2 -6
  123. package/dist/modules/customers/backend/config/customers/page.js.map +2 -2
  124. package/dist/modules/customers/backend/customers/companies/page.js +37 -26
  125. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  126. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +265 -262
  127. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +3 -3
  128. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js +23 -0
  129. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js.map +7 -0
  130. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js +1 -0
  131. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js.map +7 -0
  132. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +43 -0
  133. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +7 -0
  134. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +264 -0
  135. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +7 -0
  136. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +88 -0
  137. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +7 -0
  138. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +41 -0
  139. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +7 -0
  140. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +66 -0
  141. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +7 -0
  142. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js +39 -0
  143. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js.map +7 -0
  144. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js +49 -0
  145. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js.map +7 -0
  146. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +43 -0
  147. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +7 -0
  148. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js +28 -0
  149. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js.map +7 -0
  150. package/dist/modules/customers/backend/customers/deals/[id]/page.js +556 -503
  151. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +3 -3
  152. package/dist/modules/customers/backend/customers/deals/page.js +66 -21
  153. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  154. package/dist/modules/customers/backend/customers/people/page.js +36 -28
  155. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  156. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +318 -203
  157. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +3 -3
  158. package/dist/modules/customers/cli.js +105 -13
  159. package/dist/modules/customers/cli.js.map +2 -2
  160. package/dist/modules/customers/commands/activities.js +6 -0
  161. package/dist/modules/customers/commands/activities.js.map +2 -2
  162. package/dist/modules/customers/commands/deals.js +315 -107
  163. package/dist/modules/customers/commands/deals.js.map +2 -2
  164. package/dist/modules/customers/commands/dictionaries.js +166 -32
  165. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  166. package/dist/modules/customers/commands/dictionaryKindSettings.js +208 -0
  167. package/dist/modules/customers/commands/dictionaryKindSettings.js.map +7 -0
  168. package/dist/modules/customers/commands/entity-roles.js +415 -0
  169. package/dist/modules/customers/commands/entity-roles.js.map +7 -0
  170. package/dist/modules/customers/commands/index.js +4 -0
  171. package/dist/modules/customers/commands/index.js.map +2 -2
  172. package/dist/modules/customers/commands/interactions.js +108 -21
  173. package/dist/modules/customers/commands/interactions.js.map +2 -2
  174. package/dist/modules/customers/commands/labels.js +539 -0
  175. package/dist/modules/customers/commands/labels.js.map +7 -0
  176. package/dist/modules/customers/commands/people.js +560 -463
  177. package/dist/modules/customers/commands/people.js.map +3 -3
  178. package/dist/modules/customers/commands/personCompanyLinks.js +568 -0
  179. package/dist/modules/customers/commands/personCompanyLinks.js.map +7 -0
  180. package/dist/modules/customers/commands/shared.js +12 -4
  181. package/dist/modules/customers/commands/shared.js.map +2 -2
  182. package/dist/modules/customers/commands/todos.js +10 -1
  183. package/dist/modules/customers/commands/todos.js.map +2 -2
  184. package/dist/modules/customers/components/AddressEditor.js +1 -1
  185. package/dist/modules/customers/components/AddressEditor.js.map +2 -2
  186. package/dist/modules/customers/components/CustomersConfigurationSections.js +31 -0
  187. package/dist/modules/customers/components/CustomersConfigurationSections.js.map +7 -0
  188. package/dist/modules/customers/components/DictionarySettings.js +37 -2
  189. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  190. package/dist/modules/customers/components/detail/ActiveDealCard.js +121 -0
  191. package/dist/modules/customers/components/detail/ActiveDealCard.js.map +7 -0
  192. package/dist/modules/customers/components/detail/ActivitiesSection.js +222 -331
  193. package/dist/modules/customers/components/detail/ActivitiesSection.js.map +3 -3
  194. package/dist/modules/customers/components/detail/ActivityAiActions.js +36 -0
  195. package/dist/modules/customers/components/detail/ActivityAiActions.js.map +7 -0
  196. package/dist/modules/customers/components/detail/ActivityCard.js +126 -0
  197. package/dist/modules/customers/components/detail/ActivityCard.js.map +7 -0
  198. package/dist/modules/customers/components/detail/ActivityHistorySection.js +340 -0
  199. package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +7 -0
  200. package/dist/modules/customers/components/detail/ActivityLogTab.js +56 -0
  201. package/dist/modules/customers/components/detail/ActivityLogTab.js.map +7 -0
  202. package/dist/modules/customers/components/detail/ActivityTimeline.js +108 -0
  203. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +7 -0
  204. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +139 -0
  205. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +7 -0
  206. package/dist/modules/customers/components/detail/ActivityTypeSelector.js +42 -0
  207. package/dist/modules/customers/components/detail/ActivityTypeSelector.js.map +7 -0
  208. package/dist/modules/customers/components/detail/AiActionChips.js +38 -0
  209. package/dist/modules/customers/components/detail/AiActionChips.js.map +7 -0
  210. package/dist/modules/customers/components/detail/AssignRoleDialog.js +534 -0
  211. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +7 -0
  212. package/dist/modules/customers/components/detail/ChangelogEntryRow.js +79 -0
  213. package/dist/modules/customers/components/detail/ChangelogEntryRow.js.map +7 -0
  214. package/dist/modules/customers/components/detail/ChangelogFilters.js +176 -0
  215. package/dist/modules/customers/components/detail/ChangelogFilters.js.map +7 -0
  216. package/dist/modules/customers/components/detail/ChangelogKpiCards.js +88 -0
  217. package/dist/modules/customers/components/detail/ChangelogKpiCards.js.map +7 -0
  218. package/dist/modules/customers/components/detail/ChangelogTab.js +470 -0
  219. package/dist/modules/customers/components/detail/ChangelogTab.js.map +7 -0
  220. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js +16 -0
  221. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js.map +7 -0
  222. package/dist/modules/customers/components/detail/CompanyCard.js +283 -0
  223. package/dist/modules/customers/components/detail/CompanyCard.js.map +7 -0
  224. package/dist/modules/customers/components/detail/CompanyDashboardTab.js +133 -0
  225. package/dist/modules/customers/components/detail/CompanyDashboardTab.js.map +7 -0
  226. package/dist/modules/customers/components/detail/CompanyDetailHeader.js +191 -0
  227. package/dist/modules/customers/components/detail/CompanyDetailHeader.js.map +7 -0
  228. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +123 -0
  229. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +7 -0
  230. package/dist/modules/customers/components/detail/CompanyKpiBar.js +174 -0
  231. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +7 -0
  232. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +514 -230
  233. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/CompanyTagsDialog.js +22 -0
  235. package/dist/modules/customers/components/detail/CompanyTagsDialog.js.map +7 -0
  236. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +159 -0
  237. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +7 -0
  238. package/dist/modules/customers/components/detail/CreatePersonDialog.js +135 -0
  239. package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +7 -0
  240. package/dist/modules/customers/components/detail/DealClosureActionBar.js +59 -0
  241. package/dist/modules/customers/components/detail/DealClosureActionBar.js.map +7 -0
  242. package/dist/modules/customers/components/detail/DealDetailHeader.js +237 -0
  243. package/dist/modules/customers/components/detail/DealDetailHeader.js.map +7 -0
  244. package/dist/modules/customers/components/detail/DealDetailTabs.js +109 -0
  245. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +7 -0
  246. package/dist/modules/customers/components/detail/DealForm.js +219 -92
  247. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  248. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js +295 -0
  249. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js.map +7 -0
  250. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js +107 -0
  251. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js.map +7 -0
  252. package/dist/modules/customers/components/detail/DealWonPopup.js +113 -0
  253. package/dist/modules/customers/components/detail/DealWonPopup.js.map +7 -0
  254. package/dist/modules/customers/components/detail/DealsSection.js +206 -193
  255. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  256. package/dist/modules/customers/components/detail/DecisionMakersFooter.js +39 -0
  257. package/dist/modules/customers/components/detail/DecisionMakersFooter.js.map +7 -0
  258. package/dist/modules/customers/components/detail/EntityTagsDialog.js +1096 -0
  259. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +7 -0
  260. package/dist/modules/customers/components/detail/InlineActivityComposer.js +197 -0
  261. package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +7 -0
  262. package/dist/modules/customers/components/detail/ManageTagsDialog.js +1091 -0
  263. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +7 -0
  264. package/dist/modules/customers/components/detail/MiniWeekCalendar.js +272 -0
  265. package/dist/modules/customers/components/detail/MiniWeekCalendar.js.map +7 -0
  266. package/dist/modules/customers/components/detail/MobilePersonDetail.js +106 -0
  267. package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +7 -0
  268. package/dist/modules/customers/components/detail/NextStepCard.js +72 -0
  269. package/dist/modules/customers/components/detail/NextStepCard.js.map +7 -0
  270. package/dist/modules/customers/components/detail/PersonCard.js +192 -0
  271. package/dist/modules/customers/components/detail/PersonCard.js.map +7 -0
  272. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +345 -0
  273. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +7 -0
  274. package/dist/modules/customers/components/detail/PersonDetailHeader.js +220 -0
  275. package/dist/modules/customers/components/detail/PersonDetailHeader.js.map +7 -0
  276. package/dist/modules/customers/components/detail/PersonDetailTabs.js +122 -0
  277. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +7 -0
  278. package/dist/modules/customers/components/detail/PersonTagsDialog.js +24 -0
  279. package/dist/modules/customers/components/detail/PersonTagsDialog.js.map +7 -0
  280. package/dist/modules/customers/components/detail/PipelineStepper.js +191 -0
  281. package/dist/modules/customers/components/detail/PipelineStepper.js.map +7 -0
  282. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js +222 -0
  283. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js.map +7 -0
  284. package/dist/modules/customers/components/detail/RelationshipHealthCard.js +49 -0
  285. package/dist/modules/customers/components/detail/RelationshipHealthCard.js.map +7 -0
  286. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +189 -0
  287. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +7 -0
  288. package/dist/modules/customers/components/detail/RolesSection.js +234 -0
  289. package/dist/modules/customers/components/detail/RolesSection.js.map +7 -0
  290. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +410 -0
  291. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +7 -0
  292. package/dist/modules/customers/components/detail/aiActionCatalog.js +41 -0
  293. package/dist/modules/customers/components/detail/aiActionCatalog.js.map +7 -0
  294. package/dist/modules/customers/components/detail/assignableStaff.js +48 -0
  295. package/dist/modules/customers/components/detail/assignableStaff.js.map +7 -0
  296. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js +48 -0
  297. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js.map +7 -0
  298. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js +86 -0
  299. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js.map +7 -0
  300. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js +53 -0
  301. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js.map +7 -0
  302. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js +30 -0
  303. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js.map +7 -0
  304. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js +43 -0
  305. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js.map +7 -0
  306. package/dist/modules/customers/components/detail/dashboard/helpers.js +71 -0
  307. package/dist/modules/customers/components/detail/dashboard/helpers.js.map +7 -0
  308. package/dist/modules/customers/components/detail/healthScoreUtils.js +69 -0
  309. package/dist/modules/customers/components/detail/healthScoreUtils.js.map +7 -0
  310. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js +5 -5
  311. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js.map +2 -2
  312. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +9 -8
  313. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +3 -3
  314. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +65 -0
  315. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +7 -0
  316. package/dist/modules/customers/components/detail/notesAdapter.js +70 -30
  317. package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
  318. package/dist/modules/customers/components/detail/pipelineStageUtils.js +26 -0
  319. package/dist/modules/customers/components/detail/pipelineStageUtils.js.map +7 -0
  320. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +144 -0
  321. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +7 -0
  322. package/dist/modules/customers/components/detail/schedule/FooterFields.js +60 -0
  323. package/dist/modules/customers/components/detail/schedule/FooterFields.js.map +7 -0
  324. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js +216 -0
  325. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js.map +7 -0
  326. package/dist/modules/customers/components/detail/schedule/LocationField.js +34 -0
  327. package/dist/modules/customers/components/detail/schedule/LocationField.js.map +7 -0
  328. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +226 -0
  329. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +7 -0
  330. package/dist/modules/customers/components/detail/schedule/fieldConfig.js +69 -0
  331. package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +7 -0
  332. package/dist/modules/customers/components/detail/schedule/index.js +21 -0
  333. package/dist/modules/customers/components/detail/schedule/index.js.map +7 -0
  334. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +172 -0
  335. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +7 -0
  336. package/dist/modules/customers/components/detail/utils.js +23 -0
  337. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  338. package/dist/modules/customers/components/formConfig.js +144 -22
  339. package/dist/modules/customers/components/formConfig.js.map +2 -2
  340. package/dist/modules/customers/components/linking/LinkEntityDialog.js +661 -0
  341. package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +7 -0
  342. package/dist/modules/customers/components/linking/adapters/companyAdapter.js +252 -0
  343. package/dist/modules/customers/components/linking/adapters/companyAdapter.js.map +7 -0
  344. package/dist/modules/customers/components/linking/adapters/dealAdapter.js +384 -0
  345. package/dist/modules/customers/components/linking/adapters/dealAdapter.js.map +7 -0
  346. package/dist/modules/customers/components/linking/adapters/personAdapter.js +324 -0
  347. package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +7 -0
  348. package/dist/modules/customers/components/list/CollectionPreviewCell.js +53 -0
  349. package/dist/modules/customers/components/list/CollectionPreviewCell.js.map +7 -0
  350. package/dist/modules/customers/data/entities.js +407 -1
  351. package/dist/modules/customers/data/entities.js.map +2 -2
  352. package/dist/modules/customers/data/validators.js +139 -21
  353. package/dist/modules/customers/data/validators.js.map +2 -2
  354. package/dist/modules/customers/events.js +19 -1
  355. package/dist/modules/customers/events.js.map +2 -2
  356. package/dist/modules/customers/lib/customerRoleTypes.js +19 -0
  357. package/dist/modules/customers/lib/customerRoleTypes.js.map +7 -0
  358. package/dist/modules/customers/lib/dealClosureNotification.js +39 -0
  359. package/dist/modules/customers/lib/dealClosureNotification.js.map +7 -0
  360. package/dist/modules/customers/lib/dealStageTransitionTable.js +29 -0
  361. package/dist/modules/customers/lib/dealStageTransitionTable.js.map +7 -0
  362. package/dist/modules/customers/lib/dictionaries.js +25 -0
  363. package/dist/modules/customers/lib/dictionaries.js.map +2 -2
  364. package/dist/modules/customers/lib/interactionReadModel.js +10 -0
  365. package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
  366. package/dist/modules/customers/lib/personCompanies.js +235 -0
  367. package/dist/modules/customers/lib/personCompanies.js.map +7 -0
  368. package/dist/modules/customers/lib/personCompanyLinkTable.js +42 -0
  369. package/dist/modules/customers/lib/personCompanyLinkTable.js.map +7 -0
  370. package/dist/modules/customers/lib/roleTypeUsage.js +104 -0
  371. package/dist/modules/customers/lib/roleTypeUsage.js.map +7 -0
  372. package/dist/modules/customers/migrations/Migration20260406214502.js +18 -0
  373. package/dist/modules/customers/migrations/Migration20260406214502.js.map +7 -0
  374. package/dist/modules/customers/migrations/Migration20260408135736.js +17 -0
  375. package/dist/modules/customers/migrations/Migration20260408135736.js.map +7 -0
  376. package/dist/modules/customers/migrations/Migration20260408225345.js +21 -0
  377. package/dist/modules/customers/migrations/Migration20260408225345.js.map +7 -0
  378. package/dist/modules/customers/migrations/Migration20260411075533.js +27 -0
  379. package/dist/modules/customers/migrations/Migration20260411075533.js.map +7 -0
  380. package/dist/modules/customers/migrations/Migration20260411103551.js +13 -0
  381. package/dist/modules/customers/migrations/Migration20260411103551.js.map +7 -0
  382. package/dist/modules/customers/migrations/Migration20260411130944.js +26 -0
  383. package/dist/modules/customers/migrations/Migration20260411130944.js.map +7 -0
  384. package/dist/modules/customers/migrations/Migration20260415095203.js +13 -0
  385. package/dist/modules/customers/migrations/Migration20260415095203.js.map +7 -0
  386. package/dist/modules/customers/migrations/Migration20260415135056.js +20 -0
  387. package/dist/modules/customers/migrations/Migration20260415135056.js.map +7 -0
  388. package/dist/modules/customers/migrations/Migration20260417140000.js +15 -0
  389. package/dist/modules/customers/migrations/Migration20260417140000.js.map +7 -0
  390. package/dist/modules/customers/migrations/Migration20260417160000.js +17 -0
  391. package/dist/modules/customers/migrations/Migration20260417160000.js.map +7 -0
  392. package/dist/modules/customers/migrations/Migration20260417235407.js +13 -0
  393. package/dist/modules/customers/migrations/Migration20260417235407.js.map +7 -0
  394. package/dist/modules/customers/setup.js +16 -1
  395. package/dist/modules/customers/setup.js.map +2 -2
  396. package/dist/modules/customers/subscribers/deal-closure-notification.js +16 -0
  397. package/dist/modules/customers/subscribers/deal-closure-notification.js.map +7 -0
  398. package/dist/modules/customers/subscribers/deal-lost-notification.js +16 -0
  399. package/dist/modules/customers/subscribers/deal-lost-notification.js.map +7 -0
  400. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +2 -0
  401. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  402. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +154 -0
  403. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +7 -0
  404. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +6 -2
  405. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  406. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +154 -0
  407. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +7 -0
  408. package/dist/modules/dictionaries/api/context.js +8 -1
  409. package/dist/modules/dictionaries/api/context.js.map +2 -2
  410. package/dist/modules/dictionaries/api/openapi.js +18 -1
  411. package/dist/modules/dictionaries/api/openapi.js.map +2 -2
  412. package/dist/modules/dictionaries/commands/entry-operations.js +388 -0
  413. package/dist/modules/dictionaries/commands/entry-operations.js.map +7 -0
  414. package/dist/modules/dictionaries/commands/factory.js +24 -3
  415. package/dist/modules/dictionaries/commands/factory.js.map +2 -2
  416. package/dist/modules/dictionaries/commands/index.js +1 -0
  417. package/dist/modules/dictionaries/commands/index.js.map +2 -2
  418. package/dist/modules/dictionaries/components/DictionaryTable.js +6 -3
  419. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  420. package/dist/modules/dictionaries/data/entities.js +11 -1
  421. package/dist/modules/dictionaries/data/entities.js.map +2 -2
  422. package/dist/modules/dictionaries/data/validators.js +28 -2
  423. package/dist/modules/dictionaries/data/validators.js.map +2 -2
  424. package/dist/modules/dictionaries/events.js +18 -0
  425. package/dist/modules/dictionaries/events.js.map +7 -0
  426. package/dist/modules/dictionaries/lib/clientEntries.js +43 -0
  427. package/dist/modules/dictionaries/lib/clientEntries.js.map +7 -0
  428. package/dist/modules/dictionaries/migrations/Migration20260410171544.js +45 -0
  429. package/dist/modules/dictionaries/migrations/Migration20260410171544.js.map +7 -0
  430. package/dist/modules/inbox_ops/api/proposals/[id]/route.js +4 -1
  431. package/dist/modules/inbox_ops/api/proposals/[id]/route.js.map +2 -2
  432. package/dist/modules/query_index/lib/engine.js +1 -1
  433. package/dist/modules/query_index/lib/engine.js.map +2 -2
  434. package/dist/modules/sales/components/documents/AddressesSection.js +82 -42
  435. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  436. package/dist/modules/sales/lib/dictionaries.js +16 -0
  437. package/dist/modules/sales/lib/dictionaries.js.map +2 -2
  438. package/dist/modules/sales/widgets/injection-table.js +5 -1
  439. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  440. package/generated/entities/action_log/index.ts +4 -0
  441. package/generated/entities/customer_company_billing/index.ts +10 -0
  442. package/generated/entities/customer_deal/index.ts +4 -0
  443. package/generated/entities/customer_deal_stage_transition/index.ts +14 -0
  444. package/generated/entities/customer_dictionary_kind_setting/index.ts +9 -0
  445. package/generated/entities/customer_entity/index.ts +4 -0
  446. package/generated/entities/customer_entity_role/index.ts +10 -0
  447. package/generated/entities/customer_interaction/index.ts +11 -0
  448. package/generated/entities/customer_label/index.ts +8 -0
  449. package/generated/entities/customer_label_assignment/index.ts +7 -0
  450. package/generated/entities/customer_person_company_link/index.ts +9 -0
  451. package/generated/entities/customer_person_company_role/index.ts +7 -0
  452. package/generated/entities/dictionary_entry/index.ts +2 -0
  453. package/generated/entities.ids.generated.ts +9 -1
  454. package/generated/entity-fields-registry.ts +116 -1
  455. package/package.json +3 -3
  456. package/src/modules/attachments/api/route.ts +48 -6
  457. package/src/modules/attachments/i18n/de.json +4 -0
  458. package/src/modules/attachments/i18n/en.json +4 -0
  459. package/src/modules/attachments/i18n/es.json +4 -0
  460. package/src/modules/attachments/i18n/pl.json +4 -0
  461. package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +260 -0
  462. package/src/modules/audit_logs/api/audit-logs/actions/route.ts +81 -6
  463. package/src/modules/audit_logs/cli.ts +79 -0
  464. package/src/modules/audit_logs/data/entities.ts +17 -0
  465. package/src/modules/audit_logs/data/validators.ts +9 -1
  466. package/src/modules/audit_logs/lib/changeRows.ts +47 -0
  467. package/src/modules/audit_logs/lib/display-helpers.tsx +4 -30
  468. package/src/modules/audit_logs/lib/projections.ts +110 -0
  469. package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +325 -2
  470. package/src/modules/audit_logs/migrations/Migration20260412160533.ts +21 -0
  471. package/src/modules/audit_logs/services/actionLogService.ts +455 -85
  472. package/src/modules/catalog/i18n/de.json +1 -0
  473. package/src/modules/catalog/i18n/en.json +1 -0
  474. package/src/modules/catalog/i18n/es.json +1 -0
  475. package/src/modules/catalog/i18n/pl.json +1 -0
  476. package/src/modules/customer_accounts/i18n/de.json +2 -0
  477. package/src/modules/customer_accounts/i18n/en.json +2 -0
  478. package/src/modules/customer_accounts/i18n/es.json +2 -0
  479. package/src/modules/customer_accounts/i18n/pl.json +2 -0
  480. package/src/modules/customers/acl.ts +2 -0
  481. package/src/modules/customers/api/activities/route.ts +4 -0
  482. package/src/modules/customers/api/assignable-staff/route.ts +250 -0
  483. package/src/modules/customers/api/companies/[id]/people/route.ts +244 -0
  484. package/src/modules/customers/api/companies/[id]/roles/route.ts +15 -0
  485. package/src/modules/customers/api/companies/[id]/route.ts +458 -40
  486. package/src/modules/customers/api/companies/route.ts +93 -15
  487. package/src/modules/customers/api/deals/[id]/companies/route.ts +203 -0
  488. package/src/modules/customers/api/deals/[id]/people/route.ts +182 -0
  489. package/src/modules/customers/api/deals/[id]/route.ts +554 -57
  490. package/src/modules/customers/api/deals/[id]/stats/route.ts +221 -0
  491. package/src/modules/customers/api/deals/route.ts +35 -46
  492. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +105 -3
  493. package/src/modules/customers/api/dictionaries/[kind]/route.ts +143 -44
  494. package/src/modules/customers/api/dictionaries/context.ts +45 -16
  495. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +232 -0
  496. package/src/modules/customers/api/entity-roles-factory.ts +520 -0
  497. package/src/modules/customers/api/interactions/conflicts/route.ts +196 -0
  498. package/src/modules/customers/api/interactions/counts/route.ts +112 -0
  499. package/src/modules/customers/api/interactions/route.ts +95 -2
  500. package/src/modules/customers/api/labels/assign/route.ts +202 -0
  501. package/src/modules/customers/api/labels/auth.ts +19 -0
  502. package/src/modules/customers/api/labels/route.ts +310 -0
  503. package/src/modules/customers/api/labels/table-errors.ts +36 -0
  504. package/src/modules/customers/api/labels/unassign/route.ts +197 -0
  505. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +331 -0
  506. package/src/modules/customers/api/people/[id]/companies/context.ts +70 -0
  507. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +384 -0
  508. package/src/modules/customers/api/people/[id]/companies/route.ts +215 -0
  509. package/src/modules/customers/api/people/[id]/roles/route.ts +15 -0
  510. package/src/modules/customers/api/people/[id]/route.ts +153 -26
  511. package/src/modules/customers/api/people/route.ts +134 -31
  512. package/src/modules/customers/api/todos/route.ts +4 -0
  513. package/src/modules/customers/api/utils.ts +36 -0
  514. package/src/modules/customers/backend/config/customers/page.tsx +2 -6
  515. package/src/modules/customers/backend/customers/companies/page.tsx +36 -26
  516. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +277 -262
  517. package/src/modules/customers/backend/customers/deals/[id]/hooks/formatters.ts +19 -0
  518. package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +104 -0
  519. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +60 -0
  520. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +362 -0
  521. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +113 -0
  522. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +52 -0
  523. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +86 -0
  524. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.tsx +60 -0
  525. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.ts +76 -0
  526. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +56 -0
  527. package/src/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.ts +38 -0
  528. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +587 -624
  529. package/src/modules/customers/backend/customers/deals/page.tsx +71 -28
  530. package/src/modules/customers/backend/customers/people/page.tsx +35 -29
  531. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +343 -209
  532. package/src/modules/customers/cli.ts +107 -12
  533. package/src/modules/customers/commands/activities.ts +13 -0
  534. package/src/modules/customers/commands/deals.ts +386 -114
  535. package/src/modules/customers/commands/dictionaries.ts +175 -32
  536. package/src/modules/customers/commands/dictionaryKindSettings.ts +268 -0
  537. package/src/modules/customers/commands/entity-roles.ts +494 -0
  538. package/src/modules/customers/commands/index.ts +4 -0
  539. package/src/modules/customers/commands/interactions.ts +125 -21
  540. package/src/modules/customers/commands/labels.ts +626 -0
  541. package/src/modules/customers/commands/people.ts +373 -259
  542. package/src/modules/customers/commands/personCompanyLinks.ts +654 -0
  543. package/src/modules/customers/commands/shared.ts +16 -15
  544. package/src/modules/customers/commands/todos.ts +17 -1
  545. package/src/modules/customers/components/AddressEditor.tsx +1 -1
  546. package/src/modules/customers/components/CustomersConfigurationSections.tsx +36 -0
  547. package/src/modules/customers/components/DictionarySettings.tsx +43 -2
  548. package/src/modules/customers/components/detail/ActiveDealCard.tsx +175 -0
  549. package/src/modules/customers/components/detail/ActivitiesSection.tsx +267 -361
  550. package/src/modules/customers/components/detail/ActivityAiActions.tsx +49 -0
  551. package/src/modules/customers/components/detail/ActivityCard.tsx +154 -0
  552. package/src/modules/customers/components/detail/ActivityHistorySection.tsx +412 -0
  553. package/src/modules/customers/components/detail/ActivityLogTab.tsx +67 -0
  554. package/src/modules/customers/components/detail/ActivityTimeline.tsx +158 -0
  555. package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +163 -0
  556. package/src/modules/customers/components/detail/ActivityTypeSelector.tsx +53 -0
  557. package/src/modules/customers/components/detail/AiActionChips.tsx +48 -0
  558. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +672 -0
  559. package/src/modules/customers/components/detail/ChangelogEntryRow.tsx +132 -0
  560. package/src/modules/customers/components/detail/ChangelogFilters.tsx +193 -0
  561. package/src/modules/customers/components/detail/ChangelogKpiCards.tsx +107 -0
  562. package/src/modules/customers/components/detail/ChangelogTab.tsx +629 -0
  563. package/src/modules/customers/components/detail/ComingSoonPlaceholder.tsx +21 -0
  564. package/src/modules/customers/components/detail/CompanyCard.tsx +419 -0
  565. package/src/modules/customers/components/detail/CompanyDashboardTab.tsx +161 -0
  566. package/src/modules/customers/components/detail/CompanyDetailHeader.tsx +243 -0
  567. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +172 -0
  568. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +206 -0
  569. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +582 -288
  570. package/src/modules/customers/components/detail/CompanyTagsDialog.tsx +23 -0
  571. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +210 -0
  572. package/src/modules/customers/components/detail/CreatePersonDialog.tsx +178 -0
  573. package/src/modules/customers/components/detail/DealClosureActionBar.tsx +63 -0
  574. package/src/modules/customers/components/detail/DealDetailHeader.tsx +335 -0
  575. package/src/modules/customers/components/detail/DealDetailTabs.tsx +154 -0
  576. package/src/modules/customers/components/detail/DealForm.tsx +253 -101
  577. package/src/modules/customers/components/detail/DealLinkedEntitiesTab.tsx +349 -0
  578. package/src/modules/customers/components/detail/DealLostSummaryDialog.tsx +156 -0
  579. package/src/modules/customers/components/detail/DealWonPopup.tsx +164 -0
  580. package/src/modules/customers/components/detail/DealsSection.tsx +276 -221
  581. package/src/modules/customers/components/detail/DecisionMakersFooter.tsx +56 -0
  582. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +1372 -0
  583. package/src/modules/customers/components/detail/InlineActivityComposer.tsx +239 -0
  584. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1331 -0
  585. package/src/modules/customers/components/detail/MiniWeekCalendar.tsx +338 -0
  586. package/src/modules/customers/components/detail/MobilePersonDetail.tsx +124 -0
  587. package/src/modules/customers/components/detail/NextStepCard.tsx +104 -0
  588. package/src/modules/customers/components/detail/PersonCard.tsx +238 -0
  589. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +426 -0
  590. package/src/modules/customers/components/detail/PersonDetailHeader.tsx +294 -0
  591. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +172 -0
  592. package/src/modules/customers/components/detail/PersonTagsDialog.tsx +26 -0
  593. package/src/modules/customers/components/detail/PipelineStepper.tsx +245 -0
  594. package/src/modules/customers/components/detail/PlannedActivitiesSection.tsx +255 -0
  595. package/src/modules/customers/components/detail/RelationshipHealthCard.tsx +63 -0
  596. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +248 -0
  597. package/src/modules/customers/components/detail/RolesSection.tsx +311 -0
  598. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +481 -0
  599. package/src/modules/customers/components/detail/aiActionCatalog.ts +77 -0
  600. package/src/modules/customers/components/detail/assignableStaff.ts +124 -0
  601. package/src/modules/customers/components/detail/dashboard/ActiveDealWidget.tsx +63 -0
  602. package/src/modules/customers/components/detail/dashboard/OpenTasksWidget.tsx +114 -0
  603. package/src/modules/customers/components/detail/dashboard/RecentActivityWidget.tsx +69 -0
  604. package/src/modules/customers/components/detail/dashboard/RelationshipHealthWidget.tsx +40 -0
  605. package/src/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.tsx +64 -0
  606. package/src/modules/customers/components/detail/dashboard/helpers.ts +78 -0
  607. package/src/modules/customers/components/detail/healthScoreUtils.ts +91 -0
  608. package/src/modules/customers/components/detail/hooks/useCurrencyDictionary.ts +8 -8
  609. package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +10 -6
  610. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +91 -0
  611. package/src/modules/customers/components/detail/notesAdapter.ts +91 -30
  612. package/src/modules/customers/components/detail/pipelineStageUtils.ts +29 -0
  613. package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +187 -0
  614. package/src/modules/customers/components/detail/schedule/FooterFields.tsx +79 -0
  615. package/src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx +277 -0
  616. package/src/modules/customers/components/detail/schedule/LocationField.tsx +42 -0
  617. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +255 -0
  618. package/src/modules/customers/components/detail/schedule/fieldConfig.ts +70 -0
  619. package/src/modules/customers/components/detail/schedule/index.ts +9 -0
  620. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +221 -0
  621. package/src/modules/customers/components/detail/types.ts +16 -0
  622. package/src/modules/customers/components/detail/utils.ts +25 -0
  623. package/src/modules/customers/components/formConfig.tsx +223 -28
  624. package/src/modules/customers/components/linking/LinkEntityDialog.tsx +920 -0
  625. package/src/modules/customers/components/linking/adapters/companyAdapter.tsx +398 -0
  626. package/src/modules/customers/components/linking/adapters/dealAdapter.tsx +578 -0
  627. package/src/modules/customers/components/linking/adapters/personAdapter.tsx +512 -0
  628. package/src/modules/customers/components/list/CollectionPreviewCell.tsx +66 -0
  629. package/src/modules/customers/data/entities.ts +353 -1
  630. package/src/modules/customers/data/validators.ts +170 -19
  631. package/src/modules/customers/events.ts +22 -0
  632. package/src/modules/customers/i18n/de.json +841 -2
  633. package/src/modules/customers/i18n/en.json +841 -2
  634. package/src/modules/customers/i18n/es.json +840 -1
  635. package/src/modules/customers/i18n/pl.json +841 -2
  636. package/src/modules/customers/lib/customerRoleTypes.ts +24 -0
  637. package/src/modules/customers/lib/dealClosureNotification.ts +64 -0
  638. package/src/modules/customers/lib/dealStageTransitionTable.ts +32 -0
  639. package/src/modules/customers/lib/dictionaries.ts +26 -10
  640. package/src/modules/customers/lib/interactionReadModel.ts +10 -0
  641. package/src/modules/customers/lib/personCompanies.ts +317 -0
  642. package/src/modules/customers/lib/personCompanyLinkTable.ts +58 -0
  643. package/src/modules/customers/lib/roleTypeUsage.ts +146 -0
  644. package/src/modules/customers/migrations/.snapshot-open-mercato.json +2747 -798
  645. package/src/modules/customers/migrations/Migration20260406214502.ts +19 -0
  646. package/src/modules/customers/migrations/Migration20260408135736.ts +15 -0
  647. package/src/modules/customers/migrations/Migration20260408225345.ts +23 -0
  648. package/src/modules/customers/migrations/Migration20260411075533.ts +30 -0
  649. package/src/modules/customers/migrations/Migration20260411103551.ts +13 -0
  650. package/src/modules/customers/migrations/Migration20260411130944.ts +30 -0
  651. package/src/modules/customers/migrations/Migration20260415095203.ts +13 -0
  652. package/src/modules/customers/migrations/Migration20260415135056.ts +22 -0
  653. package/src/modules/customers/migrations/Migration20260417140000.ts +15 -0
  654. package/src/modules/customers/migrations/Migration20260417160000.ts +17 -0
  655. package/src/modules/customers/migrations/Migration20260417235407.ts +13 -0
  656. package/src/modules/customers/setup.ts +15 -0
  657. package/src/modules/customers/subscribers/deal-closure-notification.ts +22 -0
  658. package/src/modules/customers/subscribers/deal-lost-notification.ts +22 -0
  659. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +2 -0
  660. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +162 -0
  661. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +6 -2
  662. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +162 -0
  663. package/src/modules/dictionaries/api/context.ts +9 -0
  664. package/src/modules/dictionaries/api/openapi.ts +17 -0
  665. package/src/modules/dictionaries/commands/entry-operations.ts +457 -0
  666. package/src/modules/dictionaries/commands/factory.ts +31 -3
  667. package/src/modules/dictionaries/commands/index.ts +1 -0
  668. package/src/modules/dictionaries/components/DictionaryTable.tsx +15 -6
  669. package/src/modules/dictionaries/data/entities.ts +9 -0
  670. package/src/modules/dictionaries/data/validators.ts +34 -0
  671. package/src/modules/dictionaries/events.ts +20 -0
  672. package/src/modules/dictionaries/i18n/de.json +2 -0
  673. package/src/modules/dictionaries/i18n/en.json +2 -0
  674. package/src/modules/dictionaries/i18n/es.json +2 -0
  675. package/src/modules/dictionaries/i18n/pl.json +2 -0
  676. package/src/modules/dictionaries/lib/clientEntries.ts +66 -0
  677. package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +185 -3
  678. package/src/modules/dictionaries/migrations/Migration20260410171544.ts +49 -0
  679. package/src/modules/inbox_ops/api/proposals/[id]/route.ts +4 -1
  680. package/src/modules/query_index/lib/engine.ts +9 -1
  681. package/src/modules/sales/components/documents/AddressesSection.tsx +92 -42
  682. package/src/modules/sales/i18n/de.json +28 -0
  683. package/src/modules/sales/i18n/en.json +28 -0
  684. package/src/modules/sales/i18n/es.json +28 -0
  685. package/src/modules/sales/i18n/pl.json +28 -0
  686. package/src/modules/sales/lib/dictionaries.ts +18 -0
  687. package/src/modules/sales/widgets/injection-table.ts +4 -0
@@ -0,0 +1,26 @@
1
+ import { Migration } from "@mikro-orm/migrations";
2
+ class Migration20260411130944 extends Migration {
3
+ async up() {
4
+ this.addSql(`create table "customer_company_billing" ("id" uuid not null default gen_random_uuid(), "organization_id" uuid not null, "tenant_id" uuid not null, "entity_id" uuid not null, "bank_name" text null, "bank_account_masked" text null, "payment_terms" text null, "preferred_currency" text null, "created_at" timestamptz not null, "updated_at" timestamptz not null, constraint "customer_company_billing_pkey" primary key ("id"));`);
5
+ this.addSql(`create index "customer_company_billing_scope_idx" on "customer_company_billing" ("organization_id", "tenant_id");`);
6
+ this.addSql(`alter table "customer_company_billing" add constraint "customer_company_billing_entity_unique" unique ("entity_id");`);
7
+ this.addSql(`create table "customer_person_company_roles" ("id" uuid not null default gen_random_uuid(), "organization_id" uuid not null, "tenant_id" uuid not null, "person_entity_id" uuid not null, "company_entity_id" uuid not null, "role_value" text not null, "created_at" timestamptz not null, constraint "customer_person_company_roles_pkey" primary key ("id"));`);
8
+ this.addSql(`create index "customer_pcr_person_company_idx" on "customer_person_company_roles" ("person_entity_id", "company_entity_id");`);
9
+ this.addSql(`create index "customer_pcr_scope_idx" on "customer_person_company_roles" ("organization_id", "tenant_id");`);
10
+ this.addSql(`alter table "customer_person_company_roles" add constraint "customer_pcr_unique" unique ("person_entity_id", "company_entity_id", "role_value");`);
11
+ this.addSql(`alter table "customer_company_billing" add constraint "customer_company_billing_entity_id_foreign" foreign key ("entity_id") references "customer_entities" ("id") on update cascade;`);
12
+ this.addSql(`alter table "customer_person_company_roles" add constraint "customer_person_company_roles_person_entity_id_foreign" foreign key ("person_entity_id") references "customer_entities" ("id") on update cascade;`);
13
+ this.addSql(`alter table "customer_person_company_roles" add constraint "customer_person_company_roles_company_entity_id_foreign" foreign key ("company_entity_id") references "customer_entities" ("id") on update cascade;`);
14
+ }
15
+ async down() {
16
+ this.addSql(`alter table "customer_person_company_roles" drop constraint if exists "customer_person_company_roles_company_entity_id_foreign";`);
17
+ this.addSql(`alter table "customer_person_company_roles" drop constraint if exists "customer_person_company_roles_person_entity_id_foreign";`);
18
+ this.addSql(`alter table "customer_company_billing" drop constraint if exists "customer_company_billing_entity_id_foreign";`);
19
+ this.addSql(`drop table if exists "customer_person_company_roles";`);
20
+ this.addSql(`drop table if exists "customer_company_billing";`);
21
+ }
22
+ }
23
+ export {
24
+ Migration20260411130944
25
+ };
26
+ //# sourceMappingURL=Migration20260411130944.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/migrations/Migration20260411130944.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260411130944 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`create table \"customer_company_billing\" (\"id\" uuid not null default gen_random_uuid(), \"organization_id\" uuid not null, \"tenant_id\" uuid not null, \"entity_id\" uuid not null, \"bank_name\" text null, \"bank_account_masked\" text null, \"payment_terms\" text null, \"preferred_currency\" text null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, constraint \"customer_company_billing_pkey\" primary key (\"id\"));`);\n this.addSql(`create index \"customer_company_billing_scope_idx\" on \"customer_company_billing\" (\"organization_id\", \"tenant_id\");`);\n this.addSql(`alter table \"customer_company_billing\" add constraint \"customer_company_billing_entity_unique\" unique (\"entity_id\");`);\n\n this.addSql(`create table \"customer_person_company_roles\" (\"id\" uuid not null default gen_random_uuid(), \"organization_id\" uuid not null, \"tenant_id\" uuid not null, \"person_entity_id\" uuid not null, \"company_entity_id\" uuid not null, \"role_value\" text not null, \"created_at\" timestamptz not null, constraint \"customer_person_company_roles_pkey\" primary key (\"id\"));`);\n this.addSql(`create index \"customer_pcr_person_company_idx\" on \"customer_person_company_roles\" (\"person_entity_id\", \"company_entity_id\");`);\n this.addSql(`create index \"customer_pcr_scope_idx\" on \"customer_person_company_roles\" (\"organization_id\", \"tenant_id\");`);\n this.addSql(`alter table \"customer_person_company_roles\" add constraint \"customer_pcr_unique\" unique (\"person_entity_id\", \"company_entity_id\", \"role_value\");`);\n\n this.addSql(`alter table \"customer_company_billing\" add constraint \"customer_company_billing_entity_id_foreign\" foreign key (\"entity_id\") references \"customer_entities\" (\"id\") on update cascade;`);\n\n this.addSql(`alter table \"customer_person_company_roles\" add constraint \"customer_person_company_roles_person_entity_id_foreign\" foreign key (\"person_entity_id\") references \"customer_entities\" (\"id\") on update cascade;`);\n this.addSql(`alter table \"customer_person_company_roles\" add constraint \"customer_person_company_roles_company_entity_id_foreign\" foreign key (\"company_entity_id\") references \"customer_entities\" (\"id\") on update cascade;`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`alter table \"customer_person_company_roles\" drop constraint if exists \"customer_person_company_roles_company_entity_id_foreign\";`);\n this.addSql(`alter table \"customer_person_company_roles\" drop constraint if exists \"customer_person_company_roles_person_entity_id_foreign\";`);\n this.addSql(`alter table \"customer_company_billing\" drop constraint if exists \"customer_company_billing_entity_id_foreign\";`);\n\n this.addSql(`drop table if exists \"customer_person_company_roles\";`);\n this.addSql(`drop table if exists \"customer_company_billing\";`);\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,waAAwa;AACpb,SAAK,OAAO,mHAAmH;AAC/H,SAAK,OAAO,sHAAsH;AAElI,SAAK,OAAO,kWAAkW;AAC9W,SAAK,OAAO,8HAA8H;AAC1I,SAAK,OAAO,4GAA4G;AACxH,SAAK,OAAO,kJAAkJ;AAE9J,SAAK,OAAO,uLAAuL;AAEnM,SAAK,OAAO,+MAA+M;AAC3N,SAAK,OAAO,iNAAiN;AAAA,EAC/N;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,kIAAkI;AAC9I,SAAK,OAAO,iIAAiI;AAC7I,SAAK,OAAO,gHAAgH;AAE5H,SAAK,OAAO,uDAAuD;AACnE,SAAK,OAAO,kDAAkD;AAAA,EAChE;AAEF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,13 @@
1
+ import { Migration } from "@mikro-orm/migrations";
2
+ class Migration20260415095203 extends Migration {
3
+ async up() {
4
+ this.addSql(`alter table "customer_person_company_links" add column "deleted_at" timestamptz null;`);
5
+ }
6
+ async down() {
7
+ this.addSql(`alter table "customer_person_company_links" drop column "deleted_at";`);
8
+ }
9
+ }
10
+ export {
11
+ Migration20260415095203
12
+ };
13
+ //# sourceMappingURL=Migration20260415095203.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/migrations/Migration20260415095203.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260415095203 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`alter table \"customer_person_company_links\" add column \"deleted_at\" timestamptz null;`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`alter table \"customer_person_company_links\" drop column \"deleted_at\";`);\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,uFAAuF;AAAA,EACrG;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,uEAAuE;AAAA,EACrF;AAEF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,20 @@
1
+ import { Migration } from "@mikro-orm/migrations";
2
+ class Migration20260415135056 extends Migration {
3
+ async up() {
4
+ this.addSql(`create table "customer_deal_stage_transitions" ("id" uuid not null default gen_random_uuid(), "organization_id" uuid not null, "tenant_id" uuid not null, "pipeline_id" uuid not null, "stage_id" uuid not null, "stage_label" text not null, "stage_order" int not null, "transitioned_at" timestamptz not null, "transitioned_by_user_id" uuid null, "is_active" boolean not null default true, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, "deal_id" uuid not null, constraint "customer_deal_stage_transitions_pkey" primary key ("id"));`);
5
+ this.addSql(`create index "customer_deal_stage_transitions_org_tenant_idx" on "customer_deal_stage_transitions" ("organization_id", "tenant_id");`);
6
+ this.addSql(`create index "customer_deal_stage_transitions_deal_idx" on "customer_deal_stage_transitions" ("deal_id");`);
7
+ this.addSql(`alter table "customer_deal_stage_transitions" add constraint "customer_deal_stage_transitions_deal_stage_uq" unique ("deal_id", "stage_id");`);
8
+ this.addSql(`alter table "customer_deal_stage_transitions" add constraint "customer_deal_stage_transitions_deal_id_foreign" foreign key ("deal_id") references "customer_deals" ("id") on update cascade;`);
9
+ this.addSql(`create index "customer_deals_closure_stats_idx" on "customer_deals" ("organization_id", "tenant_id", "closure_outcome", "updated_at");`);
10
+ }
11
+ async down() {
12
+ this.addSql(`drop index "customer_deals_closure_stats_idx";`);
13
+ this.addSql(`alter table "customer_deal_stage_transitions" drop constraint "customer_deal_stage_transitions_deal_id_foreign";`);
14
+ this.addSql(`drop table if exists "customer_deal_stage_transitions" cascade;`);
15
+ }
16
+ }
17
+ export {
18
+ Migration20260415135056
19
+ };
20
+ //# sourceMappingURL=Migration20260415135056.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/migrations/Migration20260415135056.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260415135056 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`create table \"customer_deal_stage_transitions\" (\"id\" uuid not null default gen_random_uuid(), \"organization_id\" uuid not null, \"tenant_id\" uuid not null, \"pipeline_id\" uuid not null, \"stage_id\" uuid not null, \"stage_label\" text not null, \"stage_order\" int not null, \"transitioned_at\" timestamptz not null, \"transitioned_by_user_id\" uuid null, \"is_active\" boolean not null default true, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, \"deleted_at\" timestamptz null, \"deal_id\" uuid not null, constraint \"customer_deal_stage_transitions_pkey\" primary key (\"id\"));`);\n this.addSql(`create index \"customer_deal_stage_transitions_org_tenant_idx\" on \"customer_deal_stage_transitions\" (\"organization_id\", \"tenant_id\");`);\n this.addSql(`create index \"customer_deal_stage_transitions_deal_idx\" on \"customer_deal_stage_transitions\" (\"deal_id\");`);\n this.addSql(`alter table \"customer_deal_stage_transitions\" add constraint \"customer_deal_stage_transitions_deal_stage_uq\" unique (\"deal_id\", \"stage_id\");`);\n\n this.addSql(`alter table \"customer_deal_stage_transitions\" add constraint \"customer_deal_stage_transitions_deal_id_foreign\" foreign key (\"deal_id\") references \"customer_deals\" (\"id\") on update cascade;`);\n\n this.addSql(`create index \"customer_deals_closure_stats_idx\" on \"customer_deals\" (\"organization_id\", \"tenant_id\", \"closure_outcome\", \"updated_at\");`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`drop index \"customer_deals_closure_stats_idx\";`);\n this.addSql(`alter table \"customer_deal_stage_transitions\" drop constraint \"customer_deal_stage_transitions_deal_id_foreign\";`);\n this.addSql(`drop table if exists \"customer_deal_stage_transitions\" cascade;`);\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,wkBAAwkB;AACplB,SAAK,OAAO,sIAAsI;AAClJ,SAAK,OAAO,2GAA2G;AACvH,SAAK,OAAO,8IAA8I;AAE1J,SAAK,OAAO,8LAA8L;AAE1M,SAAK,OAAO,wIAAwI;AAAA,EACtJ;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,gDAAgD;AAC5D,SAAK,OAAO,kHAAkH;AAC9H,SAAK,OAAO,iEAAiE;AAAA,EAC/E;AAEF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ import { Migration } from "@mikro-orm/migrations";
2
+ class Migration20260417140000 extends Migration {
3
+ async up() {
4
+ this.addSql(`alter table "customer_person_company_links" drop constraint if exists "customer_person_company_links_unique";`);
5
+ this.addSql(`create unique index "customer_person_company_links_active_unique" on "customer_person_company_links" ("person_entity_id", "company_entity_id") where "deleted_at" is null;`);
6
+ }
7
+ async down() {
8
+ this.addSql(`drop index if exists "customer_person_company_links_active_unique";`);
9
+ this.addSql(`alter table "customer_person_company_links" add constraint "customer_person_company_links_unique" unique ("person_entity_id", "company_entity_id");`);
10
+ }
11
+ }
12
+ export {
13
+ Migration20260417140000
14
+ };
15
+ //# sourceMappingURL=Migration20260417140000.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/migrations/Migration20260417140000.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260417140000 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`alter table \"customer_person_company_links\" drop constraint if exists \"customer_person_company_links_unique\";`);\n this.addSql(`create unique index \"customer_person_company_links_active_unique\" on \"customer_person_company_links\" (\"person_entity_id\", \"company_entity_id\") where \"deleted_at\" is null;`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`drop index if exists \"customer_person_company_links_active_unique\";`);\n this.addSql(`alter table \"customer_person_company_links\" add constraint \"customer_person_company_links_unique\" unique (\"person_entity_id\", \"company_entity_id\");`);\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,+GAA+G;AAC3H,SAAK,OAAO,4KAA4K;AAAA,EAC1L;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,qEAAqE;AACjF,SAAK,OAAO,qJAAqJ;AAAA,EACnK;AAEF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,17 @@
1
+ import { Migration } from "@mikro-orm/migrations";
2
+ class Migration20260417160000 extends Migration {
3
+ async up() {
4
+ this.addSql(`alter table "customer_entity_roles" add column "deleted_at" timestamptz null;`);
5
+ this.addSql(`alter table "customer_entity_roles" drop constraint if exists "customer_entity_roles_unique";`);
6
+ this.addSql(`create unique index "customer_entity_roles_active_unique" on "customer_entity_roles" ("entity_type", "entity_id", "role_type") where "deleted_at" is null;`);
7
+ }
8
+ async down() {
9
+ this.addSql(`drop index if exists "customer_entity_roles_active_unique";`);
10
+ this.addSql(`alter table "customer_entity_roles" add constraint "customer_entity_roles_unique" unique ("entity_type", "entity_id", "role_type");`);
11
+ this.addSql(`alter table "customer_entity_roles" drop column "deleted_at";`);
12
+ }
13
+ }
14
+ export {
15
+ Migration20260417160000
16
+ };
17
+ //# sourceMappingURL=Migration20260417160000.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/migrations/Migration20260417160000.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260417160000 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`alter table \"customer_entity_roles\" add column \"deleted_at\" timestamptz null;`);\n this.addSql(`alter table \"customer_entity_roles\" drop constraint if exists \"customer_entity_roles_unique\";`);\n this.addSql(`create unique index \"customer_entity_roles_active_unique\" on \"customer_entity_roles\" (\"entity_type\", \"entity_id\", \"role_type\") where \"deleted_at\" is null;`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`drop index if exists \"customer_entity_roles_active_unique\";`);\n this.addSql(`alter table \"customer_entity_roles\" add constraint \"customer_entity_roles_unique\" unique (\"entity_type\", \"entity_id\", \"role_type\");`);\n this.addSql(`alter table \"customer_entity_roles\" drop column \"deleted_at\";`);\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,+EAA+E;AAC3F,SAAK,OAAO,+FAA+F;AAC3G,SAAK,OAAO,4JAA4J;AAAA,EAC1K;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,6DAA6D;AACzE,SAAK,OAAO,qIAAqI;AACjJ,SAAK,OAAO,+DAA+D;AAAA,EAC7E;AAEF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,13 @@
1
+ import { Migration } from "@mikro-orm/migrations";
2
+ class Migration20260417235407 extends Migration {
3
+ async up() {
4
+ this.addSql(`alter table "customer_interactions" add column "linked_entities" jsonb null, add column "guest_permissions" jsonb null;`);
5
+ }
6
+ async down() {
7
+ this.addSql(`alter table "customer_interactions" drop column "linked_entities", drop column "guest_permissions";`);
8
+ }
9
+ }
10
+ export {
11
+ Migration20260417235407
12
+ };
13
+ //# sourceMappingURL=Migration20260417235407.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/migrations/Migration20260417235407.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260417235407 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`alter table \"customer_interactions\" add column \"linked_entities\" jsonb null, add column \"guest_permissions\" jsonb null;`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`alter table \"customer_interactions\" drop column \"linked_entities\", drop column \"guest_permissions\";`);\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,yHAAyH;AAAA,EACvI;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,qGAAqG;AAAA,EACnH;AAEF;",
6
+ "names": []
7
+ }
@@ -6,6 +6,8 @@ import {
6
6
  seedCustomerExamples,
7
7
  seedDefaultPipeline
8
8
  } from "./cli.js";
9
+ import { ensureDictionaryEntry } from "./commands/shared.js";
10
+ import { DEFAULT_CUSTOMER_ROLE_TYPES } from "./lib/customerRoleTypes.js";
9
11
  const interactionFeatureToggles = [
10
12
  {
11
13
  identifier: "customers.interactions.unified",
@@ -56,6 +58,17 @@ const setup = {
56
58
  await seedDefaultPipeline(ctx.em, scope);
57
59
  await ensureCustomerCustomFieldDefinitions(ctx.em, ctx.tenantId);
58
60
  await seedInteractionFeatureToggles(ctx.em);
61
+ for (const entry of DEFAULT_CUSTOMER_ROLE_TYPES) {
62
+ await ensureDictionaryEntry(ctx.em, {
63
+ tenantId: ctx.tenantId,
64
+ organizationId: ctx.organizationId,
65
+ kind: "customer_role_type",
66
+ value: entry.value,
67
+ label: entry.label,
68
+ color: entry.color,
69
+ icon: entry.icon
70
+ });
71
+ }
59
72
  },
60
73
  seedExamples: async (ctx) => {
61
74
  const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId };
@@ -79,7 +92,9 @@ const setup = {
79
92
  "customers.widgets.todos",
80
93
  "customers.widgets.next-interactions",
81
94
  "customers.widgets.new-customers",
82
- "customers.widgets.new-deals"
95
+ "customers.widgets.new-deals",
96
+ "customers.roles.view",
97
+ "customers.roles.manage"
83
98
  ]
84
99
  }
85
100
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/customers/setup.ts"],
4
- "sourcesContent": ["import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { FeatureToggle } from '@open-mercato/core/modules/feature_toggles/data/entities'\nimport {\n ensureCustomerCustomFieldDefinitions,\n seedCustomerDictionaries,\n seedCurrencyDictionary,\n seedCustomerExamples,\n seedDefaultPipeline,\n} from './cli'\n\nconst interactionFeatureToggles = [\n {\n identifier: 'customers.interactions.unified',\n name: 'Unified Interactions',\n description: 'When enabled, interactions use the unified canonical model instead of per-entity activity tracking.',\n category: 'customers',\n type: 'boolean' as const,\n defaultValue: false,\n },\n {\n identifier: 'customers.interactions.legacy-adapters',\n name: 'Interaction Legacy Adapters',\n description: 'When enabled, legacy activity/todo APIs are bridged to the canonical interaction model.',\n category: 'customers',\n type: 'boolean' as const,\n defaultValue: true,\n },\n {\n identifier: 'customers.interactions.external-sync',\n name: 'Interaction External Sync',\n description: 'When enabled, interactions can be synced from external systems (calendars, email providers).',\n category: 'customers',\n type: 'boolean' as const,\n defaultValue: false,\n },\n]\n\nasync function seedInteractionFeatureToggles(em: EntityManager): Promise<void> {\n for (const toggle of interactionFeatureToggles) {\n const existing = await em.findOne(FeatureToggle, { identifier: toggle.identifier, deletedAt: null })\n if (existing) continue\n const entity = em.create(FeatureToggle, {\n identifier: toggle.identifier,\n name: toggle.name,\n description: toggle.description,\n category: toggle.category,\n type: toggle.type,\n defaultValue: toggle.defaultValue,\n })\n em.persist(entity)\n }\n await em.flush()\n}\n\nexport const setup: ModuleSetupConfig = {\n seedDefaults: async (ctx) => {\n const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n await seedCustomerDictionaries(ctx.em, scope)\n await seedCurrencyDictionary(ctx.em, scope)\n await seedDefaultPipeline(ctx.em, scope)\n await ensureCustomerCustomFieldDefinitions(ctx.em, ctx.tenantId)\n await seedInteractionFeatureToggles(ctx.em)\n },\n\n seedExamples: async (ctx) => {\n const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n await seedCustomerExamples(ctx.em, ctx.container, scope)\n },\n\n defaultRoleFeatures: {\n admin: [\n 'customers.*',\n ],\n employee: [\n 'customers.people.view',\n 'customers.people.manage',\n 'customers.companies.view',\n 'customers.companies.manage',\n 'customers.deals.view',\n 'customers.deals.manage',\n 'customers.activities.view',\n 'customers.activities.manage',\n 'customers.pipelines.view',\n 'customers.interactions.view',\n 'customers.widgets.todos',\n 'customers.widgets.next-interactions',\n 'customers.widgets.new-customers',\n 'customers.widgets.new-deals',\n ],\n },\n}\n\nexport default setup\n"],
5
- "mappings": "AAEA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,4BAA4B;AAAA,EAChC;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA,EACA;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA,EACA;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AACF;AAEA,eAAe,8BAA8B,IAAkC;AAC7E,aAAW,UAAU,2BAA2B;AAC9C,UAAM,WAAW,MAAM,GAAG,QAAQ,eAAe,EAAE,YAAY,OAAO,YAAY,WAAW,KAAK,CAAC;AACnG,QAAI,SAAU;AACd,UAAM,SAAS,GAAG,OAAO,eAAe;AAAA,MACtC,YAAY,OAAO;AAAA,MACnB,MAAM,OAAO;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,cAAc,OAAO;AAAA,IACvB,CAAC;AACD,OAAG,QAAQ,MAAM;AAAA,EACnB;AACA,QAAM,GAAG,MAAM;AACjB;AAEO,MAAM,QAA2B;AAAA,EACtC,cAAc,OAAO,QAAQ;AAC3B,UAAM,QAAQ,EAAE,UAAU,IAAI,UAAU,gBAAgB,IAAI,eAAe;AAC3E,UAAM,yBAAyB,IAAI,IAAI,KAAK;AAC5C,UAAM,uBAAuB,IAAI,IAAI,KAAK;AAC1C,UAAM,oBAAoB,IAAI,IAAI,KAAK;AACvC,UAAM,qCAAqC,IAAI,IAAI,IAAI,QAAQ;AAC/D,UAAM,8BAA8B,IAAI,EAAE;AAAA,EAC5C;AAAA,EAEA,cAAc,OAAO,QAAQ;AAC3B,UAAM,QAAQ,EAAE,UAAU,IAAI,UAAU,gBAAgB,IAAI,eAAe;AAC3E,UAAM,qBAAqB,IAAI,IAAI,IAAI,WAAW,KAAK;AAAA,EACzD;AAAA,EAEA,qBAAqB;AAAA,IACnB,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;",
4
+ "sourcesContent": ["import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { FeatureToggle } from '@open-mercato/core/modules/feature_toggles/data/entities'\nimport {\n ensureCustomerCustomFieldDefinitions,\n seedCustomerDictionaries,\n seedCurrencyDictionary,\n seedCustomerExamples,\n seedDefaultPipeline,\n} from './cli'\nimport { ensureDictionaryEntry } from './commands/shared'\nimport { DEFAULT_CUSTOMER_ROLE_TYPES } from './lib/customerRoleTypes'\n\nconst interactionFeatureToggles = [\n {\n identifier: 'customers.interactions.unified',\n name: 'Unified Interactions',\n description: 'When enabled, interactions use the unified canonical model instead of per-entity activity tracking.',\n category: 'customers',\n type: 'boolean' as const,\n defaultValue: false,\n },\n {\n identifier: 'customers.interactions.legacy-adapters',\n name: 'Interaction Legacy Adapters',\n description: 'When enabled, legacy activity/todo APIs are bridged to the canonical interaction model.',\n category: 'customers',\n type: 'boolean' as const,\n defaultValue: true,\n },\n {\n identifier: 'customers.interactions.external-sync',\n name: 'Interaction External Sync',\n description: 'When enabled, interactions can be synced from external systems (calendars, email providers).',\n category: 'customers',\n type: 'boolean' as const,\n defaultValue: false,\n },\n]\n\nasync function seedInteractionFeatureToggles(em: EntityManager): Promise<void> {\n for (const toggle of interactionFeatureToggles) {\n const existing = await em.findOne(FeatureToggle, { identifier: toggle.identifier, deletedAt: null })\n if (existing) continue\n const entity = em.create(FeatureToggle, {\n identifier: toggle.identifier,\n name: toggle.name,\n description: toggle.description,\n category: toggle.category,\n type: toggle.type,\n defaultValue: toggle.defaultValue,\n })\n em.persist(entity)\n }\n await em.flush()\n}\n\nexport const setup: ModuleSetupConfig = {\n seedDefaults: async (ctx) => {\n const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n await seedCustomerDictionaries(ctx.em, scope)\n await seedCurrencyDictionary(ctx.em, scope)\n await seedDefaultPipeline(ctx.em, scope)\n await ensureCustomerCustomFieldDefinitions(ctx.em, ctx.tenantId)\n await seedInteractionFeatureToggles(ctx.em)\n for (const entry of DEFAULT_CUSTOMER_ROLE_TYPES) {\n await ensureDictionaryEntry(ctx.em, {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId,\n kind: 'customer_role_type',\n value: entry.value,\n label: entry.label,\n color: entry.color,\n icon: entry.icon,\n })\n }\n },\n\n seedExamples: async (ctx) => {\n const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n await seedCustomerExamples(ctx.em, ctx.container, scope)\n },\n\n defaultRoleFeatures: {\n admin: [\n 'customers.*',\n ],\n employee: [\n 'customers.people.view',\n 'customers.people.manage',\n 'customers.companies.view',\n 'customers.companies.manage',\n 'customers.deals.view',\n 'customers.deals.manage',\n 'customers.activities.view',\n 'customers.activities.manage',\n 'customers.pipelines.view',\n 'customers.interactions.view',\n 'customers.widgets.todos',\n 'customers.widgets.next-interactions',\n 'customers.widgets.new-customers',\n 'customers.widgets.new-deals',\n 'customers.roles.view',\n 'customers.roles.manage',\n ],\n },\n}\n\nexport default setup\n"],
5
+ "mappings": "AAEA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAE5C,MAAM,4BAA4B;AAAA,EAChC;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA,EACA;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA,EACA;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AACF;AAEA,eAAe,8BAA8B,IAAkC;AAC7E,aAAW,UAAU,2BAA2B;AAC9C,UAAM,WAAW,MAAM,GAAG,QAAQ,eAAe,EAAE,YAAY,OAAO,YAAY,WAAW,KAAK,CAAC;AACnG,QAAI,SAAU;AACd,UAAM,SAAS,GAAG,OAAO,eAAe;AAAA,MACtC,YAAY,OAAO;AAAA,MACnB,MAAM,OAAO;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,cAAc,OAAO;AAAA,IACvB,CAAC;AACD,OAAG,QAAQ,MAAM;AAAA,EACnB;AACA,QAAM,GAAG,MAAM;AACjB;AAEO,MAAM,QAA2B;AAAA,EACtC,cAAc,OAAO,QAAQ;AAC3B,UAAM,QAAQ,EAAE,UAAU,IAAI,UAAU,gBAAgB,IAAI,eAAe;AAC3E,UAAM,yBAAyB,IAAI,IAAI,KAAK;AAC5C,UAAM,uBAAuB,IAAI,IAAI,KAAK;AAC1C,UAAM,oBAAoB,IAAI,IAAI,KAAK;AACvC,UAAM,qCAAqC,IAAI,IAAI,IAAI,QAAQ;AAC/D,UAAM,8BAA8B,IAAI,EAAE;AAC1C,eAAW,SAAS,6BAA6B;AAC/C,YAAM,sBAAsB,IAAI,IAAI;AAAA,QAClC,UAAU,IAAI;AAAA,QACd,gBAAgB,IAAI;AAAA,QACpB,MAAM;AAAA,QACN,OAAO,MAAM;AAAA,QACb,OAAO,MAAM;AAAA,QACb,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,cAAc,OAAO,QAAQ;AAC3B,UAAM,QAAQ,EAAE,UAAU,IAAI,UAAU,gBAAgB,IAAI,eAAe;AAC3E,UAAM,qBAAqB,IAAI,IAAI,IAAI,WAAW,KAAK;AAAA,EACzD;AAAA,EAEA,qBAAqB;AAAA,IACnB,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,16 @@
1
+ import {
2
+ deliverDealClosureNotification
3
+ } from "../lib/dealClosureNotification.js";
4
+ const metadata = {
5
+ event: "customers.deal.won",
6
+ persistent: true,
7
+ id: "customers:deal-won-notification"
8
+ };
9
+ async function handleDealWon(payload, ctx) {
10
+ await deliverDealClosureNotification(payload, ctx, "customers.deal.won");
11
+ }
12
+ export {
13
+ handleDealWon as default,
14
+ metadata
15
+ };
16
+ //# sourceMappingURL=deal-closure-notification.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/subscribers/deal-closure-notification.ts"],
4
+ "sourcesContent": ["import {\n deliverDealClosureNotification,\n type DealClosurePayload,\n} from '../lib/dealClosureNotification'\n\nexport const metadata = {\n event: 'customers.deal.won',\n persistent: true,\n id: 'customers:deal-won-notification',\n}\n\ntype ResolverContext = {\n resolve: <T = unknown>(name: string) => T\n container?: { resolve<T = unknown>(name: string): T }\n}\n\nexport default async function handleDealWon(\n payload: DealClosurePayload,\n ctx: ResolverContext,\n): Promise<void> {\n await deliverDealClosureNotification(payload, ctx, 'customers.deal.won')\n}\n"],
5
+ "mappings": "AAAA;AAAA,EACE;AAAA,OAEK;AAEA,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAOA,eAAO,cACL,SACA,KACe;AACf,QAAM,+BAA+B,SAAS,KAAK,oBAAoB;AACzE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,16 @@
1
+ import {
2
+ deliverDealClosureNotification
3
+ } from "../lib/dealClosureNotification.js";
4
+ const metadata = {
5
+ event: "customers.deal.lost",
6
+ persistent: true,
7
+ id: "customers:deal-lost-notification"
8
+ };
9
+ async function handleDealLost(payload, ctx) {
10
+ await deliverDealClosureNotification(payload, ctx, "customers.deal.lost");
11
+ }
12
+ export {
13
+ handleDealLost as default,
14
+ metadata
15
+ };
16
+ //# sourceMappingURL=deal-lost-notification.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customers/subscribers/deal-lost-notification.ts"],
4
+ "sourcesContent": ["import {\n deliverDealClosureNotification,\n type DealClosurePayload,\n} from '../lib/dealClosureNotification'\n\nexport const metadata = {\n event: 'customers.deal.lost',\n persistent: true,\n id: 'customers:deal-lost-notification',\n}\n\ntype ResolverContext = {\n resolve: <T = unknown>(name: string) => T\n container?: { resolve<T = unknown>(name: string): T }\n}\n\nexport default async function handleDealLost(\n payload: DealClosurePayload,\n ctx: ResolverContext,\n): Promise<void> {\n await deliverDealClosureNotification(payload, ctx, 'customers.deal.lost')\n}\n"],
5
+ "mappings": "AAAA;AAAA,EACE;AAAA,OAEK;AAEA,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAOA,eAAO,eACL,SACA,KACe;AACf,QAAM,+BAA+B,SAAS,KAAK,qBAAqB;AAC1E;",
6
+ "names": []
7
+ }
@@ -90,6 +90,8 @@ async function PATCH(req, ctx) {
90
90
  label: updated.label,
91
91
  color: updated.color,
92
92
  icon: updated.icon,
93
+ position: updated.position ?? 0,
94
+ isDefault: updated.isDefault ?? false,
93
95
  createdAt: updated.createdAt,
94
96
  updatedAt: updated.updatedAt
95
97
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/dictionaries/api/%5BdictionaryId%5D/entries/%5BentryId%5D/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { Dictionary, DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'\nimport { resolveDictionariesRouteContext } from '@open-mercato/core/modules/dictionaries/api/context'\nimport { updateDictionaryEntrySchema } from '@open-mercato/core/modules/dictionaries/data/validators'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { serializeOperationMetadata } from '@open-mercato/shared/lib/commands/operationMetadata'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n dictionaryEntryParamsSchema,\n dictionaryEntryResponseSchema,\n dictionariesErrorSchema,\n dictionariesOkSchema,\n dictionariesTag,\n updateDictionaryEntrySchema as updateEntryDocSchema,\n} from '../../../openapi'\nconst paramsSchema = z.object({\n dictionaryId: z.string().uuid(),\n entryId: z.string().uuid(),\n})\n\nasync function loadDictionary(context: Awaited<ReturnType<typeof resolveDictionariesRouteContext>>, id: string) {\n if (!context.organizationId) {\n throw new CrudHttpError(400, { error: context.translate('dictionaries.errors.organization_required', 'Organization context is required') })\n }\n const dictionary = await context.em.findOne(Dictionary, {\n id,\n organizationId: context.organizationId,\n tenantId: context.tenantId,\n deletedAt: null,\n })\n if (!dictionary) {\n throw new CrudHttpError(404, { error: context.translate('dictionaries.errors.not_found', 'Dictionary not found') })\n }\n return dictionary\n}\n\nasync function loadEntry(\n context: Awaited<ReturnType<typeof resolveDictionariesRouteContext>>,\n dictionary: Dictionary,\n entryId: string,\n) {\n const entry = await context.em.findOne(DictionaryEntry, {\n id: entryId,\n dictionary,\n organizationId: dictionary.organizationId,\n tenantId: context.tenantId,\n })\n if (!entry) {\n throw new CrudHttpError(404, { error: context.translate('dictionaries.errors.entry_not_found', 'Dictionary entry not found') })\n }\n return entry\n}\n\nexport const metadata = {\n PATCH: { requireAuth: true, requireFeatures: ['dictionaries.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['dictionaries.manage'] },\n}\n\nexport async function PATCH(req: Request, ctx: { params?: { dictionaryId?: string; entryId?: string } }) {\n try {\n const context = await resolveDictionariesRouteContext(req)\n if (!context.auth) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const { dictionaryId, entryId } = paramsSchema.parse({\n dictionaryId: ctx.params?.dictionaryId,\n entryId: ctx.params?.entryId,\n })\n const dictionary = await loadDictionary(context, dictionaryId)\n await loadEntry(context, dictionary, entryId)\n const rawBody = await req.json().catch(() => ({}))\n const payload = updateDictionaryEntrySchema.parse(rawBody)\n // These nested routes don't use the CRUD factory, so invoke the command bus explicitly.\n const commandBus = (context.container.resolve('commandBus') as CommandBus)\n const input = { ...(payload as Record<string, unknown>), id: entryId }\n const { result, logEntry } = await commandBus.execute('dictionaries.entries.update', {\n input,\n ctx: context.ctx,\n })\n const updateResult = (result ?? {}) as { entryId?: string | null }\n const updatedEntryId = typeof updateResult.entryId === 'string' ? updateResult.entryId : null\n if (!updatedEntryId) {\n throw new CrudHttpError(500, { error: context.translate('dictionaries.errors.entry_update_failed', 'Failed to update dictionary entry') })\n }\n const updated = await findOneWithDecryption(\n context.em.fork(),\n DictionaryEntry,\n updatedEntryId,\n { populate: ['dictionary'] },\n { tenantId: context.auth.tenantId ?? null, organizationId: context.auth.orgId ?? null },\n )\n if (!updated) {\n throw new CrudHttpError(500, { error: context.translate('dictionaries.errors.entry_update_failed', 'Failed to update dictionary entry') })\n }\n const response = NextResponse.json({\n id: updated.id,\n value: updated.value,\n label: updated.label,\n color: updated.color,\n icon: updated.icon,\n createdAt: updated.createdAt,\n updatedAt: updated.updatedAt,\n })\n if (logEntry?.undoToken && logEntry?.id && logEntry?.commandId) {\n response.headers.set(\n 'x-om-operation',\n serializeOperationMetadata({\n id: logEntry.id,\n undoToken: logEntry.undoToken,\n commandId: logEntry.commandId,\n actionLabel: logEntry.actionLabel ?? null,\n resourceKind: logEntry.resourceKind ?? 'dictionaries.entry',\n resourceId: updatedEntryId,\n executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : undefined,\n })\n )\n }\n return response\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('[dictionaries/:id/entries/:entryId.PATCH] Unexpected error', err)\n return NextResponse.json({ error: 'Failed to update dictionary entry' }, { status: 500 })\n }\n}\n\nexport async function DELETE(req: Request, ctx: { params?: { dictionaryId?: string; entryId?: string } }) {\n try {\n const context = await resolveDictionariesRouteContext(req)\n const { dictionaryId, entryId } = paramsSchema.parse({\n dictionaryId: ctx.params?.dictionaryId,\n entryId: ctx.params?.entryId,\n })\n const dictionary = await loadDictionary(context, dictionaryId)\n const entry = await loadEntry(context, dictionary, entryId)\n const commandBus = (context.container.resolve('commandBus') as CommandBus)\n const { logEntry } = await commandBus.execute('dictionaries.entries.delete', {\n input: { body: { id: entry.id } },\n ctx: context.ctx,\n })\n const response = NextResponse.json({ ok: true })\n if (logEntry?.undoToken && logEntry?.id && logEntry?.commandId) {\n response.headers.set(\n 'x-om-operation',\n serializeOperationMetadata({\n id: logEntry.id,\n undoToken: logEntry.undoToken,\n commandId: logEntry.commandId,\n actionLabel: logEntry.actionLabel ?? null,\n resourceKind: logEntry.resourceKind ?? 'dictionaries.entry',\n resourceId: entry.id,\n executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : undefined,\n })\n )\n }\n return response\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('[dictionaries/:id/entries/:entryId.DELETE] Unexpected error', err)\n return NextResponse.json({ error: 'Failed to delete dictionary entry' }, { status: 500 })\n }\n}\n\nconst dictionaryEntryPatchDoc: OpenApiMethodDoc = {\n summary: 'Update dictionary entry',\n description: 'Updates the specified dictionary entry using the command bus pipeline.',\n tags: [dictionariesTag],\n requestBody: {\n contentType: 'application/json',\n schema: updateEntryDocSchema,\n description: 'Fields to update on the dictionary entry.',\n },\n responses: [\n { status: 200, description: 'Dictionary entry updated.', schema: dictionaryEntryResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: dictionariesErrorSchema },\n { status: 401, description: 'Authentication required', schema: dictionariesErrorSchema },\n { status: 404, description: 'Dictionary or entry not found', schema: dictionariesErrorSchema },\n { status: 500, description: 'Failed to update entry', schema: dictionariesErrorSchema },\n ],\n}\n\nconst dictionaryEntryDeleteDoc: OpenApiMethodDoc = {\n summary: 'Delete dictionary entry',\n description: 'Deletes the specified dictionary entry via the command bus.',\n tags: [dictionariesTag],\n responses: [\n { status: 200, description: 'Entry deleted.', schema: dictionariesOkSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: dictionariesErrorSchema },\n { status: 401, description: 'Authentication required', schema: dictionariesErrorSchema },\n { status: 404, description: 'Dictionary or entry not found', schema: dictionariesErrorSchema },\n { status: 500, description: 'Failed to delete entry', schema: dictionariesErrorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: dictionariesTag,\n summary: 'Dictionary entry resource',\n pathParams: dictionaryEntryParamsSchema,\n methods: {\n PATCH: dictionaryEntryPatchDoc,\n DELETE: dictionaryEntryDeleteDoc,\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { Dictionary, DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'\nimport { resolveDictionariesRouteContext } from '@open-mercato/core/modules/dictionaries/api/context'\nimport { updateDictionaryEntrySchema } from '@open-mercato/core/modules/dictionaries/data/validators'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { serializeOperationMetadata } from '@open-mercato/shared/lib/commands/operationMetadata'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n dictionaryEntryParamsSchema,\n dictionaryEntryResponseSchema,\n dictionariesErrorSchema,\n dictionariesOkSchema,\n dictionariesTag,\n updateDictionaryEntrySchema as updateEntryDocSchema,\n} from '../../../openapi'\nconst paramsSchema = z.object({\n dictionaryId: z.string().uuid(),\n entryId: z.string().uuid(),\n})\n\nasync function loadDictionary(context: Awaited<ReturnType<typeof resolveDictionariesRouteContext>>, id: string) {\n if (!context.organizationId) {\n throw new CrudHttpError(400, { error: context.translate('dictionaries.errors.organization_required', 'Organization context is required') })\n }\n const dictionary = await context.em.findOne(Dictionary, {\n id,\n organizationId: context.organizationId,\n tenantId: context.tenantId,\n deletedAt: null,\n })\n if (!dictionary) {\n throw new CrudHttpError(404, { error: context.translate('dictionaries.errors.not_found', 'Dictionary not found') })\n }\n return dictionary\n}\n\nasync function loadEntry(\n context: Awaited<ReturnType<typeof resolveDictionariesRouteContext>>,\n dictionary: Dictionary,\n entryId: string,\n) {\n const entry = await context.em.findOne(DictionaryEntry, {\n id: entryId,\n dictionary,\n organizationId: dictionary.organizationId,\n tenantId: context.tenantId,\n })\n if (!entry) {\n throw new CrudHttpError(404, { error: context.translate('dictionaries.errors.entry_not_found', 'Dictionary entry not found') })\n }\n return entry\n}\n\nexport const metadata = {\n PATCH: { requireAuth: true, requireFeatures: ['dictionaries.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['dictionaries.manage'] },\n}\n\nexport async function PATCH(req: Request, ctx: { params?: { dictionaryId?: string; entryId?: string } }) {\n try {\n const context = await resolveDictionariesRouteContext(req)\n if (!context.auth) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const { dictionaryId, entryId } = paramsSchema.parse({\n dictionaryId: ctx.params?.dictionaryId,\n entryId: ctx.params?.entryId,\n })\n const dictionary = await loadDictionary(context, dictionaryId)\n await loadEntry(context, dictionary, entryId)\n const rawBody = await req.json().catch(() => ({}))\n const payload = updateDictionaryEntrySchema.parse(rawBody)\n // These nested routes don't use the CRUD factory, so invoke the command bus explicitly.\n const commandBus = (context.container.resolve('commandBus') as CommandBus)\n const input = { ...(payload as Record<string, unknown>), id: entryId }\n const { result, logEntry } = await commandBus.execute('dictionaries.entries.update', {\n input,\n ctx: context.ctx,\n })\n const updateResult = (result ?? {}) as { entryId?: string | null }\n const updatedEntryId = typeof updateResult.entryId === 'string' ? updateResult.entryId : null\n if (!updatedEntryId) {\n throw new CrudHttpError(500, { error: context.translate('dictionaries.errors.entry_update_failed', 'Failed to update dictionary entry') })\n }\n const updated = await findOneWithDecryption(\n context.em.fork(),\n DictionaryEntry,\n updatedEntryId,\n { populate: ['dictionary'] },\n { tenantId: context.auth.tenantId ?? null, organizationId: context.auth.orgId ?? null },\n )\n if (!updated) {\n throw new CrudHttpError(500, { error: context.translate('dictionaries.errors.entry_update_failed', 'Failed to update dictionary entry') })\n }\n const response = NextResponse.json({\n id: updated.id,\n value: updated.value,\n label: updated.label,\n color: updated.color,\n icon: updated.icon,\n position: updated.position ?? 0,\n isDefault: updated.isDefault ?? false,\n createdAt: updated.createdAt,\n updatedAt: updated.updatedAt,\n })\n if (logEntry?.undoToken && logEntry?.id && logEntry?.commandId) {\n response.headers.set(\n 'x-om-operation',\n serializeOperationMetadata({\n id: logEntry.id,\n undoToken: logEntry.undoToken,\n commandId: logEntry.commandId,\n actionLabel: logEntry.actionLabel ?? null,\n resourceKind: logEntry.resourceKind ?? 'dictionaries.entry',\n resourceId: updatedEntryId,\n executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : undefined,\n })\n )\n }\n return response\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('[dictionaries/:id/entries/:entryId.PATCH] Unexpected error', err)\n return NextResponse.json({ error: 'Failed to update dictionary entry' }, { status: 500 })\n }\n}\n\nexport async function DELETE(req: Request, ctx: { params?: { dictionaryId?: string; entryId?: string } }) {\n try {\n const context = await resolveDictionariesRouteContext(req)\n const { dictionaryId, entryId } = paramsSchema.parse({\n dictionaryId: ctx.params?.dictionaryId,\n entryId: ctx.params?.entryId,\n })\n const dictionary = await loadDictionary(context, dictionaryId)\n const entry = await loadEntry(context, dictionary, entryId)\n const commandBus = (context.container.resolve('commandBus') as CommandBus)\n const { logEntry } = await commandBus.execute('dictionaries.entries.delete', {\n input: { body: { id: entry.id } },\n ctx: context.ctx,\n })\n const response = NextResponse.json({ ok: true })\n if (logEntry?.undoToken && logEntry?.id && logEntry?.commandId) {\n response.headers.set(\n 'x-om-operation',\n serializeOperationMetadata({\n id: logEntry.id,\n undoToken: logEntry.undoToken,\n commandId: logEntry.commandId,\n actionLabel: logEntry.actionLabel ?? null,\n resourceKind: logEntry.resourceKind ?? 'dictionaries.entry',\n resourceId: entry.id,\n executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : undefined,\n })\n )\n }\n return response\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('[dictionaries/:id/entries/:entryId.DELETE] Unexpected error', err)\n return NextResponse.json({ error: 'Failed to delete dictionary entry' }, { status: 500 })\n }\n}\n\nconst dictionaryEntryPatchDoc: OpenApiMethodDoc = {\n summary: 'Update dictionary entry',\n description: 'Updates the specified dictionary entry using the command bus pipeline.',\n tags: [dictionariesTag],\n requestBody: {\n contentType: 'application/json',\n schema: updateEntryDocSchema,\n description: 'Fields to update on the dictionary entry.',\n },\n responses: [\n { status: 200, description: 'Dictionary entry updated.', schema: dictionaryEntryResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: dictionariesErrorSchema },\n { status: 401, description: 'Authentication required', schema: dictionariesErrorSchema },\n { status: 404, description: 'Dictionary or entry not found', schema: dictionariesErrorSchema },\n { status: 500, description: 'Failed to update entry', schema: dictionariesErrorSchema },\n ],\n}\n\nconst dictionaryEntryDeleteDoc: OpenApiMethodDoc = {\n summary: 'Delete dictionary entry',\n description: 'Deletes the specified dictionary entry via the command bus.',\n tags: [dictionariesTag],\n responses: [\n { status: 200, description: 'Entry deleted.', schema: dictionariesOkSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: dictionariesErrorSchema },\n { status: 401, description: 'Authentication required', schema: dictionariesErrorSchema },\n { status: 404, description: 'Dictionary or entry not found', schema: dictionariesErrorSchema },\n { status: 500, description: 'Failed to delete entry', schema: dictionariesErrorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: dictionariesTag,\n summary: 'Dictionary entry resource',\n pathParams: dictionaryEntryParamsSchema,\n methods: {\n PATCH: dictionaryEntryPatchDoc,\n DELETE: dictionaryEntryDeleteDoc,\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,154 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { Dictionary } from "@open-mercato/core/modules/dictionaries/data/entities";
4
+ import { resolveDictionariesRouteContext } from "@open-mercato/core/modules/dictionaries/api/context";
5
+ import {
6
+ reorderDictionaryEntriesCommandSchema,
7
+ reorderDictionaryEntriesSchema
8
+ } from "@open-mercato/core/modules/dictionaries/data/validators";
9
+ import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
10
+ import { serializeOperationMetadata } from "@open-mercato/shared/lib/commands/operationMetadata";
11
+ import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
12
+ import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
13
+ import {
14
+ runCrudMutationGuardAfterSuccess,
15
+ validateCrudMutationGuard
16
+ } from "@open-mercato/shared/lib/crud/mutation-guard";
17
+ import {
18
+ dictionaryIdParamsSchema,
19
+ dictionariesErrorSchema,
20
+ dictionariesOkSchema,
21
+ dictionariesTag,
22
+ reorderEntriesRequestSchema
23
+ } from "../../../openapi.js";
24
+ import { resolveDictionaryActorId } from "../../../context.js";
25
+ const paramsSchema = z.object({ dictionaryId: z.string().uuid() });
26
+ const metadata = {
27
+ POST: { requireAuth: true, requireFeatures: ["dictionaries.manage"] }
28
+ };
29
+ async function POST(req, ctx) {
30
+ try {
31
+ const context = await resolveDictionariesRouteContext(req);
32
+ if (!context.auth) {
33
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
34
+ }
35
+ const { dictionaryId } = paramsSchema.parse({ dictionaryId: ctx.params?.dictionaryId });
36
+ if (!context.organizationId) {
37
+ throw new CrudHttpError(400, { error: context.translate("dictionaries.errors.organization_required", "Organization context is required") });
38
+ }
39
+ const dictionaryEm = context.em.fork();
40
+ const dictionary = await findOneWithDecryption(
41
+ dictionaryEm,
42
+ Dictionary,
43
+ {
44
+ id: dictionaryId,
45
+ organizationId: context.organizationId,
46
+ tenantId: context.tenantId,
47
+ deletedAt: null
48
+ },
49
+ void 0,
50
+ { tenantId: context.tenantId, organizationId: context.organizationId }
51
+ );
52
+ if (!dictionary) {
53
+ throw new CrudHttpError(404, { error: context.translate("dictionaries.errors.not_found", "Dictionary not found") });
54
+ }
55
+ const payload = reorderDictionaryEntriesSchema.parse(await readJsonSafe(req, {}));
56
+ const guardUserId = resolveDictionaryActorId(context.auth);
57
+ const guardResult = await validateCrudMutationGuard(context.container, {
58
+ tenantId: context.tenantId,
59
+ organizationId: context.organizationId,
60
+ userId: guardUserId,
61
+ resourceKind: "dictionaries.dictionary",
62
+ resourceId: dictionaryId,
63
+ operation: "custom",
64
+ requestMethod: req.method,
65
+ requestHeaders: req.headers,
66
+ mutationPayload: payload
67
+ });
68
+ if (guardResult && !guardResult.ok) {
69
+ return NextResponse.json(guardResult.body, { status: guardResult.status });
70
+ }
71
+ const commandInput = reorderDictionaryEntriesCommandSchema.parse({
72
+ dictionaryId,
73
+ tenantId: context.tenantId,
74
+ organizationId: context.organizationId,
75
+ entries: payload.entries
76
+ });
77
+ const commandBus = context.container.resolve("commandBus");
78
+ const { logEntry } = await commandBus.execute(
79
+ "dictionaries.entries.reorder",
80
+ {
81
+ input: commandInput,
82
+ ctx: context.ctx
83
+ }
84
+ );
85
+ if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
86
+ await runCrudMutationGuardAfterSuccess(context.container, {
87
+ tenantId: context.tenantId,
88
+ organizationId: context.organizationId,
89
+ userId: guardUserId,
90
+ resourceKind: "dictionaries.dictionary",
91
+ resourceId: dictionaryId,
92
+ operation: "custom",
93
+ requestMethod: req.method,
94
+ requestHeaders: req.headers,
95
+ metadata: guardResult.metadata ?? null
96
+ });
97
+ }
98
+ const response = NextResponse.json({ ok: true });
99
+ if (logEntry?.undoToken && logEntry.id && logEntry.commandId) {
100
+ response.headers.set(
101
+ "x-om-operation",
102
+ serializeOperationMetadata({
103
+ id: logEntry.id,
104
+ undoToken: logEntry.undoToken,
105
+ commandId: logEntry.commandId,
106
+ actionLabel: logEntry.actionLabel ?? null,
107
+ resourceKind: logEntry.resourceKind ?? "dictionaries.dictionary",
108
+ resourceId: logEntry.resourceId ?? dictionaryId,
109
+ executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : (/* @__PURE__ */ new Date()).toISOString()
110
+ })
111
+ );
112
+ }
113
+ return response;
114
+ } catch (err) {
115
+ if (err instanceof CrudHttpError) {
116
+ return NextResponse.json(err.body, { status: err.status });
117
+ }
118
+ console.error("[dictionaries/:id/entries/reorder.POST] Unexpected error", err);
119
+ return NextResponse.json({ error: "Failed to reorder dictionary entries" }, { status: 500 });
120
+ }
121
+ }
122
+ const reorderPostDoc = {
123
+ summary: "Reorder dictionary entries",
124
+ description: "Updates the position of dictionary entries for drag-and-drop reordering.",
125
+ tags: [dictionariesTag],
126
+ requestBody: {
127
+ contentType: "application/json",
128
+ schema: reorderEntriesRequestSchema,
129
+ description: "Array of entry IDs with their new positions."
130
+ },
131
+ responses: [
132
+ { status: 200, description: "Entries reordered.", schema: dictionariesOkSchema }
133
+ ],
134
+ errors: [
135
+ { status: 400, description: "Validation failed", schema: dictionariesErrorSchema },
136
+ { status: 401, description: "Authentication required", schema: dictionariesErrorSchema },
137
+ { status: 404, description: "Dictionary not found", schema: dictionariesErrorSchema },
138
+ { status: 500, description: "Failed to reorder entries", schema: dictionariesErrorSchema }
139
+ ]
140
+ };
141
+ const openApi = {
142
+ tag: dictionariesTag,
143
+ summary: "Reorder dictionary entries",
144
+ pathParams: dictionaryIdParamsSchema,
145
+ methods: {
146
+ POST: reorderPostDoc
147
+ }
148
+ };
149
+ export {
150
+ POST,
151
+ metadata,
152
+ openApi
153
+ };
154
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/dictionaries/api/%5BdictionaryId%5D/entries/reorder/route.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { Dictionary } from '@open-mercato/core/modules/dictionaries/data/entities'\nimport { resolveDictionariesRouteContext } from '@open-mercato/core/modules/dictionaries/api/context'\nimport {\n reorderDictionaryEntriesCommandSchema,\n reorderDictionaryEntriesSchema,\n type ReorderDictionaryEntriesCommandInput,\n} from '@open-mercato/core/modules/dictionaries/data/validators'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { serializeOperationMetadata } from '@open-mercato/shared/lib/commands/operationMetadata'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport {\n dictionaryIdParamsSchema,\n dictionariesErrorSchema,\n dictionariesOkSchema,\n dictionariesTag,\n reorderEntriesRequestSchema,\n} from '../../../openapi'\nimport { resolveDictionaryActorId } from '../../../context'\n\nconst paramsSchema = z.object({ dictionaryId: z.string().uuid() })\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['dictionaries.manage'] },\n}\n\nexport async function POST(req: Request, ctx: { params?: { dictionaryId?: string } }) {\n try {\n const context = await resolveDictionariesRouteContext(req)\n if (!context.auth) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const { dictionaryId } = paramsSchema.parse({ dictionaryId: ctx.params?.dictionaryId })\n\n if (!context.organizationId) {\n throw new CrudHttpError(400, { error: context.translate('dictionaries.errors.organization_required', 'Organization context is required') })\n }\n const dictionaryEm = context.em.fork()\n const dictionary = await findOneWithDecryption(\n dictionaryEm,\n Dictionary,\n {\n id: dictionaryId,\n organizationId: context.organizationId,\n tenantId: context.tenantId,\n deletedAt: null,\n },\n undefined,\n { tenantId: context.tenantId, organizationId: context.organizationId },\n )\n if (!dictionary) {\n throw new CrudHttpError(404, { error: context.translate('dictionaries.errors.not_found', 'Dictionary not found') })\n }\n\n const payload = reorderDictionaryEntriesSchema.parse(await readJsonSafe(req, {}))\n const guardUserId = resolveDictionaryActorId(context.auth)\n const guardResult = await validateCrudMutationGuard(context.container, {\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n userId: guardUserId,\n resourceKind: 'dictionaries.dictionary',\n resourceId: dictionaryId,\n operation: 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: payload,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const commandInput = reorderDictionaryEntriesCommandSchema.parse({\n dictionaryId,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n entries: payload.entries,\n } satisfies ReorderDictionaryEntriesCommandInput)\n\n const commandBus = context.container.resolve('commandBus') as CommandBus\n const { logEntry } = await commandBus.execute<ReorderDictionaryEntriesCommandInput, { dictionaryId: string; updatedIds: string[] }>(\n 'dictionaries.entries.reorder',\n {\n input: commandInput,\n ctx: context.ctx,\n },\n )\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(context.container, {\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n userId: guardUserId,\n resourceKind: 'dictionaries.dictionary',\n resourceId: dictionaryId,\n operation: 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const response = NextResponse.json({ ok: true })\n if (logEntry?.undoToken && logEntry.id && logEntry.commandId) {\n response.headers.set(\n 'x-om-operation',\n serializeOperationMetadata({\n id: logEntry.id,\n undoToken: logEntry.undoToken,\n commandId: logEntry.commandId,\n actionLabel: logEntry.actionLabel ?? null,\n resourceKind: logEntry.resourceKind ?? 'dictionaries.dictionary',\n resourceId: logEntry.resourceId ?? dictionaryId,\n executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : new Date().toISOString(),\n }),\n )\n }\n return response\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('[dictionaries/:id/entries/reorder.POST] Unexpected error', err)\n return NextResponse.json({ error: 'Failed to reorder dictionary entries' }, { status: 500 })\n }\n}\n\nconst reorderPostDoc: OpenApiMethodDoc = {\n summary: 'Reorder dictionary entries',\n description: 'Updates the position of dictionary entries for drag-and-drop reordering.',\n tags: [dictionariesTag],\n requestBody: {\n contentType: 'application/json',\n schema: reorderEntriesRequestSchema,\n description: 'Array of entry IDs with their new positions.',\n },\n responses: [\n { status: 200, description: 'Entries reordered.', schema: dictionariesOkSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: dictionariesErrorSchema },\n { status: 401, description: 'Authentication required', schema: dictionariesErrorSchema },\n { status: 404, description: 'Dictionary not found', schema: dictionariesErrorSchema },\n { status: 500, description: 'Failed to reorder entries', schema: dictionariesErrorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: dictionariesTag,\n summary: 'Reorder dictionary entries',\n pathParams: dictionaryIdParamsSchema,\n methods: {\n POST: reorderPostDoc,\n },\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -57,7 +57,7 @@ async function GET(req, ctx) {
57
57
  organizationId: dictionary.organizationId,
58
58
  tenantId: dictionary.tenantId
59
59
  },
60
- { orderBy: { label: "asc" } }
60
+ { orderBy: { position: "asc", label: "asc" } }
61
61
  );
62
62
  return NextResponse.json({
63
63
  items: entries.map((entry) => ({
@@ -66,6 +66,8 @@ async function GET(req, ctx) {
66
66
  label: entry.label,
67
67
  color: entry.color,
68
68
  icon: entry.icon,
69
+ position: entry.position ?? 0,
70
+ isDefault: entry.isDefault ?? false,
69
71
  createdAt: entry.createdAt,
70
72
  updatedAt: entry.updatedAt
71
73
  }))
@@ -112,6 +114,8 @@ async function POST(req, ctx) {
112
114
  label: entry.label,
113
115
  color: entry.color,
114
116
  icon: entry.icon,
117
+ position: entry.position ?? 0,
118
+ isDefault: entry.isDefault ?? false,
115
119
  createdAt: entry.createdAt,
116
120
  updatedAt: entry.updatedAt
117
121
  }, { status: 201 });
@@ -140,7 +144,7 @@ async function POST(req, ctx) {
140
144
  }
141
145
  const dictionaryEntriesGetDoc = {
142
146
  summary: "List dictionary entries",
143
- description: "Returns entries for the specified dictionary ordered alphabetically.",
147
+ description: "Returns entries for the specified dictionary ordered by position.",
144
148
  tags: [dictionariesTag],
145
149
  responses: [
146
150
  { status: 200, description: "Dictionary entries.", schema: dictionaryEntryListResponseSchema }