@aglyn/plugins-crm 1.0.0-beta.221 → 1.0.0-beta.223

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 (541) hide show
  1. package/README.md +2 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/activity-list.js +12 -5
  4. package/src/lib/components/activity-list.js.map +1 -1
  5. package/src/lib/components/companies-bulk-bar.d.ts +1 -4
  6. package/src/lib/components/companies-bulk-bar.js +7 -20
  7. package/src/lib/components/companies-bulk-bar.js.map +1 -1
  8. package/src/lib/components/companies-section.d.ts +3 -3
  9. package/src/lib/components/companies-section.js +149 -46
  10. package/src/lib/components/companies-section.js.map +1 -1
  11. package/src/lib/components/company-edit-drawer.js +281 -20
  12. package/src/lib/components/company-edit-drawer.js.map +1 -1
  13. package/src/lib/components/company-properties-card.js +99 -8
  14. package/src/lib/components/company-properties-card.js.map +1 -1
  15. package/src/lib/components/contact-detail-page.js +3 -1
  16. package/src/lib/components/contact-detail-page.js.map +1 -1
  17. package/src/lib/components/contact-merge-dialog.js +33 -10
  18. package/src/lib/components/contact-merge-dialog.js.map +1 -1
  19. package/src/lib/components/contact-properties-card.d.ts +0 -69
  20. package/src/lib/components/contact-properties-card.js +350 -60
  21. package/src/lib/components/contact-properties-card.js.map +1 -1
  22. package/src/lib/components/contact-reports-to-field.d.ts +46 -0
  23. package/src/lib/components/contact-reports-to-field.js +67 -0
  24. package/src/lib/components/contact-reports-to-field.js.map +1 -0
  25. package/src/lib/components/contacts-bulk-bar.d.ts +1 -8
  26. package/src/lib/components/contacts-bulk-bar.js +7 -19
  27. package/src/lib/components/contacts-bulk-bar.js.map +1 -1
  28. package/src/lib/components/contacts-section.js +46 -33
  29. package/src/lib/components/contacts-section.js.map +1 -1
  30. package/src/lib/components/crm-call-actions.d.ts +10 -0
  31. package/src/lib/components/crm-call-actions.js +26 -9
  32. package/src/lib/components/crm-call-actions.js.map +1 -1
  33. package/src/lib/components/crm-next-activity-column.js +1 -1
  34. package/src/lib/components/crm-next-activity-column.js.map +1 -1
  35. package/src/lib/components/crm-record-picker.d.ts +15 -0
  36. package/src/lib/components/crm-record-picker.js +16 -10
  37. package/src/lib/components/crm-record-picker.js.map +1 -1
  38. package/src/lib/components/crm-transfer-buttons.d.ts +54 -0
  39. package/src/lib/components/crm-transfer-buttons.js +167 -0
  40. package/src/lib/components/crm-transfer-buttons.js.map +1 -0
  41. package/src/lib/components/deal-contact-roles-card.d.ts +46 -0
  42. package/src/lib/components/deal-contact-roles-card.js +368 -0
  43. package/src/lib/components/deal-contact-roles-card.js.map +1 -0
  44. package/src/lib/components/deal-detail-page.d.ts +3 -2
  45. package/src/lib/components/deal-detail-page.js +25 -6
  46. package/src/lib/components/deal-detail-page.js.map +1 -1
  47. package/src/lib/components/deal-edit-drawer.d.ts +10 -0
  48. package/src/lib/components/deal-edit-drawer.js +219 -10
  49. package/src/lib/components/deal-edit-drawer.js.map +1 -1
  50. package/src/lib/components/deal-properties-card.d.ts +7 -0
  51. package/src/lib/components/deal-properties-card.js +34 -3
  52. package/src/lib/components/deal-properties-card.js.map +1 -1
  53. package/src/lib/components/deal-stage-card.d.ts +4 -0
  54. package/src/lib/components/deal-stage-card.js +10 -2
  55. package/src/lib/components/deal-stage-card.js.map +1 -1
  56. package/src/lib/components/deals-bulk-bar.d.ts +0 -3
  57. package/src/lib/components/deals-bulk-bar.js +7 -20
  58. package/src/lib/components/deals-bulk-bar.js.map +1 -1
  59. package/src/lib/components/deals-section.d.ts +3 -3
  60. package/src/lib/components/deals-section.js +123 -63
  61. package/src/lib/components/deals-section.js.map +1 -1
  62. package/src/lib/components/fields-section.js +31 -17
  63. package/src/lib/components/fields-section.js.map +1 -1
  64. package/src/lib/components/lead-convert-dialog.d.ts +4 -0
  65. package/src/lib/components/lead-convert-dialog.js +23 -1
  66. package/src/lib/components/lead-convert-dialog.js.map +1 -1
  67. package/src/lib/components/lead-detail-page.js +8 -2
  68. package/src/lib/components/lead-detail-page.js.map +1 -1
  69. package/src/lib/components/lead-profile-fields.d.ts +71 -0
  70. package/src/lib/components/lead-profile-fields.js +386 -0
  71. package/src/lib/components/lead-profile-fields.js.map +1 -0
  72. package/src/lib/components/lead-properties-card.d.ts +2 -1
  73. package/src/lib/components/lead-properties-card.js +85 -176
  74. package/src/lib/components/lead-properties-card.js.map +1 -1
  75. package/src/lib/components/lead-source-select.d.ts +4 -23
  76. package/src/lib/components/lead-source-select.js +9 -73
  77. package/src/lib/components/lead-source-select.js.map +1 -1
  78. package/src/lib/components/lead-status-chip.d.ts +9 -3
  79. package/src/lib/components/lead-status-chip.js +8 -4
  80. package/src/lib/components/lead-status-chip.js.map +1 -1
  81. package/src/lib/components/lead-status-options.d.ts +20 -0
  82. package/src/lib/components/lead-status-options.js +51 -0
  83. package/src/lib/components/lead-status-options.js.map +1 -0
  84. package/src/lib/components/lead-unqualify-dialog.d.ts +5 -0
  85. package/src/lib/components/lead-unqualify-dialog.js +50 -18
  86. package/src/lib/components/lead-unqualify-dialog.js.map +1 -1
  87. package/src/lib/components/leads-bulk-bar.d.ts +0 -3
  88. package/src/lib/components/leads-bulk-bar.js +29 -29
  89. package/src/lib/components/leads-bulk-bar.js.map +1 -1
  90. package/src/lib/components/leads-section.js +120 -68
  91. package/src/lib/components/leads-section.js.map +1 -1
  92. package/src/lib/components/linked-deals-card.d.ts +4 -0
  93. package/src/lib/components/linked-deals-card.js +47 -3
  94. package/src/lib/components/linked-deals-card.js.map +1 -1
  95. package/src/lib/components/log-activity-dialog.js +43 -3
  96. package/src/lib/components/log-activity-dialog.js.map +1 -1
  97. package/src/lib/components/new-contact-drawer.d.ts +8 -0
  98. package/src/lib/components/new-contact-drawer.js +108 -6
  99. package/src/lib/components/new-contact-drawer.js.map +1 -1
  100. package/src/lib/components/new-lead-drawer.d.ts +9 -2
  101. package/src/lib/components/new-lead-drawer.js +88 -121
  102. package/src/lib/components/new-lead-drawer.js.map +1 -1
  103. package/src/lib/components/picklist-select.d.ts +36 -0
  104. package/src/lib/components/picklist-select.js +114 -0
  105. package/src/lib/components/picklist-select.js.map +1 -0
  106. package/src/lib/components/picklist-values-card.d.ts +34 -0
  107. package/src/lib/components/{lead-source-values-card.js → picklist-values-card.js} +241 -58
  108. package/src/lib/components/picklist-values-card.js.map +1 -0
  109. package/src/lib/components/pipeline-stages-dialog.d.ts +7 -0
  110. package/src/lib/components/pipeline-stages-dialog.js +26 -4
  111. package/src/lib/components/pipeline-stages-dialog.js.map +1 -1
  112. package/src/lib/components/pipelines-dialog.js +15 -6
  113. package/src/lib/components/pipelines-dialog.js.map +1 -1
  114. package/src/lib/components/recent-activity-feed.js +20 -5
  115. package/src/lib/components/recent-activity-feed.js.map +1 -1
  116. package/src/lib/components/recipes-card.js +4 -2
  117. package/src/lib/components/recipes-card.js.map +1 -1
  118. package/src/lib/components/record-tasks-card.js +15 -8
  119. package/src/lib/components/record-tasks-card.js.map +1 -1
  120. package/src/lib/components/reports/forecast-card.d.ts +6 -0
  121. package/src/lib/components/reports/forecast-card.js +101 -3
  122. package/src/lib/components/reports/forecast-card.js.map +1 -1
  123. package/src/lib/components/reports/lead-funnel-card.d.ts +12 -0
  124. package/src/lib/components/reports/lead-funnel-card.js +9 -5
  125. package/src/lib/components/reports/lead-funnel-card.js.map +1 -1
  126. package/src/lib/components/reports/lead-source-card.d.ts +23 -0
  127. package/src/lib/components/reports/lead-source-card.js +318 -0
  128. package/src/lib/components/reports/lead-source-card.js.map +1 -0
  129. package/src/lib/components/reports/pipeline-card.js +2 -1
  130. package/src/lib/components/reports/pipeline-card.js.map +1 -1
  131. package/src/lib/components/reports/report-export.js +1 -1
  132. package/src/lib/components/reports/report-export.js.map +1 -1
  133. package/src/lib/components/reports-section.js +8 -0
  134. package/src/lib/components/reports-section.js.map +1 -1
  135. package/src/lib/components/sharing-rule-drawer.d.ts +5 -0
  136. package/src/lib/components/sharing-rule-drawer.js +108 -19
  137. package/src/lib/components/sharing-rule-drawer.js.map +1 -1
  138. package/src/lib/components/sharing-rules-card.js +11 -3
  139. package/src/lib/components/sharing-rules-card.js.map +1 -1
  140. package/src/lib/components/task-cells.d.ts +9 -1
  141. package/src/lib/components/task-cells.js +9 -4
  142. package/src/lib/components/task-cells.js.map +1 -1
  143. package/src/lib/components/task-edit-drawer.js +111 -43
  144. package/src/lib/components/task-edit-drawer.js.map +1 -1
  145. package/src/lib/components/tasks-bulk-bar.d.ts +0 -3
  146. package/src/lib/components/tasks-bulk-bar.js +7 -20
  147. package/src/lib/components/tasks-bulk-bar.js.map +1 -1
  148. package/src/lib/components/tasks-calendar.d.ts +3 -0
  149. package/src/lib/components/tasks-calendar.js +8 -1
  150. package/src/lib/components/tasks-calendar.js.map +1 -1
  151. package/src/lib/components/tasks-section.d.ts +3 -3
  152. package/src/lib/components/tasks-section.js +58 -43
  153. package/src/lib/components/tasks-section.js.map +1 -1
  154. package/src/lib/constants/api-routes.d.ts +2 -9
  155. package/src/lib/constants/api-routes.js +1 -7
  156. package/src/lib/constants/api-routes.js.map +1 -1
  157. package/src/lib/constants/bundle-common.d.ts +6 -0
  158. package/src/lib/constants/bundle-common.js +11 -0
  159. package/src/lib/constants/bundle-common.js.map +1 -1
  160. package/src/lib/constants/company-filters.d.ts +14 -0
  161. package/src/lib/constants/company-filters.js +51 -1
  162. package/src/lib/constants/company-filters.js.map +1 -1
  163. package/src/lib/constants/contact-filters.d.ts +2 -0
  164. package/src/lib/constants/contact-filters.js +18 -1
  165. package/src/lib/constants/contact-filters.js.map +1 -1
  166. package/src/lib/constants/deal-filters.d.ts +22 -1
  167. package/src/lib/constants/deal-filters.js +67 -4
  168. package/src/lib/constants/deal-filters.js.map +1 -1
  169. package/src/lib/declarations.console-server.d.ts +3 -0
  170. package/src/lib/declarations.console-server.js +35 -0
  171. package/src/lib/declarations.console-server.js.map +1 -1
  172. package/src/lib/declarations.d.ts +26 -0
  173. package/src/lib/declarations.js +35 -0
  174. package/src/lib/declarations.js.map +1 -0
  175. package/src/lib/declarations.server.d.ts +11 -0
  176. package/src/lib/declarations.server.js +97 -1
  177. package/src/lib/declarations.server.js.map +1 -1
  178. package/src/lib/hooks/use-company-picklists.d.ts +15 -0
  179. package/src/lib/hooks/use-company-picklists.js +55 -0
  180. package/src/lib/hooks/use-company-picklists.js.map +1 -0
  181. package/src/lib/hooks/use-crm-picklist.d.ts +25 -0
  182. package/src/lib/hooks/use-crm-picklist.js +53 -0
  183. package/src/lib/hooks/use-crm-picklist.js.map +1 -0
  184. package/src/lib/hooks/use-crm-record-names.d.ts +16 -0
  185. package/src/lib/hooks/use-crm-record-names.js +45 -19
  186. package/src/lib/hooks/use-crm-record-names.js.map +1 -1
  187. package/src/lib/hooks/use-crm-task-picklists.d.ts +11 -0
  188. package/src/lib/hooks/use-crm-task-picklists.js +45 -0
  189. package/src/lib/hooks/use-crm-task-picklists.js.map +1 -0
  190. package/src/lib/hooks/use-deals.d.ts +14 -0
  191. package/src/lib/hooks/use-deals.js +29 -0
  192. package/src/lib/hooks/use-deals.js.map +1 -1
  193. package/src/lib/hooks/use-lead-picklists.d.ts +14 -0
  194. package/src/lib/hooks/use-lead-picklists.js +46 -0
  195. package/src/lib/hooks/use-lead-picklists.js.map +1 -0
  196. package/src/lib/hooks/use-lead-source-picklist.d.ts +5 -19
  197. package/src/lib/hooks/use-lead-source-picklist.js +12 -22
  198. package/src/lib/hooks/use-lead-source-picklist.js.map +1 -1
  199. package/src/lib/hooks/use-lead-status-picklist.d.ts +9 -0
  200. package/src/lib/hooks/use-lead-status-picklist.js +40 -0
  201. package/src/lib/hooks/use-lead-status-picklist.js.map +1 -0
  202. package/src/lib/model/companies.d.ts +32 -3
  203. package/src/lib/model/companies.js +133 -16
  204. package/src/lib/model/companies.js.map +1 -1
  205. package/src/lib/model/contact-merge.d.ts +27 -3
  206. package/src/lib/model/contact-merge.js +81 -7
  207. package/src/lib/model/contact-merge.js.map +1 -1
  208. package/src/lib/model/contact-record.d.ts +17 -0
  209. package/src/lib/model/contact-record.js +17 -2
  210. package/src/lib/model/contact-record.js.map +1 -1
  211. package/src/lib/model/contact-update.d.ts +31 -2
  212. package/src/lib/model/contact-update.js +14 -0
  213. package/src/lib/model/contact-update.js.map +1 -1
  214. package/src/lib/model/crm-list-query.d.ts +5 -0
  215. package/src/lib/model/crm-list-query.js +8 -0
  216. package/src/lib/model/crm-list-query.js.map +1 -1
  217. package/src/lib/model/crm-next-activity.d.ts +107 -0
  218. package/src/lib/model/crm-next-activity.js +140 -0
  219. package/src/lib/model/crm-next-activity.js.map +1 -0
  220. package/src/lib/model/crm-recipes.d.ts +40 -0
  221. package/src/lib/model/crm-recipes.js +259 -0
  222. package/src/lib/model/crm-recipes.js.map +1 -0
  223. package/src/lib/model/crm-record-counts.d.ts +36 -0
  224. package/src/lib/model/crm-record-counts.js +54 -0
  225. package/src/lib/model/crm-record-counts.js.map +1 -0
  226. package/src/lib/model/crm-record-lists.d.ts +23 -0
  227. package/src/lib/model/crm-record-lists.js +161 -0
  228. package/src/lib/model/crm-record-lists.js.map +1 -0
  229. package/src/lib/model/crm-reports.d.ts +73 -3
  230. package/src/lib/model/crm-reports.js +120 -1
  231. package/src/lib/model/crm-reports.js.map +1 -1
  232. package/src/lib/model/crm-sharing.d.ts +21 -3
  233. package/src/lib/model/crm-sharing.js +27 -6
  234. package/src/lib/model/crm-sharing.js.map +1 -1
  235. package/src/lib/model/crm-task-reminders.d.ts +152 -0
  236. package/src/lib/model/crm-task-reminders.js +161 -0
  237. package/src/lib/model/crm-task-reminders.js.map +1 -0
  238. package/src/lib/model/deal-board-model.d.ts +8 -2
  239. package/src/lib/model/deal-board-model.js +15 -2
  240. package/src/lib/model/deal-board-model.js.map +1 -1
  241. package/src/lib/model/deal-contact-roles.d.ts +45 -0
  242. package/src/lib/model/deal-contact-roles.js +73 -0
  243. package/src/lib/model/deal-contact-roles.js.map +1 -0
  244. package/src/lib/model/deal-form-model.d.ts +56 -0
  245. package/src/lib/model/deal-form-model.js +79 -7
  246. package/src/lib/model/deal-form-model.js.map +1 -1
  247. package/src/lib/model/download-text-file.d.ts +23 -0
  248. package/src/lib/model/download-text-file.js +34 -0
  249. package/src/lib/model/download-text-file.js.map +1 -0
  250. package/src/lib/model/lead-filters.d.ts +36 -2
  251. package/src/lib/model/lead-filters.js +123 -2
  252. package/src/lib/model/lead-filters.js.map +1 -1
  253. package/src/lib/model/lead-source-direction.d.ts +38 -0
  254. package/src/lib/model/lead-source-direction.js +52 -0
  255. package/src/lib/model/lead-source-direction.js.map +1 -0
  256. package/src/lib/model/next-activity.d.ts +1 -1
  257. package/src/lib/model/next-activity.js.map +1 -1
  258. package/src/lib/model/picklist-values.d.ts +119 -0
  259. package/src/lib/model/picklist-values.js +256 -0
  260. package/src/lib/model/picklist-values.js.map +1 -0
  261. package/src/lib/model/record-facts-disclosed.d.ts +81 -0
  262. package/src/lib/model/record-facts-disclosed.js +281 -0
  263. package/src/lib/model/record-facts-disclosed.js.map +1 -0
  264. package/src/lib/model/record-facts.d.ts +215 -34
  265. package/src/lib/model/record-facts.js +307 -128
  266. package/src/lib/model/record-facts.js.map +1 -1
  267. package/src/lib/model/task-picklists.d.ts +52 -0
  268. package/src/lib/model/task-picklists.js +83 -0
  269. package/src/lib/model/task-picklists.js.map +1 -0
  270. package/src/lib/model/task-routes.d.ts +13 -0
  271. package/src/lib/model/task-routes.js +23 -4
  272. package/src/lib/model/task-routes.js.map +1 -1
  273. package/src/lib/plan-entitlements.js +6 -4
  274. package/src/lib/plan-entitlements.js.map +1 -1
  275. package/src/lib/plugin.js +17 -0
  276. package/src/lib/plugin.js.map +1 -1
  277. package/src/lib/server/api-v1/contacts.js +220 -14
  278. package/src/lib/server/api-v1/contacts.js.map +1 -1
  279. package/src/lib/server/api-v1/crm-activities.js +14 -1
  280. package/src/lib/server/api-v1/crm-activities.js.map +1 -1
  281. package/src/lib/server/api-v1/crm-companies.js +123 -14
  282. package/src/lib/server/api-v1/crm-companies.js.map +1 -1
  283. package/src/lib/server/api-v1/crm-deals.js +291 -26
  284. package/src/lib/server/api-v1/crm-deals.js.map +1 -1
  285. package/src/lib/server/api-v1/crm-leads.js +144 -38
  286. package/src/lib/server/api-v1/crm-leads.js.map +1 -1
  287. package/src/lib/server/api-v1/crm-pipelines.d.ts +6 -0
  288. package/src/lib/server/api-v1/crm-pipelines.js +8 -2
  289. package/src/lib/server/api-v1/crm-pipelines.js.map +1 -1
  290. package/src/lib/server/api-v1/crm-tasks.js +78 -34
  291. package/src/lib/server/api-v1/crm-tasks.js.map +1 -1
  292. package/src/lib/server/api-v1/openapi.d.ts +0 -11
  293. package/src/lib/server/api-v1/openapi.js +171 -16
  294. package/src/lib/server/api-v1/openapi.js.map +1 -1
  295. package/src/lib/server/assign-contact-owner.d.ts +188 -0
  296. package/src/lib/server/assign-contact-owner.js +446 -0
  297. package/src/lib/server/assign-contact-owner.js.map +1 -0
  298. package/src/lib/server/associate-company-by-domain.d.ts +70 -0
  299. package/src/lib/server/associate-company-by-domain.js +153 -0
  300. package/src/lib/server/associate-company-by-domain.js.map +1 -0
  301. package/src/lib/server/automation-steps.d.ts +140 -0
  302. package/src/lib/server/automation-steps.js +669 -0
  303. package/src/lib/server/automation-steps.js.map +1 -0
  304. package/src/lib/server/capture-contact.d.ts +17 -0
  305. package/src/lib/server/capture-contact.js +95 -26
  306. package/src/lib/server/capture-contact.js.map +1 -1
  307. package/src/lib/server/capture-host-contact.d.ts +104 -0
  308. package/src/lib/server/capture-host-contact.js +151 -0
  309. package/src/lib/server/capture-host-contact.js.map +1 -0
  310. package/src/lib/server/company-children.d.ts +25 -0
  311. package/src/lib/server/company-children.js +42 -0
  312. package/src/lib/server/company-children.js.map +1 -0
  313. package/src/lib/server/company-delete.d.ts +18 -0
  314. package/src/lib/server/company-delete.js +44 -21
  315. package/src/lib/server/company-delete.js.map +1 -1
  316. package/src/lib/server/contact-email-history.js +21 -19
  317. package/src/lib/server/contact-email-history.js.map +1 -1
  318. package/src/lib/server/contact-remove.js +27 -2
  319. package/src/lib/server/contact-remove.js.map +1 -1
  320. package/src/lib/server/contact-reports-to.d.ts +61 -0
  321. package/src/lib/server/contact-reports-to.js +114 -0
  322. package/src/lib/server/contact-reports-to.js.map +1 -0
  323. package/src/lib/server/contact-update.d.ts +42 -1
  324. package/src/lib/server/contact-update.js +204 -23
  325. package/src/lib/server/contact-update.js.map +1 -1
  326. package/src/lib/server/convert-host-lead.d.ts +46 -1
  327. package/src/lib/server/convert-host-lead.js +173 -15
  328. package/src/lib/server/convert-host-lead.js.map +1 -1
  329. package/src/lib/server/convert-open-lead.js +12 -5
  330. package/src/lib/server/convert-open-lead.js.map +1 -1
  331. package/src/lib/server/crm-email-activity.d.ts +118 -0
  332. package/src/lib/server/crm-email-activity.js +148 -0
  333. package/src/lib/server/crm-email-activity.js.map +1 -0
  334. package/src/lib/server/crm-inbound-email.js +1 -1
  335. package/src/lib/server/crm-inbound-email.js.map +1 -1
  336. package/src/lib/server/crm-next-activity.d.ts +74 -0
  337. package/src/lib/server/crm-next-activity.js +194 -0
  338. package/src/lib/server/crm-next-activity.js.map +1 -0
  339. package/src/lib/server/crm-record-indexes.d.ts +45 -0
  340. package/src/lib/server/crm-record-indexes.js +78 -0
  341. package/src/lib/server/crm-record-indexes.js.map +1 -0
  342. package/src/lib/server/crm-sharing.d.ts +9 -1
  343. package/src/lib/server/crm-sharing.js +23 -3
  344. package/src/lib/server/crm-sharing.js.map +1 -1
  345. package/src/lib/server/deal-contact-roles.d.ts +27 -0
  346. package/src/lib/server/deal-contact-roles.js +89 -0
  347. package/src/lib/server/deal-contact-roles.js.map +1 -0
  348. package/src/lib/server/email-send.js +2 -1
  349. package/src/lib/server/email-send.js.map +1 -1
  350. package/src/lib/server/lead-convert.d.ts +5 -0
  351. package/src/lib/server/lead-convert.js +19 -3
  352. package/src/lib/server/lead-convert.js.map +1 -1
  353. package/src/lib/server/lead-create.d.ts +17 -2
  354. package/src/lib/server/lead-create.js +46 -14
  355. package/src/lib/server/lead-create.js.map +1 -1
  356. package/src/lib/server/lead-nurturing.d.ts +6 -0
  357. package/src/lib/server/lead-nurturing.js +57 -20
  358. package/src/lib/server/lead-nurturing.js.map +1 -1
  359. package/src/lib/server/lead-picklists.d.ts +35 -0
  360. package/src/lib/server/lead-picklists.js +52 -0
  361. package/src/lib/server/lead-picklists.js.map +1 -0
  362. package/src/lib/server/lead-source-picklist.d.ts +1 -13
  363. package/src/lib/server/lead-source-picklist.js +6 -33
  364. package/src/lib/server/lead-source-picklist.js.map +1 -1
  365. package/src/lib/server/merge-contacts.js +23 -5
  366. package/src/lib/server/merge-contacts.js.map +1 -1
  367. package/src/lib/server/next-activity-routes.js +2 -1
  368. package/src/lib/server/next-activity-routes.js.map +1 -1
  369. package/src/lib/server/person-eraser.d.ts +53 -0
  370. package/src/lib/server/person-eraser.js +149 -0
  371. package/src/lib/server/person-eraser.js.map +1 -0
  372. package/src/lib/server/person-records.d.ts +69 -0
  373. package/src/lib/server/person-records.js +317 -0
  374. package/src/lib/server/person-records.js.map +1 -0
  375. package/src/lib/server/person-refund.d.ts +97 -0
  376. package/src/lib/server/person-refund.js +221 -0
  377. package/src/lib/server/person-refund.js.map +1 -0
  378. package/src/lib/server/picklist-values.d.ts +21 -0
  379. package/src/lib/server/picklist-values.js +308 -0
  380. package/src/lib/server/picklist-values.js.map +1 -0
  381. package/src/lib/server/read-picklist.d.ts +44 -0
  382. package/src/lib/server/read-picklist.js +65 -0
  383. package/src/lib/server/read-picklist.js.map +1 -0
  384. package/src/lib/server/recipe-routes.js +22 -8
  385. package/src/lib/server/recipe-routes.js.map +1 -1
  386. package/src/lib/server/record-email-state.js +7 -1
  387. package/src/lib/server/record-email-state.js.map +1 -1
  388. package/src/lib/server/record-facts.d.ts +3 -0
  389. package/src/lib/server/record-facts.js +233 -31
  390. package/src/lib/server/record-facts.js.map +1 -1
  391. package/src/lib/server/record-origin.d.ts +27 -0
  392. package/src/lib/server/record-origin.js +104 -0
  393. package/src/lib/server/record-origin.js.map +1 -0
  394. package/src/lib/server/record-timeline.js +40 -3
  395. package/src/lib/server/record-timeline.js.map +1 -1
  396. package/src/lib/server/suite-gate.js +4 -3
  397. package/src/lib/server/suite-gate.js.map +1 -1
  398. package/src/lib/server/task-reminders-route.js +2 -1
  399. package/src/lib/server/task-reminders-route.js.map +1 -1
  400. package/src/lib/server/task-routes.js +33 -17
  401. package/src/lib/server/task-routes.js.map +1 -1
  402. package/src/lib/server-deal-stage.d.ts +5 -1
  403. package/src/lib/server-deal-stage.js +10 -5
  404. package/src/lib/server-deal-stage.js.map +1 -1
  405. package/src/lib/server.d.ts +8 -3
  406. package/src/lib/server.js +47 -43
  407. package/src/lib/server.js.map +1 -1
  408. package/src/lib/testing/memory-firestore.d.ts +55 -0
  409. package/src/lib/testing/memory-firestore.js +335 -0
  410. package/src/lib/testing/memory-firestore.js.map +1 -0
  411. package/src/lib/testing/stand-in-email-send-index.d.ts +25 -0
  412. package/src/lib/testing/stand-in-email-send-index.js +49 -0
  413. package/src/lib/testing/stand-in-email-send-index.js.map +1 -0
  414. package/src/lib/transfer/activities.d.ts +30 -0
  415. package/src/lib/transfer/activities.js +132 -0
  416. package/src/lib/transfer/activities.js.map +1 -0
  417. package/src/lib/transfer/aliases.d.ts +22 -0
  418. package/src/lib/transfer/aliases.js +1342 -0
  419. package/src/lib/transfer/aliases.js.map +1 -0
  420. package/src/lib/transfer/common.d.ts +222 -0
  421. package/src/lib/transfer/common.js +832 -0
  422. package/src/lib/transfer/common.js.map +1 -0
  423. package/src/lib/transfer/companies.d.ts +43 -0
  424. package/src/lib/transfer/companies.js +549 -0
  425. package/src/lib/transfer/companies.js.map +1 -0
  426. package/src/lib/transfer/contacts.d.ts +31 -0
  427. package/src/lib/transfer/contacts.js +727 -0
  428. package/src/lib/transfer/contacts.js.map +1 -0
  429. package/src/lib/transfer/deals.d.ts +66 -0
  430. package/src/lib/transfer/deals.js +698 -0
  431. package/src/lib/transfer/deals.js.map +1 -0
  432. package/src/lib/transfer/email-templates-package.d.ts +40 -0
  433. package/src/lib/transfer/email-templates-package.js +76 -0
  434. package/src/lib/transfer/email-templates-package.js.map +1 -0
  435. package/src/lib/transfer/email-templates-package.server.d.ts +32 -0
  436. package/src/lib/transfer/email-templates-package.server.js +176 -0
  437. package/src/lib/transfer/email-templates-package.server.js.map +1 -0
  438. package/src/lib/transfer/fields.d.ts +102 -0
  439. package/src/lib/transfer/fields.js +1755 -0
  440. package/src/lib/transfer/fields.js.map +1 -0
  441. package/src/lib/transfer/leads.d.ts +30 -0
  442. package/src/lib/transfer/leads.js +582 -0
  443. package/src/lib/transfer/leads.js.map +1 -0
  444. package/src/lib/transfer/pipelines.d.ts +21 -0
  445. package/src/lib/transfer/pipelines.js +172 -0
  446. package/src/lib/transfer/pipelines.js.map +1 -0
  447. package/src/lib/transfer/register.d.ts +47 -0
  448. package/src/lib/transfer/register.js +277 -0
  449. package/src/lib/transfer/register.js.map +1 -0
  450. package/src/lib/transfer/tasks.d.ts +30 -0
  451. package/src/lib/transfer/tasks.js +418 -0
  452. package/src/lib/transfer/tasks.js.map +1 -0
  453. package/src/lib/transfer/ui.d.ts +20 -0
  454. package/src/lib/transfer/ui.js +42 -0
  455. package/src/lib/transfer/ui.js.map +1 -0
  456. package/src/lib/components/company-import-drawer.d.ts +0 -42
  457. package/src/lib/components/company-import-drawer.js +0 -99
  458. package/src/lib/components/company-import-drawer.js.map +0 -1
  459. package/src/lib/components/contact-import-drawer.d.ts +0 -46
  460. package/src/lib/components/contact-import-drawer.js +0 -149
  461. package/src/lib/components/contact-import-drawer.js.map +0 -1
  462. package/src/lib/components/crm-export-all-button.d.ts +0 -39
  463. package/src/lib/components/crm-export-all-button.js +0 -98
  464. package/src/lib/components/crm-export-all-button.js.map +0 -1
  465. package/src/lib/components/csv-import-drawer.d.ts +0 -139
  466. package/src/lib/components/csv-import-drawer.js +0 -757
  467. package/src/lib/components/csv-import-drawer.js.map +0 -1
  468. package/src/lib/components/deal-import-drawer.d.ts +0 -24
  469. package/src/lib/components/deal-import-drawer.js +0 -83
  470. package/src/lib/components/deal-import-drawer.js.map +0 -1
  471. package/src/lib/components/lead-import-drawer.d.ts +0 -27
  472. package/src/lib/components/lead-import-drawer.js +0 -118
  473. package/src/lib/components/lead-import-drawer.js.map +0 -1
  474. package/src/lib/components/lead-source-values-card.d.ts +0 -27
  475. package/src/lib/components/lead-source-values-card.js.map +0 -1
  476. package/src/lib/components/task-import-drawer.d.ts +0 -24
  477. package/src/lib/components/task-import-drawer.js +0 -82
  478. package/src/lib/components/task-import-drawer.js.map +0 -1
  479. package/src/lib/model/companies-csv.d.ts +0 -36
  480. package/src/lib/model/companies-csv.js +0 -38
  481. package/src/lib/model/companies-csv.js.map +0 -1
  482. package/src/lib/model/contacts-csv.d.ts +0 -54
  483. package/src/lib/model/contacts-csv.js +0 -67
  484. package/src/lib/model/contacts-csv.js.map +0 -1
  485. package/src/lib/model/crm-company-import.d.ts +0 -154
  486. package/src/lib/model/crm-company-import.js +0 -331
  487. package/src/lib/model/crm-company-import.js.map +0 -1
  488. package/src/lib/model/crm-csv.d.ts +0 -239
  489. package/src/lib/model/crm-csv.js +0 -467
  490. package/src/lib/model/crm-csv.js.map +0 -1
  491. package/src/lib/model/crm-deal-import.d.ts +0 -112
  492. package/src/lib/model/crm-deal-import.js +0 -263
  493. package/src/lib/model/crm-deal-import.js.map +0 -1
  494. package/src/lib/model/crm-import.d.ts +0 -250
  495. package/src/lib/model/crm-import.js +0 -467
  496. package/src/lib/model/crm-import.js.map +0 -1
  497. package/src/lib/model/crm-lead-import.d.ts +0 -138
  498. package/src/lib/model/crm-lead-import.js +0 -446
  499. package/src/lib/model/crm-lead-import.js.map +0 -1
  500. package/src/lib/model/crm-task-import.d.ts +0 -94
  501. package/src/lib/model/crm-task-import.js +0 -275
  502. package/src/lib/model/crm-task-import.js.map +0 -1
  503. package/src/lib/model/deals-csv.d.ts +0 -32
  504. package/src/lib/model/deals-csv.js +0 -36
  505. package/src/lib/model/deals-csv.js.map +0 -1
  506. package/src/lib/model/import-column-shapes.d.ts +0 -36
  507. package/src/lib/model/import-column-shapes.js +0 -76
  508. package/src/lib/model/import-column-shapes.js.map +0 -1
  509. package/src/lib/model/lead-source-values.d.ts +0 -82
  510. package/src/lib/model/lead-source-values.js +0 -149
  511. package/src/lib/model/lead-source-values.js.map +0 -1
  512. package/src/lib/model/leads-csv.d.ts +0 -40
  513. package/src/lib/model/leads-csv.js +0 -40
  514. package/src/lib/model/leads-csv.js.map +0 -1
  515. package/src/lib/model/tasks-csv.d.ts +0 -28
  516. package/src/lib/model/tasks-csv.js +0 -28
  517. package/src/lib/model/tasks-csv.js.map +0 -1
  518. package/src/lib/server/companies-import.d.ts +0 -57
  519. package/src/lib/server/companies-import.js +0 -242
  520. package/src/lib/server/companies-import.js.map +0 -1
  521. package/src/lib/server/contacts-import.d.ts +0 -109
  522. package/src/lib/server/contacts-import.js +0 -393
  523. package/src/lib/server/contacts-import.js.map +0 -1
  524. package/src/lib/server/deals-import.d.ts +0 -76
  525. package/src/lib/server/deals-import.js +0 -248
  526. package/src/lib/server/deals-import.js.map +0 -1
  527. package/src/lib/server/export-route.d.ts +0 -60
  528. package/src/lib/server/export-route.js +0 -447
  529. package/src/lib/server/export-route.js.map +0 -1
  530. package/src/lib/server/import-context.d.ts +0 -87
  531. package/src/lib/server/import-context.js +0 -182
  532. package/src/lib/server/import-context.js.map +0 -1
  533. package/src/lib/server/lead-source-values.d.ts +0 -50
  534. package/src/lib/server/lead-source-values.js +0 -191
  535. package/src/lib/server/lead-source-values.js.map +0 -1
  536. package/src/lib/server/leads-import.d.ts +0 -84
  537. package/src/lib/server/leads-import.js +0 -367
  538. package/src/lib/server/leads-import.js.map +0 -1
  539. package/src/lib/server/tasks-import.d.ts +0 -54
  540. package/src/lib/server/tasks-import.js +0 -160
  541. package/src/lib/server/tasks-import.js.map +0 -1
@@ -0,0 +1,669 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { buildCrmEmailActivity, checkEntitlement, CONTACT_LIFECYCLE_STAGE_LABELS, CONTACT_TAG_MAX_LENGTH, contactFacetPath, CRM_ACTIVITY_LOG_FULL_MESSAGE, CRM_COLLECTIONS, crmActivityLogHasRoom, crmActivityDirection, crmEmailDeliveryTags, crmScopeTokens, crmTaskLabelsForNew, crmTaskListFields, normalizeContactEmail, parseCrmMemberRef, personKey, planLabelGrantingFeature, readContactFacet, visibleToHost } from "@aglyn/aglyn/server";
18
+ import { consentGroupForSite, countCrmActivitiesForRecord, firebaseAdmin, orgDataQueryForHost, restampCrmListFieldsAt } from "@aglyn/tenant-data-admin";
19
+ // The leaf, not the barrel: the specs substitute the barrel wholesale, and
20
+ // the lookup must reach the real index logic under them.
21
+ import { findContactByEmail } from "@aglyn/tenant-data-admin/server/contact-email-index";
22
+ import { FieldValue } from "firebase-admin/firestore";
23
+ // The leaf, not the runtime barrel: the specs substitute it.
24
+ import { OWNER_ASSIGNMENT_REFUSALS, reassignContactOwner, reassignLeadOwner } from "./assign-contact-owner.js";
25
+ import { createResourceUid } from "@aglyn/aglyn/app-utils/create-resource-uid";
26
+ import { readCrmTaskPicklists } from "./read-picklist.js";
27
+ import { CRM_SUITE_FEATURE } from "./suite-gate.js";
28
+ import { crmTaskReminderAfterEdit } from "../model/crm-task-reminders.js";
29
+ import { recomputeCrmNextTaskAt } from "./crm-next-activity.js";
30
+ import { newCrmActivityRef, writeCrmEmailActivity } from "./crm-email-activity.js";
31
+ const DAY_MS = 24 * 60 * 60 * 1000;
32
+ /**
33
+ * The contact an event names, as this site may see it.
34
+ *
35
+ * Id first, because a CRM event carries the document the door just wrote and
36
+ * a lookup by id is a read, not a query. The address second, through the
37
+ * org's address index narrowed to this site (AGL-2633), for every event that
38
+ * predates the CRM and knows only who filled in the form — so an address a
39
+ * merge folded into another record still reaches the person who now holds it.
40
+ */ async function resolveEventContact(hostId, named) {
41
+ var _named_contactId, _hit_data;
42
+ const { ref: contactsRef } = await orgDataQueryForHost(hostId, 'contacts');
43
+ const contactId = String((_named_contactId = named.contactId) != null ? _named_contactId : '').trim();
44
+ if (contactId) {
45
+ const doc = await contactsRef.doc(contactId).get();
46
+ if (doc.exists && visibleToHost(doc.get('visibleTo'), hostId)) {
47
+ var _doc_data;
48
+ return {
49
+ id: doc.id,
50
+ ref: doc.ref,
51
+ data: (_doc_data = doc.data()) != null ? _doc_data : {}
52
+ };
53
+ }
54
+ }
55
+ const hit = await findContactByEmail(contactsRef, named.email, {
56
+ hostId
57
+ });
58
+ return hit ? {
59
+ id: hit.id,
60
+ ref: hit.ref,
61
+ data: (_hit_data = hit.data()) != null ? _hit_data : {}
62
+ } : null;
63
+ }
64
+ /**
65
+ * The lead an event names, as this site may see it: by `leadId` — the `lead`
66
+ * event carries it, and it is the person's key — else by the key of the
67
+ * `email`. A row this site cannot see is absent, exactly as a contact's is.
68
+ */ async function resolveEventLead(hostId, named) {
69
+ var _named_leadId, _doc_data;
70
+ const key = String((_named_leadId = named.leadId) != null ? _named_leadId : '').trim() || personKey(named.email) || '';
71
+ if (!key) return null;
72
+ const { ref: leadsRef } = await orgDataQueryForHost(hostId, 'leads');
73
+ const doc = await leadsRef.doc(key).get();
74
+ if (!doc.exists || !visibleToHost(doc.get('visibleTo'), hostId)) return null;
75
+ return {
76
+ id: doc.id,
77
+ ref: doc.ref,
78
+ data: (_doc_data = doc.data()) != null ? _doc_data : {}
79
+ };
80
+ }
81
+ /** The contact the event names, else its lead — see {@link ResolvedPerson}. */ async function resolveEventPerson(hostId, named) {
82
+ const contact = await resolveEventContact(hostId, named);
83
+ if (contact) return _extends({
84
+ kind: 'contact'
85
+ }, contact);
86
+ const lead = await resolveEventLead(hostId, named);
87
+ return lead ? _extends({
88
+ kind: 'lead'
89
+ }, lead) : null;
90
+ }
91
+ /**
92
+ * The uid a step names for somebody on the team — an owner, an assignee —
93
+ * resolved against the org's roster, whichever way the step named them.
94
+ *
95
+ * A step names a member by uid when a picker wrote it and by address when a
96
+ * person typed it, and the editor's one text field accepts either — so both
97
+ * fields are read through `parseCrmMemberRef`, and an address typed into the
98
+ * uid slot or a uid typed into the address slot still names the person.
99
+ *
100
+ * Both are RESOLVED, not trusted. `orgs/{orgId}/members/{uid}` is keyed by the
101
+ * uid, so a uid costs one document read and must exist: `ownerUid` and
102
+ * `assigneeUid` are fields every reader resolves as a member, and a stranger's
103
+ * uid in one is a task nobody on the team can find. An address is matched on
104
+ * the roster's own `email` field, and two production paths create a member
105
+ * document WITHOUT one (a host-access re-grant, and an add whose auth record
106
+ * carried none) — such a member is named by uid, which is the reason the
107
+ * editor takes one.
108
+ *
109
+ * The roster is the only directory consulted. A project-level Auth lookup by
110
+ * address would resolve people who are not on this organization at all
111
+ * (AGL-1122). A reference that resolves neither way is an error, not a stored
112
+ * string.
113
+ */ async function resolveMemberUid(orgId, named, role) {
114
+ var _parseCrmMemberRef;
115
+ const ref = (_parseCrmMemberRef = parseCrmMemberRef(named.uid)) != null ? _parseCrmMemberRef : parseCrmMemberRef(named.email);
116
+ if (!ref) return {
117
+ error: `no ${role} named on the step`
118
+ };
119
+ if (!orgId) return {
120
+ error: 'this site has no organization'
121
+ };
122
+ const members = firebaseAdmin.app().firestore().collection('orgs').doc(orgId).collection('members');
123
+ if (ref.kind === 'uid') {
124
+ const member = await members.doc(ref.uid).get();
125
+ if (member.exists) return {
126
+ uid: ref.uid,
127
+ detail: ref.uid
128
+ };
129
+ return {
130
+ error: `no team member with the id ${ref.uid}`
131
+ };
132
+ }
133
+ const byField = (await members.where('email', '==', ref.email).limit(1).get()).docs[0];
134
+ if (byField) return {
135
+ uid: byField.id,
136
+ detail: ref.email
137
+ };
138
+ return {
139
+ error: `no team member with the address ${ref.email}`
140
+ };
141
+ }
142
+ /**
143
+ * Runs one CRM step for the person the event names: the executor the CRM
144
+ * registers on the server-step seam for every type in `CRM_STEP_TYPES`.
145
+ *
146
+ * Never throws for a plan without the CRM, a missing person, an unknown owner
147
+ * or a site with no org — those are answered as `error` so the run records
148
+ * them; a Firestore failure propagates, and the engine records it the same
149
+ * way.
150
+ */ export async function runCrmAutomationStep(request, nowMs = Date.now()) {
151
+ var _contact_data_email, _env_org;
152
+ if (!checkEntitlement(request.org, CRM_SUITE_FEATURE)) {
153
+ return {
154
+ error: `CRM steps require the ${planLabelGrantingFeature(CRM_SUITE_FEATURE)} plan`
155
+ };
156
+ }
157
+ const env = {
158
+ hostId: request.hostId,
159
+ org: request.org,
160
+ orgId: request.orgId
161
+ };
162
+ const step = request.step;
163
+ const actionId = request.run.id;
164
+ const { hostId } = env;
165
+ const person = await resolveEventPerson(hostId, request.payload);
166
+ if (!person) {
167
+ var _ref, _request_payload_contactId;
168
+ const named = String((_ref = (_request_payload_contactId = request.payload['contactId']) != null ? _request_payload_contactId : request.payload['email']) != null ? _ref : '').trim();
169
+ return {
170
+ error: named ? `no contact or lead this site can see for ${named}` : 'the event names no contact — no contactId or email in its payload'
171
+ };
172
+ }
173
+ if (person.kind === 'lead') return runLeadStep(env, actionId, step, person, nowMs);
174
+ const contact = person;
175
+ /*
176
+ * THE HOLDER whose facet the write addresses — the site's consent group,
177
+ * which is the site alone unless the org declared the site one of a set
178
+ * that presents as one sender. Same resolution the capture doors use, so a
179
+ * stage set here lands in the facet the console reads.
180
+ */ const group = await consentGroupForSite(hostId);
181
+ const facet = readContactFacet(contact.data, group.groupId);
182
+ const email = String((_contact_data_email = contact.data['email']) != null ? _contact_data_email : '');
183
+ if (step.type === 'setContactStage') {
184
+ var _facet_lifecycleStage;
185
+ const previous = (_facet_lifecycleStage = facet.lifecycleStage) != null ? _facet_lifecycleStage : '';
186
+ const label = CONTACT_LIFECYCLE_STAGE_LABELS[step.lifecycleStage];
187
+ /*
188
+ * A stage set to what it already is changes nothing and ANNOUNCES
189
+ * nothing. The write is skipped so the row's `updatedAt` does not move for
190
+ * a non-event, and the absent emit is what stops an action that sets the
191
+ * stage it listens for from re-running on its own write — the engine's
192
+ * nesting cap bounds that chain, this ends it at once.
193
+ */ if (previous === step.lifecycleStage) {
194
+ return {
195
+ detail: `${label} (already)`
196
+ };
197
+ }
198
+ await contact.ref.update({
199
+ [contactFacetPath(group.groupId, 'lifecycleStage')]: step.lifecycleStage,
200
+ updatedAt: FieldValue.serverTimestamp()
201
+ });
202
+ // The stage is what the Contacts list filters by (AGL-3321).
203
+ await restampCrmListFieldsAt(contact.ref, 'contacts');
204
+ /*
205
+ * A stage set by an automation IS a stage change, and the action
206
+ * listening for it must run — but through the engine's nesting cap, so
207
+ * the event is answered back for the engine to raise, never raised here.
208
+ */ return {
209
+ detail: label,
210
+ emit: {
211
+ event: 'contactStageChanged',
212
+ payload: {
213
+ contactId: contact.id,
214
+ email,
215
+ lifecycleStage: step.lifecycleStage,
216
+ previousStage: previous
217
+ }
218
+ }
219
+ };
220
+ }
221
+ if (step.type === 'addContactTag') {
222
+ var _step_tag;
223
+ const tag = String((_step_tag = step.tag) != null ? _step_tag : '').trim().slice(0, CONTACT_TAG_MAX_LENGTH);
224
+ if (!tag) return {
225
+ error: 'the step has no tag'
226
+ };
227
+ // `arrayUnion`, so the tag a merchant already applied by hand is not
228
+ // duplicated and the tags beside it are kept.
229
+ await contact.ref.update({
230
+ [contactFacetPath(group.groupId, 'tags')]: FieldValue.arrayUnion(tag),
231
+ updatedAt: FieldValue.serverTimestamp()
232
+ });
233
+ // The tags are what the Contacts list filters by (AGL-3321).
234
+ await restampCrmListFieldsAt(contact.ref, 'contacts');
235
+ return {
236
+ detail: tag
237
+ };
238
+ }
239
+ if (step.type === 'assignContactOwner') {
240
+ /*
241
+ * Through the one server assignment (AGL-2618), in both of the step's
242
+ * modes, rather than a facet write of its own: the helper is what moves
243
+ * the round-robin pointer inside the transaction that writes the owner,
244
+ * mirrors the owner onto the site's lead, and tells the new owner. A
245
+ * member named on the step is still resolved here — by address against
246
+ * the roster, as before — and handed over by uid; the helper checks the
247
+ * roster document again, which is one read and the same answer.
248
+ */ let assign;
249
+ let named = 'round robin';
250
+ if (step.roundRobin === true) {
251
+ assign = {
252
+ roundRobin: true
253
+ };
254
+ } else {
255
+ const owner = await resolveMemberUid(env.orgId, {
256
+ uid: step.ownerUid,
257
+ email: step.ownerEmail
258
+ }, 'owner');
259
+ if ('error' in owner) return {
260
+ error: owner.error
261
+ };
262
+ assign = {
263
+ memberUid: owner.uid
264
+ };
265
+ named = owner.detail;
266
+ }
267
+ const verdict = await reassignContactOwner({
268
+ hostId,
269
+ contactId: contact.id,
270
+ email,
271
+ assign
272
+ });
273
+ if (verdict.outcome === 'none') {
274
+ return {
275
+ error: OWNER_ASSIGNMENT_REFUSALS[verdict.reason]
276
+ };
277
+ }
278
+ if (verdict.outcome === 'unchanged') {
279
+ return {
280
+ detail: `${named} (already)`
281
+ };
282
+ }
283
+ return {
284
+ detail: step.roundRobin === true ? `round robin → ${verdict.ownerUid}` : named
285
+ };
286
+ }
287
+ // The two record creators: a task and an activity are documents of their
288
+ // own beside the contact, stamped with the scope a contact captured on this
289
+ // site would carry — `crmScopeTokens` is the create path's own expression,
290
+ // so a record an automation made is visible to exactly the sites a record a
291
+ // person made would be.
292
+ if (!env.orgId) return {
293
+ error: 'this site has no organization'
294
+ };
295
+ const orgRef = firebaseAdmin.app().firestore().collection('orgs').doc(env.orgId);
296
+ const visibleTo = crmScopeTokens((_env_org = env.org) != null ? _env_org : null, group);
297
+ const links = _extends({
298
+ contactId: contact.id
299
+ }, facet.companyId ? {
300
+ companyId: facet.companyId
301
+ } : {});
302
+ if (step.type === 'createCrmTask') {
303
+ var _step_title, _facet_ownerUid;
304
+ var _step_assigneeUid, _step_assigneeEmail;
305
+ const title = String((_step_title = step.title) != null ? _step_title : '').trim().slice(0, 200);
306
+ if (!title) return {
307
+ error: 'the task has no title'
308
+ };
309
+ const dueInDays = Math.max(0, Math.round(Number(step.dueInDays) || 0));
310
+ /*
311
+ * The assignee the step names, else the person who OWNS the contact, else
312
+ * nobody. A follow-up task belongs to whoever holds the relationship, and
313
+ * an automation that had to name one person for every contact it touches
314
+ * would assign the whole list to one rep. A named assignee who cannot be
315
+ * resolved is an error rather than a fallback to the owner: the author
316
+ * named somebody on purpose.
317
+ */ let assignee = (_facet_ownerUid = facet.ownerUid) != null ? _facet_ownerUid : '';
318
+ if (((_step_assigneeUid = step.assigneeUid) == null ? void 0 : _step_assigneeUid.trim()) || ((_step_assigneeEmail = step.assigneeEmail) == null ? void 0 : _step_assigneeEmail.trim())) {
319
+ const named = await resolveMemberUid(env.orgId, {
320
+ uid: step.assigneeUid,
321
+ email: step.assigneeEmail
322
+ }, 'assignee');
323
+ if ('error' in named) return {
324
+ error: named.error
325
+ };
326
+ assignee = named.uid;
327
+ }
328
+ const dueAtMs = nowMs + dueInDays * DAY_MS;
329
+ const priority = step.priority === 'high' || step.priority === 'low' ? step.priority : 'normal';
330
+ // The org's labels for the meanings the step names (AGL-3517).
331
+ const labels = crmTaskLabelsForNew(await readCrmTaskPicklists(firebaseAdmin.app().firestore(), env.orgId), {
332
+ kind: step.kind,
333
+ priority
334
+ });
335
+ const task = _extends({
336
+ title,
337
+ kind: step.kind,
338
+ priority,
339
+ status: 'open'
340
+ }, labels, {
341
+ dueAtMs,
342
+ // The reminder a person's task gets (AGL-2659): the due time.
343
+ remindAtMs: crmTaskReminderAfterEdit({
344
+ dueAtMs,
345
+ previous: null
346
+ })
347
+ }, assignee ? {
348
+ assigneeUid: assignee
349
+ } : {}, {
350
+ createdByUid: '',
351
+ sourceActionId: actionId
352
+ }, links, {
353
+ hostId,
354
+ visibleTo,
355
+ createdAt: FieldValue.serverTimestamp(),
356
+ updatedAt: FieldValue.serverTimestamp()
357
+ });
358
+ // What the Tasks list searches by (AGL-3321), beside the task.
359
+ await orgRef.collection(CRM_COLLECTIONS.tasks).add(_extends({}, task, crmTaskListFields(task)));
360
+ // The contact and company the task names carry `nextTaskAtMs` (AGL-2661);
361
+ // a figure that could not move is the Fields section's recompute's.
362
+ await recomputeCrmNextTaskAt(firebaseAdmin.app().firestore(), env.orgId, [
363
+ links
364
+ ]).catch((error)=>{
365
+ console.error('[crm] next activity could not be recomputed', env.orgId, error);
366
+ });
367
+ return {
368
+ detail: title.slice(0, 60)
369
+ };
370
+ }
371
+ if (step.type === 'logCrmActivity') {
372
+ var _step_body;
373
+ const body = String((_step_body = step.body) != null ? _step_body : '').trim().slice(0, 2000);
374
+ if (!body) return {
375
+ error: 'the activity has no body'
376
+ };
377
+ /*
378
+ * The per-record ceiling (AGL-2611), and this step is the writer it exists
379
+ * for: a flow that logs on every page view fills one person's log in an
380
+ * afternoon. Refused into the run history as an error, the way an
381
+ * unresolvable assignee is, so the merchant reads why the flow stopped
382
+ * writing rather than finding a log that silently stopped.
383
+ */ const logged = await countCrmActivitiesForRecord(orgRef, links);
384
+ if (!crmActivityLogHasRoom(logged)) {
385
+ return {
386
+ error: CRM_ACTIVITY_LOG_FULL_MESSAGE
387
+ };
388
+ }
389
+ const direction = crmActivityDirection(step.kind, step.direction);
390
+ const activity = _extends({
391
+ kind: step.kind,
392
+ body
393
+ }, direction ? {
394
+ direction
395
+ } : {}, {
396
+ atMs: nowMs,
397
+ byUid: '',
398
+ sourceActionId: actionId
399
+ }, links, {
400
+ hostId,
401
+ visibleTo,
402
+ createdAt: FieldValue.serverTimestamp(),
403
+ updatedAt: FieldValue.serverTimestamp()
404
+ });
405
+ await orgRef.collection(CRM_COLLECTIONS.activities).add(activity);
406
+ return {
407
+ detail: step.kind
408
+ };
409
+ }
410
+ return {
411
+ error: `unknown CRM step "${step.type}"`
412
+ };
413
+ }
414
+ /**
415
+ * A CRM step on a LEAD (AGL-3458) — the person is not a contact yet, so each
416
+ * step writes the lead's equivalent of what it writes on a contact. See
417
+ * {@link ResolvedPerson}.
418
+ */ async function runLeadStep(env, actionId, step, lead, nowMs) {
419
+ var _env_org;
420
+ const { hostId } = env;
421
+ if (step.type === 'setContactStage') {
422
+ return {
423
+ error: 'the event names a lead, and a lead has no lifecycle stage until it is ' + 'converted to a contact'
424
+ };
425
+ }
426
+ if (step.type === 'addContactTag') {
427
+ var _step_tag;
428
+ const tag = String((_step_tag = step.tag) != null ? _step_tag : '').trim().slice(0, CONTACT_TAG_MAX_LENGTH);
429
+ if (!tag) return {
430
+ error: 'the step has no tag'
431
+ };
432
+ await lead.ref.update({
433
+ tags: FieldValue.arrayUnion(tag),
434
+ updatedAt: FieldValue.serverTimestamp()
435
+ });
436
+ // A lead's tags are what the Leads list searches (AGL-3321).
437
+ await restampCrmListFieldsAt(lead.ref, 'leads');
438
+ return {
439
+ detail: `${tag} (lead)`
440
+ };
441
+ }
442
+ if (step.type === 'assignContactOwner') {
443
+ let assign;
444
+ let named = 'round robin';
445
+ if (step.roundRobin === true) {
446
+ assign = {
447
+ roundRobin: true
448
+ };
449
+ } else {
450
+ const owner = await resolveMemberUid(env.orgId, {
451
+ uid: step.ownerUid,
452
+ email: step.ownerEmail
453
+ }, 'owner');
454
+ if ('error' in owner) return {
455
+ error: owner.error
456
+ };
457
+ assign = {
458
+ memberUid: owner.uid
459
+ };
460
+ named = owner.detail;
461
+ }
462
+ const verdict = await reassignLeadOwner({
463
+ hostId,
464
+ leadId: lead.id,
465
+ assign
466
+ });
467
+ if (verdict.outcome === 'none') {
468
+ return {
469
+ error: OWNER_ASSIGNMENT_REFUSALS[verdict.reason]
470
+ };
471
+ }
472
+ if (verdict.outcome === 'unchanged') return {
473
+ detail: `${named} (already, lead)`
474
+ };
475
+ return {
476
+ detail: step.roundRobin === true ? `round robin → ${verdict.ownerUid} (lead)` : `${named} (lead)`
477
+ };
478
+ }
479
+ if (!env.orgId) return {
480
+ error: 'this site has no organization'
481
+ };
482
+ const orgRef = firebaseAdmin.app().firestore().collection('orgs').doc(env.orgId);
483
+ const group = await consentGroupForSite(hostId);
484
+ const visibleTo = crmScopeTokens((_env_org = env.org) != null ? _env_org : null, group);
485
+ // Filed under the lead, as a sequence's call step files one (AGL-3233); a
486
+ // conversion stamps the contact beside it, and the task follows the person.
487
+ const links = {
488
+ leadId: lead.id
489
+ };
490
+ if (step.type === 'createCrmTask') {
491
+ var _step_title;
492
+ var _step_assigneeUid, _step_assigneeEmail;
493
+ const title = String((_step_title = step.title) != null ? _step_title : '').trim().slice(0, 200);
494
+ if (!title) return {
495
+ error: 'the task has no title'
496
+ };
497
+ const dueInDays = Math.max(0, Math.round(Number(step.dueInDays) || 0));
498
+ // The named assignee, else whoever owns the lead NOW — an owner step
499
+ // earlier in this same run wrote the lead after it was resolved, so it
500
+ // is read again — else nobody.
501
+ let assignee;
502
+ if (((_step_assigneeUid = step.assigneeUid) == null ? void 0 : _step_assigneeUid.trim()) || ((_step_assigneeEmail = step.assigneeEmail) == null ? void 0 : _step_assigneeEmail.trim())) {
503
+ const named = await resolveMemberUid(env.orgId, {
504
+ uid: step.assigneeUid,
505
+ email: step.assigneeEmail
506
+ }, 'assignee');
507
+ if ('error' in named) return {
508
+ error: named.error
509
+ };
510
+ assignee = named.uid;
511
+ } else {
512
+ var _ownerUid, _fresh_data;
513
+ const fresh = await lead.ref.get();
514
+ assignee = String((_ownerUid = ((_fresh_data = fresh.data()) != null ? _fresh_data : lead.data)['ownerUid']) != null ? _ownerUid : '');
515
+ }
516
+ const dueAtMs = nowMs + dueInDays * DAY_MS;
517
+ const task = _extends({
518
+ title,
519
+ kind: step.kind,
520
+ priority: 'normal',
521
+ status: 'open',
522
+ dueAtMs,
523
+ remindAtMs: crmTaskReminderAfterEdit({
524
+ dueAtMs,
525
+ previous: null
526
+ })
527
+ }, assignee ? {
528
+ assigneeUid: assignee
529
+ } : {}, {
530
+ createdByUid: '',
531
+ sourceActionId: actionId
532
+ }, links, {
533
+ hostId,
534
+ visibleTo,
535
+ createdAt: FieldValue.serverTimestamp(),
536
+ updatedAt: FieldValue.serverTimestamp()
537
+ });
538
+ await orgRef.collection(CRM_COLLECTIONS.tasks).doc(createResourceUid()).set(_extends({}, task, crmTaskListFields(task)));
539
+ return {
540
+ detail: `${title.slice(0, 60)} (lead)`
541
+ };
542
+ }
543
+ if (step.type === 'logCrmActivity') {
544
+ var _step_body;
545
+ const body = String((_step_body = step.body) != null ? _step_body : '').trim().slice(0, 2000);
546
+ if (!body) return {
547
+ error: 'the activity has no body'
548
+ };
549
+ if (!crmActivityLogHasRoom(await countCrmActivitiesForRecord(orgRef, links))) {
550
+ return {
551
+ error: CRM_ACTIVITY_LOG_FULL_MESSAGE
552
+ };
553
+ }
554
+ const activity = _extends({
555
+ kind: step.kind,
556
+ body,
557
+ atMs: nowMs,
558
+ byUid: '',
559
+ sourceActionId: actionId
560
+ }, links, {
561
+ hostId,
562
+ visibleTo,
563
+ createdAt: FieldValue.serverTimestamp(),
564
+ updatedAt: FieldValue.serverTimestamp()
565
+ });
566
+ await orgRef.collection(CRM_COLLECTIONS.activities).doc(createResourceUid()).set(activity);
567
+ return {
568
+ detail: `${step.kind} (lead)`
569
+ };
570
+ }
571
+ return {
572
+ error: `unknown CRM step "${step.type}"`
573
+ };
574
+ }
575
+ /**
576
+ * Whether — and where — an email a plugin is about to send lands on a
577
+ * timeline: the CRM's answer to the record timeline's `prepareEmail`.
578
+ *
579
+ * An automation's `sendEmail` step is not a CRM step: it mails whatever
580
+ * address the event carries, to a person who may be nobody the CRM knows. It
581
+ * earns a row on exactly one condition, that the message is ADDRESSED TO THE
582
+ * PERSON the sender means — a contact, else the lead a lead-routed form filed
583
+ * (AGL-3458), whose row lands on the lead's timeline — the person the request's link finds, at the
584
+ * address the row holds. A welcome sequence to a new contact is that; an
585
+ * internal alert routed to a merchant's own address through `toField` is not,
586
+ * and a row for it would put the merchant's inbox on a customer's history.
587
+ *
588
+ * Prepared ahead of the send, for the reason the console route mints its id
589
+ * first: the delivery webhook has nothing but the tags on the message to find
590
+ * the row with. Nothing is written until `file` is called, once the provider
591
+ * accepted the message. A workspace whose plan does not carry the CRM, a
592
+ * record at the activity ceiling and a site with no org earn no row — the
593
+ * message still goes, because the ceiling bounds the log and not the mail.
594
+ *
595
+ * **Never throws**, and neither does `file`. The row is bookkeeping beside a
596
+ * send, and a lookup that fails must not become a message that never left —
597
+ * the posture every meter beside a send takes. A failure is logged and the
598
+ * message goes out untagged.
599
+ */ export async function prepareCrmRecordEmail(request) {
600
+ var _request_orgId, _request_hostId;
601
+ const orgId = String((_request_orgId = request.orgId) != null ? _request_orgId : '').trim();
602
+ const hostId = String((_request_hostId = request.hostId) != null ? _request_hostId : '').trim();
603
+ if (!orgId || !hostId) return null;
604
+ const address = normalizeContactEmail(request.to);
605
+ if (!address) return null;
606
+ try {
607
+ var _data;
608
+ const firestore = firebaseAdmin.app().firestore();
609
+ const orgRef = firestore.collection('orgs').doc(orgId);
610
+ // The org the caller already read, or the one read here once.
611
+ const org = request.org !== undefined ? request.org : (_data = (await orgRef.get()).data()) != null ? _data : null;
612
+ if (!checkEntitlement(org, CRM_SUITE_FEATURE)) {
613
+ return null;
614
+ }
615
+ const person = await resolveEventPerson(hostId, request.link);
616
+ if (!person || normalizeContactEmail(person.data['email']) !== address) {
617
+ return null;
618
+ }
619
+ const group = await consentGroupForSite(hostId);
620
+ const facet = person.kind === 'contact' ? readContactFacet(person.data, group.groupId) : null;
621
+ const link = person.kind === 'lead' ? {
622
+ leadId: person.id
623
+ } : _extends({
624
+ contactId: person.id
625
+ }, (facet == null ? void 0 : facet.companyId) ? {
626
+ companyId: facet.companyId
627
+ } : {});
628
+ if (!crmActivityLogHasRoom(await countCrmActivitiesForRecord(orgRef, link))) {
629
+ return null;
630
+ }
631
+ const ref = newCrmActivityRef(firestore, orgId);
632
+ const visibleTo = crmScopeTokens(org != null ? org : null, group);
633
+ return {
634
+ tags: crmEmailDeliveryTags({
635
+ orgId,
636
+ hostId,
637
+ activityId: ref.id
638
+ }),
639
+ /*
640
+ * The same shape the console route logs — `buildCrmEmailActivity` is the
641
+ * one builder — with the sender's id as its source and nobody as its
642
+ * author. Never throws: the message has left, and a row that could not
643
+ * be written is a gap on the timeline rather than a failed send.
644
+ */ async file (sent) {
645
+ try {
646
+ var _normalizeContactEmail, _sent_atMs;
647
+ await writeCrmEmailActivity(ref, buildCrmEmailActivity({
648
+ subject: sent.subject,
649
+ body: sent.body,
650
+ to: (_normalizeContactEmail = normalizeContactEmail(sent.to)) != null ? _normalizeContactEmail : sent.to,
651
+ atMs: (_sent_atMs = sent.atMs) != null ? _sent_atMs : Date.now(),
652
+ byUid: '',
653
+ sourceActionId: sent.sourceRef,
654
+ link,
655
+ hostId,
656
+ visibleTo
657
+ }));
658
+ } catch (error) {
659
+ console.error('[crm] automation email activity write failed', ref.id, error);
660
+ }
661
+ }
662
+ };
663
+ } catch (error) {
664
+ console.error('[crm] automation email activity could not be prepared', hostId, error);
665
+ return null;
666
+ }
667
+ }
668
+
669
+ //# sourceMappingURL=automation-steps.js.map