@aglyn/plugins-crm 1.0.0-beta.143

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 (669) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +57 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +29 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/activity-list.d.ts +98 -0
  8. package/src/lib/components/activity-list.js +321 -0
  9. package/src/lib/components/activity-list.js.map +1 -0
  10. package/src/lib/components/activity-queries.d.ts +117 -0
  11. package/src/lib/components/activity-queries.js +198 -0
  12. package/src/lib/components/activity-queries.js.map +1 -0
  13. package/src/lib/components/add-to-list-button.d.ts +25 -0
  14. package/src/lib/components/add-to-list-button.js +64 -0
  15. package/src/lib/components/add-to-list-button.js.map +1 -0
  16. package/src/lib/components/add-to-list-dialog.d.ts +24 -0
  17. package/src/lib/components/add-to-list-dialog.js +327 -0
  18. package/src/lib/components/add-to-list-dialog.js.map +1 -0
  19. package/src/lib/components/assignment-rule-drawer.d.ts +43 -0
  20. package/src/lib/components/assignment-rule-drawer.js +293 -0
  21. package/src/lib/components/assignment-rule-drawer.js.map +1 -0
  22. package/src/lib/components/companies-bulk-bar.d.ts +29 -0
  23. package/src/lib/components/companies-bulk-bar.js +274 -0
  24. package/src/lib/components/companies-bulk-bar.js.map +1 -0
  25. package/src/lib/components/companies-section.d.ts +54 -0
  26. package/src/lib/components/companies-section.js +522 -0
  27. package/src/lib/components/companies-section.js.map +1 -0
  28. package/src/lib/components/company-contacts-card.d.ts +49 -0
  29. package/src/lib/components/company-contacts-card.js +435 -0
  30. package/src/lib/components/company-contacts-card.js.map +1 -0
  31. package/src/lib/components/company-deals-card.d.ts +20 -0
  32. package/src/lib/components/company-deals-card.js +38 -0
  33. package/src/lib/components/company-deals-card.js.map +1 -0
  34. package/src/lib/components/company-detail-page.d.ts +20 -0
  35. package/src/lib/components/company-detail-page.js +165 -0
  36. package/src/lib/components/company-detail-page.js.map +1 -0
  37. package/src/lib/components/company-edit-drawer.d.ts +65 -0
  38. package/src/lib/components/company-edit-drawer.js +433 -0
  39. package/src/lib/components/company-edit-drawer.js.map +1 -0
  40. package/src/lib/components/company-import-drawer.d.ts +42 -0
  41. package/src/lib/components/company-import-drawer.js +99 -0
  42. package/src/lib/components/company-import-drawer.js.map +1 -0
  43. package/src/lib/components/company-picker.d.ts +127 -0
  44. package/src/lib/components/company-picker.js +323 -0
  45. package/src/lib/components/company-picker.js.map +1 -0
  46. package/src/lib/components/company-properties-card.d.ts +47 -0
  47. package/src/lib/components/company-properties-card.js +289 -0
  48. package/src/lib/components/company-properties-card.js.map +1 -0
  49. package/src/lib/components/contact-address-fields.d.ts +29 -0
  50. package/src/lib/components/contact-address-fields.js +149 -0
  51. package/src/lib/components/contact-address-fields.js.map +1 -0
  52. package/src/lib/components/contact-associations-card.d.ts +72 -0
  53. package/src/lib/components/contact-associations-card.js +296 -0
  54. package/src/lib/components/contact-associations-card.js.map +1 -0
  55. package/src/lib/components/contact-custom-columns.d.ts +38 -0
  56. package/src/lib/components/contact-custom-columns.js +102 -0
  57. package/src/lib/components/contact-custom-columns.js.map +1 -0
  58. package/src/lib/components/contact-custom-fields-card.d.ts +39 -0
  59. package/src/lib/components/contact-custom-fields-card.js +204 -0
  60. package/src/lib/components/contact-custom-fields-card.js.map +1 -0
  61. package/src/lib/components/contact-deals-card.d.ts +20 -0
  62. package/src/lib/components/contact-deals-card.js +38 -0
  63. package/src/lib/components/contact-deals-card.js.map +1 -0
  64. package/src/lib/components/contact-detail-page.d.ts +46 -0
  65. package/src/lib/components/contact-detail-page.js +535 -0
  66. package/src/lib/components/contact-detail-page.js.map +1 -0
  67. package/src/lib/components/contact-duplicates-card.d.ts +42 -0
  68. package/src/lib/components/contact-duplicates-card.js +167 -0
  69. package/src/lib/components/contact-duplicates-card.js.map +1 -0
  70. package/src/lib/components/contact-field-drawer.d.ts +64 -0
  71. package/src/lib/components/contact-field-drawer.js +251 -0
  72. package/src/lib/components/contact-field-drawer.js.map +1 -0
  73. package/src/lib/components/contact-import-drawer.d.ts +46 -0
  74. package/src/lib/components/contact-import-drawer.js +149 -0
  75. package/src/lib/components/contact-import-drawer.js.map +1 -0
  76. package/src/lib/components/contact-known-by-card.d.ts +39 -0
  77. package/src/lib/components/contact-known-by-card.js +142 -0
  78. package/src/lib/components/contact-known-by-card.js.map +1 -0
  79. package/src/lib/components/contact-list-columns.d.ts +53 -0
  80. package/src/lib/components/contact-list-columns.js +288 -0
  81. package/src/lib/components/contact-list-columns.js.map +1 -0
  82. package/src/lib/components/contact-merge-dialog.d.ts +79 -0
  83. package/src/lib/components/contact-merge-dialog.js +405 -0
  84. package/src/lib/components/contact-merge-dialog.js.map +1 -0
  85. package/src/lib/components/contact-properties-card.d.ts +89 -0
  86. package/src/lib/components/contact-properties-card.js +492 -0
  87. package/src/lib/components/contact-properties-card.js.map +1 -0
  88. package/src/lib/components/contact-timeline-card.d.ts +68 -0
  89. package/src/lib/components/contact-timeline-card.js +435 -0
  90. package/src/lib/components/contact-timeline-card.js.map +1 -0
  91. package/src/lib/components/contacts-bulk-bar.d.ts +91 -0
  92. package/src/lib/components/contacts-bulk-bar.js +493 -0
  93. package/src/lib/components/contacts-bulk-bar.js.map +1 -0
  94. package/src/lib/components/contacts-section.d.ts +26 -0
  95. package/src/lib/components/contacts-section.js +1025 -0
  96. package/src/lib/components/contacts-section.js.map +1 -0
  97. package/src/lib/components/copy-capture-address-button.d.ts +33 -0
  98. package/src/lib/components/copy-capture-address-button.js +60 -0
  99. package/src/lib/components/copy-capture-address-button.js.map +1 -0
  100. package/src/lib/components/crm-attribution-zone.d.ts +38 -0
  101. package/src/lib/components/crm-attribution-zone.js +36 -0
  102. package/src/lib/components/crm-attribution-zone.js.map +1 -0
  103. package/src/lib/components/crm-booking-zone.d.ts +61 -0
  104. package/src/lib/components/crm-booking-zone.js +50 -0
  105. package/src/lib/components/crm-booking-zone.js.map +1 -0
  106. package/src/lib/components/crm-bulk-bar-frame.d.ts +47 -0
  107. package/src/lib/components/crm-bulk-bar-frame.js +137 -0
  108. package/src/lib/components/crm-bulk-bar-frame.js.map +1 -0
  109. package/src/lib/components/crm-call-actions.d.ts +65 -0
  110. package/src/lib/components/crm-call-actions.js +110 -0
  111. package/src/lib/components/crm-call-actions.js.map +1 -0
  112. package/src/lib/components/crm-column-menu.d.ts +21 -0
  113. package/src/lib/components/crm-column-menu.js +103 -0
  114. package/src/lib/components/crm-column-menu.js.map +1 -0
  115. package/src/lib/components/crm-console-page.d.ts +19 -0
  116. package/src/lib/components/crm-console-page.js +151 -0
  117. package/src/lib/components/crm-console-page.js.map +1 -0
  118. package/src/lib/components/crm-console-sections.d.ts +52 -0
  119. package/src/lib/components/crm-console-sections.js +83 -0
  120. package/src/lib/components/crm-console-sections.js.map +1 -0
  121. package/src/lib/components/crm-custom-field-control.d.ts +26 -0
  122. package/src/lib/components/crm-custom-field-control.js +131 -0
  123. package/src/lib/components/crm-custom-field-control.js.map +1 -0
  124. package/src/lib/components/crm-email-template-tools.d.ts +69 -0
  125. package/src/lib/components/crm-email-template-tools.js +240 -0
  126. package/src/lib/components/crm-email-template-tools.js.map +1 -0
  127. package/src/lib/components/crm-export-all-button.d.ts +39 -0
  128. package/src/lib/components/crm-export-all-button.js +98 -0
  129. package/src/lib/components/crm-export-all-button.js.map +1 -0
  130. package/src/lib/components/crm-filter-bar.d.ts +53 -0
  131. package/src/lib/components/crm-filter-bar.js +294 -0
  132. package/src/lib/components/crm-filter-bar.js.map +1 -0
  133. package/src/lib/components/crm-glance-card.d.ts +54 -0
  134. package/src/lib/components/crm-glance-card.js +219 -0
  135. package/src/lib/components/crm-glance-card.js.map +1 -0
  136. package/src/lib/components/crm-next-activity-column.d.ts +35 -0
  137. package/src/lib/components/crm-next-activity-column.js +100 -0
  138. package/src/lib/components/crm-next-activity-column.js.map +1 -0
  139. package/src/lib/components/crm-record-header.d.ts +97 -0
  140. package/src/lib/components/crm-record-header.js +160 -0
  141. package/src/lib/components/crm-record-header.js.map +1 -0
  142. package/src/lib/components/crm-record-insights-zone.d.ts +50 -0
  143. package/src/lib/components/crm-record-insights-zone.js +169 -0
  144. package/src/lib/components/crm-record-insights-zone.js.map +1 -0
  145. package/src/lib/components/crm-record-picker.d.ts +42 -0
  146. package/src/lib/components/crm-record-picker.js +104 -0
  147. package/src/lib/components/crm-record-picker.js.map +1 -0
  148. package/src/lib/components/crm-send-email-button.d.ts +39 -0
  149. package/src/lib/components/crm-send-email-button.js +81 -0
  150. package/src/lib/components/crm-send-email-button.js.map +1 -0
  151. package/src/lib/components/crm-send-email-dialog.d.ts +61 -0
  152. package/src/lib/components/crm-send-email-dialog.js +851 -0
  153. package/src/lib/components/crm-send-email-dialog.js.map +1 -0
  154. package/src/lib/components/crm-site-picker.d.ts +61 -0
  155. package/src/lib/components/crm-site-picker.js +99 -0
  156. package/src/lib/components/crm-site-picker.js.map +1 -0
  157. package/src/lib/components/crm-suite-lock.d.ts +29 -0
  158. package/src/lib/components/crm-suite-lock.js +114 -0
  159. package/src/lib/components/crm-suite-lock.js.map +1 -0
  160. package/src/lib/components/crm-tasks-due-card.d.ts +42 -0
  161. package/src/lib/components/crm-tasks-due-card.js +225 -0
  162. package/src/lib/components/crm-tasks-due-card.js.map +1 -0
  163. package/src/lib/components/crm-views-control.d.ts +65 -0
  164. package/src/lib/components/crm-views-control.js +518 -0
  165. package/src/lib/components/crm-views-control.js.map +1 -0
  166. package/src/lib/components/csv-import-drawer.d.ts +132 -0
  167. package/src/lib/components/csv-import-drawer.js +746 -0
  168. package/src/lib/components/csv-import-drawer.js.map +1 -0
  169. package/src/lib/components/deal-board.d.ts +70 -0
  170. package/src/lib/components/deal-board.js +478 -0
  171. package/src/lib/components/deal-board.js.map +1 -0
  172. package/src/lib/components/deal-detail-page.d.ts +18 -0
  173. package/src/lib/components/deal-detail-page.js +323 -0
  174. package/src/lib/components/deal-detail-page.js.map +1 -0
  175. package/src/lib/components/deal-edit-drawer.d.ts +59 -0
  176. package/src/lib/components/deal-edit-drawer.js +640 -0
  177. package/src/lib/components/deal-edit-drawer.js.map +1 -0
  178. package/src/lib/components/deal-import-drawer.d.ts +24 -0
  179. package/src/lib/components/deal-import-drawer.js +83 -0
  180. package/src/lib/components/deal-import-drawer.js.map +1 -0
  181. package/src/lib/components/deal-products-card.d.ts +48 -0
  182. package/src/lib/components/deal-products-card.js +614 -0
  183. package/src/lib/components/deal-products-card.js.map +1 -0
  184. package/src/lib/components/deal-properties-card.d.ts +29 -0
  185. package/src/lib/components/deal-properties-card.js +144 -0
  186. package/src/lib/components/deal-properties-card.js.map +1 -0
  187. package/src/lib/components/deal-stage-card.d.ts +24 -0
  188. package/src/lib/components/deal-stage-card.js +199 -0
  189. package/src/lib/components/deal-stage-card.js.map +1 -0
  190. package/src/lib/components/deals-bulk-bar.d.ts +31 -0
  191. package/src/lib/components/deals-bulk-bar.js +340 -0
  192. package/src/lib/components/deals-bulk-bar.js.map +1 -0
  193. package/src/lib/components/deals-section.d.ts +49 -0
  194. package/src/lib/components/deals-section.js +767 -0
  195. package/src/lib/components/deals-section.js.map +1 -0
  196. package/src/lib/components/email-capture-card.d.ts +42 -0
  197. package/src/lib/components/email-capture-card.js +134 -0
  198. package/src/lib/components/email-capture-card.js.map +1 -0
  199. package/src/lib/components/email-template-drawer.d.ts +33 -0
  200. package/src/lib/components/email-template-drawer.js +209 -0
  201. package/src/lib/components/email-template-drawer.js.map +1 -0
  202. package/src/lib/components/email-templates-card.d.ts +33 -0
  203. package/src/lib/components/email-templates-card.js +370 -0
  204. package/src/lib/components/email-templates-card.js.map +1 -0
  205. package/src/lib/components/erase-person-action.d.ts +92 -0
  206. package/src/lib/components/erase-person-action.js +261 -0
  207. package/src/lib/components/erase-person-action.js.map +1 -0
  208. package/src/lib/components/fields-section.d.ts +37 -0
  209. package/src/lib/components/fields-section.js +641 -0
  210. package/src/lib/components/fields-section.js.map +1 -0
  211. package/src/lib/components/form-contact-fields-card.d.ts +46 -0
  212. package/src/lib/components/form-contact-fields-card.js +253 -0
  213. package/src/lib/components/form-contact-fields-card.js.map +1 -0
  214. package/src/lib/components/insert-link-at-caret.d.ts +28 -0
  215. package/src/lib/components/insert-link-at-caret.js +37 -0
  216. package/src/lib/components/insert-link-at-caret.js.map +1 -0
  217. package/src/lib/components/lead-convert-dialog.d.ts +32 -0
  218. package/src/lib/components/lead-convert-dialog.js +493 -0
  219. package/src/lib/components/lead-convert-dialog.js.map +1 -0
  220. package/src/lib/components/lead-detail-page.d.ts +16 -0
  221. package/src/lib/components/lead-detail-page.js +163 -0
  222. package/src/lib/components/lead-detail-page.js.map +1 -0
  223. package/src/lib/components/lead-history-card.d.ts +32 -0
  224. package/src/lib/components/lead-history-card.js +165 -0
  225. package/src/lib/components/lead-history-card.js.map +1 -0
  226. package/src/lib/components/lead-import-drawer.d.ts +24 -0
  227. package/src/lib/components/lead-import-drawer.js +95 -0
  228. package/src/lib/components/lead-import-drawer.js.map +1 -0
  229. package/src/lib/components/lead-owner-select.d.ts +35 -0
  230. package/src/lib/components/lead-owner-select.js +91 -0
  231. package/src/lib/components/lead-owner-select.js.map +1 -0
  232. package/src/lib/components/lead-properties-card.d.ts +61 -0
  233. package/src/lib/components/lead-properties-card.js +395 -0
  234. package/src/lib/components/lead-properties-card.js.map +1 -0
  235. package/src/lib/components/lead-status-chip.d.ts +12 -0
  236. package/src/lib/components/lead-status-chip.js +43 -0
  237. package/src/lib/components/lead-status-chip.js.map +1 -0
  238. package/src/lib/components/lead-surfaces-note.d.ts +126 -0
  239. package/src/lib/components/lead-surfaces-note.js +262 -0
  240. package/src/lib/components/lead-surfaces-note.js.map +1 -0
  241. package/src/lib/components/lead-unqualify-dialog.d.ts +24 -0
  242. package/src/lib/components/lead-unqualify-dialog.js +125 -0
  243. package/src/lib/components/lead-unqualify-dialog.js.map +1 -0
  244. package/src/lib/components/leads-bulk-bar.d.ts +58 -0
  245. package/src/lib/components/leads-bulk-bar.js +307 -0
  246. package/src/lib/components/leads-bulk-bar.js.map +1 -0
  247. package/src/lib/components/leads-section.d.ts +23 -0
  248. package/src/lib/components/leads-section.js +664 -0
  249. package/src/lib/components/leads-section.js.map +1 -0
  250. package/src/lib/components/linked-deals-card.d.ts +32 -0
  251. package/src/lib/components/linked-deals-card.js +163 -0
  252. package/src/lib/components/linked-deals-card.js.map +1 -0
  253. package/src/lib/components/log-activity-dialog.d.ts +60 -0
  254. package/src/lib/components/log-activity-dialog.js +368 -0
  255. package/src/lib/components/log-activity-dialog.js.map +1 -0
  256. package/src/lib/components/lost-reason-dialog.d.ts +26 -0
  257. package/src/lib/components/lost-reason-dialog.js +95 -0
  258. package/src/lib/components/lost-reason-dialog.js.map +1 -0
  259. package/src/lib/components/new-contact-drawer.d.ts +78 -0
  260. package/src/lib/components/new-contact-drawer.js +343 -0
  261. package/src/lib/components/new-contact-drawer.js.map +1 -0
  262. package/src/lib/components/org-lead-surfaces-note.d.ts +57 -0
  263. package/src/lib/components/org-lead-surfaces-note.js +172 -0
  264. package/src/lib/components/org-lead-surfaces-note.js.map +1 -0
  265. package/src/lib/components/owner-avatar.d.ts +18 -0
  266. package/src/lib/components/owner-avatar.js +61 -0
  267. package/src/lib/components/owner-avatar.js.map +1 -0
  268. package/src/lib/components/pipeline-stages-dialog.d.ts +43 -0
  269. package/src/lib/components/pipeline-stages-dialog.js +339 -0
  270. package/src/lib/components/pipeline-stages-dialog.js.map +1 -0
  271. package/src/lib/components/pipelines-dialog.d.ts +55 -0
  272. package/src/lib/components/pipelines-dialog.js +517 -0
  273. package/src/lib/components/pipelines-dialog.js.map +1 -0
  274. package/src/lib/components/recent-activity-feed.d.ts +39 -0
  275. package/src/lib/components/recent-activity-feed.js +103 -0
  276. package/src/lib/components/recent-activity-feed.js.map +1 -0
  277. package/src/lib/components/recipes-card.d.ts +39 -0
  278. package/src/lib/components/recipes-card.js +485 -0
  279. package/src/lib/components/recipes-card.js.map +1 -0
  280. package/src/lib/components/record-activity-card.d.ts +26 -0
  281. package/src/lib/components/record-activity-card.js +121 -0
  282. package/src/lib/components/record-activity-card.js.map +1 -0
  283. package/src/lib/components/record-files-card.d.ts +67 -0
  284. package/src/lib/components/record-files-card.js +290 -0
  285. package/src/lib/components/record-files-card.js.map +1 -0
  286. package/src/lib/components/record-tasks-card.d.ts +32 -0
  287. package/src/lib/components/record-tasks-card.js +306 -0
  288. package/src/lib/components/record-tasks-card.js.map +1 -0
  289. package/src/lib/components/reports/activity-card.d.ts +57 -0
  290. package/src/lib/components/reports/activity-card.js +281 -0
  291. package/src/lib/components/reports/activity-card.js.map +1 -0
  292. package/src/lib/components/reports/closed-deals-card.d.ts +20 -0
  293. package/src/lib/components/reports/closed-deals-card.js +194 -0
  294. package/src/lib/components/reports/closed-deals-card.js.map +1 -0
  295. package/src/lib/components/reports/contacts-mix-card.d.ts +27 -0
  296. package/src/lib/components/reports/contacts-mix-card.js +161 -0
  297. package/src/lib/components/reports/contacts-mix-card.js.map +1 -0
  298. package/src/lib/components/reports/contacts-trend-card.d.ts +31 -0
  299. package/src/lib/components/reports/contacts-trend-card.js +144 -0
  300. package/src/lib/components/reports/contacts-trend-card.js.map +1 -0
  301. package/src/lib/components/reports/forecast-card.d.ts +22 -0
  302. package/src/lib/components/reports/forecast-card.js +251 -0
  303. package/src/lib/components/reports/forecast-card.js.map +1 -0
  304. package/src/lib/components/reports/lead-counts.d.ts +32 -0
  305. package/src/lib/components/reports/lead-counts.js +44 -0
  306. package/src/lib/components/reports/lead-counts.js.map +1 -0
  307. package/src/lib/components/reports/lead-funnel-card.d.ts +38 -0
  308. package/src/lib/components/reports/lead-funnel-card.js +375 -0
  309. package/src/lib/components/reports/lead-funnel-card.js.map +1 -0
  310. package/src/lib/components/reports/pipeline-card.d.ts +19 -0
  311. package/src/lib/components/reports/pipeline-card.js +338 -0
  312. package/src/lib/components/reports/pipeline-card.js.map +1 -0
  313. package/src/lib/components/reports/report-bar-chart.d.ts +39 -0
  314. package/src/lib/components/reports/report-bar-chart.js +133 -0
  315. package/src/lib/components/reports/report-bar-chart.js.map +1 -0
  316. package/src/lib/components/reports/report-breakdown.d.ts +32 -0
  317. package/src/lib/components/reports/report-breakdown.js +105 -0
  318. package/src/lib/components/reports/report-breakdown.js.map +1 -0
  319. package/src/lib/components/reports/report-export.d.ts +37 -0
  320. package/src/lib/components/reports/report-export.js +66 -0
  321. package/src/lib/components/reports/report-export.js.map +1 -0
  322. package/src/lib/components/reports/report-format.d.ts +36 -0
  323. package/src/lib/components/reports/report-format.js +43 -0
  324. package/src/lib/components/reports/report-format.js.map +1 -0
  325. package/src/lib/components/reports/report-scope.d.ts +81 -0
  326. package/src/lib/components/reports/report-scope.js +58 -0
  327. package/src/lib/components/reports/report-scope.js.map +1 -0
  328. package/src/lib/components/reports/report-stat-tile.d.ts +47 -0
  329. package/src/lib/components/reports/report-stat-tile.js +96 -0
  330. package/src/lib/components/reports/report-stat-tile.js.map +1 -0
  331. package/src/lib/components/reports/source-conversion-card.d.ts +28 -0
  332. package/src/lib/components/reports/source-conversion-card.js +205 -0
  333. package/src/lib/components/reports/source-conversion-card.js.map +1 -0
  334. package/src/lib/components/reports/tasks-card.d.ts +26 -0
  335. package/src/lib/components/reports/tasks-card.js +279 -0
  336. package/src/lib/components/reports/tasks-card.js.map +1 -0
  337. package/src/lib/components/reports/use-aggregate-read.d.ts +99 -0
  338. package/src/lib/components/reports/use-aggregate-read.js +195 -0
  339. package/src/lib/components/reports/use-aggregate-read.js.map +1 -0
  340. package/src/lib/components/reports/won-lost-by-owner-card.d.ts +30 -0
  341. package/src/lib/components/reports/won-lost-by-owner-card.js +168 -0
  342. package/src/lib/components/reports/won-lost-by-owner-card.js.map +1 -0
  343. package/src/lib/components/reports-section.d.ts +42 -0
  344. package/src/lib/components/reports-section.js +308 -0
  345. package/src/lib/components/reports-section.js.map +1 -0
  346. package/src/lib/components/sending-addresses-card.d.ts +49 -0
  347. package/src/lib/components/sending-addresses-card.js +262 -0
  348. package/src/lib/components/sending-addresses-card.js.map +1 -0
  349. package/src/lib/components/settings-section.d.ts +151 -0
  350. package/src/lib/components/settings-section.js +783 -0
  351. package/src/lib/components/settings-section.js.map +1 -0
  352. package/src/lib/components/task-cells.d.ts +51 -0
  353. package/src/lib/components/task-cells.js +139 -0
  354. package/src/lib/components/task-cells.js.map +1 -0
  355. package/src/lib/components/task-edit-drawer.d.ts +53 -0
  356. package/src/lib/components/task-edit-drawer.js +483 -0
  357. package/src/lib/components/task-edit-drawer.js.map +1 -0
  358. package/src/lib/components/task-import-drawer.d.ts +24 -0
  359. package/src/lib/components/task-import-drawer.js +82 -0
  360. package/src/lib/components/task-import-drawer.js.map +1 -0
  361. package/src/lib/components/task-snooze-menu.d.ts +65 -0
  362. package/src/lib/components/task-snooze-menu.js +207 -0
  363. package/src/lib/components/task-snooze-menu.js.map +1 -0
  364. package/src/lib/components/tasks-bulk-bar.d.ts +25 -0
  365. package/src/lib/components/tasks-bulk-bar.js +348 -0
  366. package/src/lib/components/tasks-bulk-bar.js.map +1 -0
  367. package/src/lib/components/tasks-calendar.d.ts +38 -0
  368. package/src/lib/components/tasks-calendar.js +228 -0
  369. package/src/lib/components/tasks-calendar.js.map +1 -0
  370. package/src/lib/components/tasks-section.d.ts +27 -0
  371. package/src/lib/components/tasks-section.js +579 -0
  372. package/src/lib/components/tasks-section.js.map +1 -0
  373. package/src/lib/components/use-contact-campaign-emails.d.ts +32 -0
  374. package/src/lib/components/use-contact-campaign-emails.js +83 -0
  375. package/src/lib/components/use-contact-campaign-emails.js.map +1 -0
  376. package/src/lib/components/use-crm-api.d.ts +44 -0
  377. package/src/lib/components/use-crm-api.js +84 -0
  378. package/src/lib/components/use-crm-api.js.map +1 -0
  379. package/src/lib/components/use-crm-inbound-address.d.ts +60 -0
  380. package/src/lib/components/use-crm-inbound-address.js +124 -0
  381. package/src/lib/components/use-crm-inbound-address.js.map +1 -0
  382. package/src/lib/components/use-emails-hub-path.d.ts +24 -0
  383. package/src/lib/components/use-emails-hub-path.js +59 -0
  384. package/src/lib/components/use-emails-hub-path.js.map +1 -0
  385. package/src/lib/components/use-member-email-aliases.d.ts +54 -0
  386. package/src/lib/components/use-member-email-aliases.js +186 -0
  387. package/src/lib/components/use-member-email-aliases.js.map +1 -0
  388. package/src/lib/components/use-org-members.d.ts +40 -0
  389. package/src/lib/components/use-org-members.js +100 -0
  390. package/src/lib/components/use-org-members.js.map +1 -0
  391. package/src/lib/constants/api-routes.d.ts +109 -0
  392. package/src/lib/constants/api-routes.js +74 -0
  393. package/src/lib/constants/api-routes.js.map +1 -0
  394. package/src/lib/constants/bundle-common.d.ts +14 -0
  395. package/src/lib/constants/bundle-common.js +14 -0
  396. package/src/lib/constants/bundle-common.js.map +1 -0
  397. package/src/lib/constants/company-filters.d.ts +18 -0
  398. package/src/lib/constants/company-filters.js +51 -0
  399. package/src/lib/constants/company-filters.js.map +1 -0
  400. package/src/lib/constants/contact-filters.d.ts +38 -0
  401. package/src/lib/constants/contact-filters.js +294 -0
  402. package/src/lib/constants/contact-filters.js.map +1 -0
  403. package/src/lib/hooks/use-contact-field-definitions.d.ts +48 -0
  404. package/src/lib/hooks/use-contact-field-definitions.js +72 -0
  405. package/src/lib/hooks/use-contact-field-definitions.js.map +1 -0
  406. package/src/lib/hooks/use-contact-update.d.ts +25 -0
  407. package/src/lib/hooks/use-contact-update.js +80 -0
  408. package/src/lib/hooks/use-contact-update.js.map +1 -0
  409. package/src/lib/hooks/use-crm-activity-logger.d.ts +73 -0
  410. package/src/lib/hooks/use-crm-activity-logger.js +101 -0
  411. package/src/lib/hooks/use-crm-activity-logger.js.map +1 -0
  412. package/src/lib/hooks/use-crm-bulk-apply.d.ts +52 -0
  413. package/src/lib/hooks/use-crm-bulk-apply.js +112 -0
  414. package/src/lib/hooks/use-crm-bulk-apply.js.map +1 -0
  415. package/src/lib/hooks/use-crm-default-view.d.ts +24 -0
  416. package/src/lib/hooks/use-crm-default-view.js +64 -0
  417. package/src/lib/hooks/use-crm-default-view.js.map +1 -0
  418. package/src/lib/hooks/use-crm-email-templates.d.ts +59 -0
  419. package/src/lib/hooks/use-crm-email-templates.js +103 -0
  420. package/src/lib/hooks/use-crm-email-templates.js.map +1 -0
  421. package/src/lib/hooks/use-crm-hub-path.d.ts +29 -0
  422. package/src/lib/hooks/use-crm-hub-path.js +41 -0
  423. package/src/lib/hooks/use-crm-hub-path.js.map +1 -0
  424. package/src/lib/hooks/use-crm-org-mount.d.ts +97 -0
  425. package/src/lib/hooks/use-crm-org-mount.js +215 -0
  426. package/src/lib/hooks/use-crm-org-mount.js.map +1 -0
  427. package/src/lib/hooks/use-crm-record-names.d.ts +52 -0
  428. package/src/lib/hooks/use-crm-record-names.js +126 -0
  429. package/src/lib/hooks/use-crm-record-names.js.map +1 -0
  430. package/src/lib/hooks/use-crm-records-quota.d.ts +68 -0
  431. package/src/lib/hooks/use-crm-records-quota.js +118 -0
  432. package/src/lib/hooks/use-crm-records-quota.js.map +1 -0
  433. package/src/lib/hooks/use-crm-saved-view.d.ts +96 -0
  434. package/src/lib/hooks/use-crm-saved-view.js +329 -0
  435. package/src/lib/hooks/use-crm-saved-view.js.map +1 -0
  436. package/src/lib/hooks/use-crm-scope.d.ts +117 -0
  437. package/src/lib/hooks/use-crm-scope.js +147 -0
  438. package/src/lib/hooks/use-crm-scope.js.map +1 -0
  439. package/src/lib/hooks/use-crm-tasks.d.ts +85 -0
  440. package/src/lib/hooks/use-crm-tasks.js +153 -0
  441. package/src/lib/hooks/use-crm-tasks.js.map +1 -0
  442. package/src/lib/hooks/use-crm-view-grid.d.ts +55 -0
  443. package/src/lib/hooks/use-crm-view-grid.js +170 -0
  444. package/src/lib/hooks/use-crm-view-grid.js.map +1 -0
  445. package/src/lib/hooks/use-crm-views.d.ts +42 -0
  446. package/src/lib/hooks/use-crm-views.js +84 -0
  447. package/src/lib/hooks/use-crm-views.js.map +1 -0
  448. package/src/lib/hooks/use-deal-stage-api.d.ts +69 -0
  449. package/src/lib/hooks/use-deal-stage-api.js +78 -0
  450. package/src/lib/hooks/use-deal-stage-api.js.map +1 -0
  451. package/src/lib/hooks/use-deals.d.ts +47 -0
  452. package/src/lib/hooks/use-deals.js +105 -0
  453. package/src/lib/hooks/use-deals.js.map +1 -0
  454. package/src/lib/hooks/use-org-leads.d.ts +53 -0
  455. package/src/lib/hooks/use-org-leads.js +114 -0
  456. package/src/lib/hooks/use-org-leads.js.map +1 -0
  457. package/src/lib/hooks/use-org-member-directory.d.ts +36 -0
  458. package/src/lib/hooks/use-org-member-directory.js +116 -0
  459. package/src/lib/hooks/use-org-member-directory.js.map +1 -0
  460. package/src/lib/hooks/use-org-member-options.d.ts +38 -0
  461. package/src/lib/hooks/use-org-member-options.js +131 -0
  462. package/src/lib/hooks/use-org-member-options.js.map +1 -0
  463. package/src/lib/hooks/use-pipeline.d.ts +71 -0
  464. package/src/lib/hooks/use-pipeline.js +159 -0
  465. package/src/lib/hooks/use-pipeline.js.map +1 -0
  466. package/src/lib/model/companies-bulk-writes.d.ts +40 -0
  467. package/src/lib/model/companies-bulk-writes.js +103 -0
  468. package/src/lib/model/companies-bulk-writes.js.map +1 -0
  469. package/src/lib/model/companies-csv.d.ts +36 -0
  470. package/src/lib/model/companies-csv.js +38 -0
  471. package/src/lib/model/companies-csv.js.map +1 -0
  472. package/src/lib/model/companies.d.ts +99 -0
  473. package/src/lib/model/companies.js +168 -0
  474. package/src/lib/model/companies.js.map +1 -0
  475. package/src/lib/model/company-delete-route.d.ts +43 -0
  476. package/src/lib/model/company-delete-route.js +31 -0
  477. package/src/lib/model/company-delete-route.js.map +1 -0
  478. package/src/lib/model/company-delete.d.ts +42 -0
  479. package/src/lib/model/company-delete.js +52 -0
  480. package/src/lib/model/company-delete.js.map +1 -0
  481. package/src/lib/model/contact-duplicates.d.ts +58 -0
  482. package/src/lib/model/contact-duplicates.js +67 -0
  483. package/src/lib/model/contact-duplicates.js.map +1 -0
  484. package/src/lib/model/contact-record.d.ts +113 -0
  485. package/src/lib/model/contact-record.js +70 -0
  486. package/src/lib/model/contact-record.js.map +1 -0
  487. package/src/lib/model/contact-update.d.ts +93 -0
  488. package/src/lib/model/contact-update.js +50 -0
  489. package/src/lib/model/contact-update.js.map +1 -0
  490. package/src/lib/model/contacts-bulk-writes.d.ts +173 -0
  491. package/src/lib/model/contacts-bulk-writes.js +196 -0
  492. package/src/lib/model/contacts-bulk-writes.js.map +1 -0
  493. package/src/lib/model/contacts-csv.d.ts +54 -0
  494. package/src/lib/model/contacts-csv.js +67 -0
  495. package/src/lib/model/contacts-csv.js.map +1 -0
  496. package/src/lib/model/contacts-list-seed.d.ts +51 -0
  497. package/src/lib/model/contacts-list-seed.js +63 -0
  498. package/src/lib/model/contacts-list-seed.js.map +1 -0
  499. package/src/lib/model/crm-activity-report.d.ts +27 -0
  500. package/src/lib/model/crm-activity-report.js +56 -0
  501. package/src/lib/model/crm-activity-report.js.map +1 -0
  502. package/src/lib/model/crm-api.d.ts +49 -0
  503. package/src/lib/model/crm-api.js +47 -0
  504. package/src/lib/model/crm-api.js.map +1 -0
  505. package/src/lib/model/crm-bulk-writes.d.ts +147 -0
  506. package/src/lib/model/crm-bulk-writes.js +207 -0
  507. package/src/lib/model/crm-bulk-writes.js.map +1 -0
  508. package/src/lib/model/crm-company-import.d.ts +154 -0
  509. package/src/lib/model/crm-company-import.js +331 -0
  510. package/src/lib/model/crm-company-import.js.map +1 -0
  511. package/src/lib/model/crm-custom-draft.d.ts +62 -0
  512. package/src/lib/model/crm-custom-draft.js +67 -0
  513. package/src/lib/model/crm-custom-draft.js.map +1 -0
  514. package/src/lib/model/crm-deal-import.d.ts +112 -0
  515. package/src/lib/model/crm-deal-import.js +263 -0
  516. package/src/lib/model/crm-deal-import.js.map +1 -0
  517. package/src/lib/model/crm-import.d.ts +244 -0
  518. package/src/lib/model/crm-import.js +466 -0
  519. package/src/lib/model/crm-import.js.map +1 -0
  520. package/src/lib/model/crm-lead-import.d.ts +105 -0
  521. package/src/lib/model/crm-lead-import.js +255 -0
  522. package/src/lib/model/crm-lead-import.js.map +1 -0
  523. package/src/lib/model/crm-record-routes.d.ts +21 -0
  524. package/src/lib/model/crm-record-routes.js +70 -0
  525. package/src/lib/model/crm-record-routes.js.map +1 -0
  526. package/src/lib/model/crm-routes.d.ts +101 -0
  527. package/src/lib/model/crm-routes.js +92 -0
  528. package/src/lib/model/crm-routes.js.map +1 -0
  529. package/src/lib/model/crm-task-import.d.ts +94 -0
  530. package/src/lib/model/crm-task-import.js +275 -0
  531. package/src/lib/model/crm-task-import.js.map +1 -0
  532. package/src/lib/model/crm-view-param.d.ts +43 -0
  533. package/src/lib/model/crm-view-param.js +49 -0
  534. package/src/lib/model/crm-view-param.js.map +1 -0
  535. package/src/lib/model/deal-board-model.d.ts +241 -0
  536. package/src/lib/model/deal-board-model.js +439 -0
  537. package/src/lib/model/deal-board-model.js.map +1 -0
  538. package/src/lib/model/deal-form-model.d.ts +114 -0
  539. package/src/lib/model/deal-form-model.js +218 -0
  540. package/src/lib/model/deal-form-model.js.map +1 -0
  541. package/src/lib/model/deals-csv.d.ts +32 -0
  542. package/src/lib/model/deals-csv.js +37 -0
  543. package/src/lib/model/deals-csv.js.map +1 -0
  544. package/src/lib/model/import-column-shapes.d.ts +36 -0
  545. package/src/lib/model/import-column-shapes.js +76 -0
  546. package/src/lib/model/import-column-shapes.js.map +1 -0
  547. package/src/lib/model/lead-company-suggestion.d.ts +61 -0
  548. package/src/lib/model/lead-company-suggestion.js +65 -0
  549. package/src/lib/model/lead-company-suggestion.js.map +1 -0
  550. package/src/lib/model/lead-filters.d.ts +29 -0
  551. package/src/lib/model/lead-filters.js +39 -0
  552. package/src/lib/model/lead-filters.js.map +1 -0
  553. package/src/lib/model/lead-surfaces.d.ts +58 -0
  554. package/src/lib/model/lead-surfaces.js +67 -0
  555. package/src/lib/model/lead-surfaces.js.map +1 -0
  556. package/src/lib/model/leads-csv.d.ts +40 -0
  557. package/src/lib/model/leads-csv.js +40 -0
  558. package/src/lib/model/leads-csv.js.map +1 -0
  559. package/src/lib/model/next-activity-api.d.ts +31 -0
  560. package/src/lib/model/next-activity-api.js +57 -0
  561. package/src/lib/model/next-activity-api.js.map +1 -0
  562. package/src/lib/model/next-activity.d.ts +64 -0
  563. package/src/lib/model/next-activity.js +47 -0
  564. package/src/lib/model/next-activity.js.map +1 -0
  565. package/src/lib/model/person-key-web.d.ts +43 -0
  566. package/src/lib/model/person-key-web.js +52 -0
  567. package/src/lib/model/person-key-web.js.map +1 -0
  568. package/src/lib/model/record-facts.d.ts +282 -0
  569. package/src/lib/model/record-facts.js +434 -0
  570. package/src/lib/model/record-facts.js.map +1 -0
  571. package/src/lib/model/task-api.d.ts +28 -0
  572. package/src/lib/model/task-api.js +57 -0
  573. package/src/lib/model/task-api.js.map +1 -0
  574. package/src/lib/model/task-calendar.d.ts +108 -0
  575. package/src/lib/model/task-calendar.js +139 -0
  576. package/src/lib/model/task-calendar.js.map +1 -0
  577. package/src/lib/model/task-routes.d.ts +177 -0
  578. package/src/lib/model/task-routes.js +197 -0
  579. package/src/lib/model/task-routes.js.map +1 -0
  580. package/src/lib/model/task-scope.d.ts +45 -0
  581. package/src/lib/model/task-scope.js +51 -0
  582. package/src/lib/model/task-scope.js.map +1 -0
  583. package/src/lib/model/task-views.d.ts +149 -0
  584. package/src/lib/model/task-views.js +286 -0
  585. package/src/lib/model/task-views.js.map +1 -0
  586. package/src/lib/model/tasks-csv.d.ts +28 -0
  587. package/src/lib/model/tasks-csv.js +28 -0
  588. package/src/lib/model/tasks-csv.js.map +1 -0
  589. package/src/lib/plugin.d.ts +32 -0
  590. package/src/lib/plugin.js +208 -0
  591. package/src/lib/plugin.js.map +1 -0
  592. package/src/lib/server/companies-import.d.ts +57 -0
  593. package/src/lib/server/companies-import.js +242 -0
  594. package/src/lib/server/companies-import.js.map +1 -0
  595. package/src/lib/server/company-delete.d.ts +59 -0
  596. package/src/lib/server/company-delete.js +146 -0
  597. package/src/lib/server/company-delete.js.map +1 -0
  598. package/src/lib/server/contact-email-history.d.ts +82 -0
  599. package/src/lib/server/contact-email-history.js +264 -0
  600. package/src/lib/server/contact-email-history.js.map +1 -0
  601. package/src/lib/server/contact-profile.d.ts +41 -0
  602. package/src/lib/server/contact-profile.js +45 -0
  603. package/src/lib/server/contact-profile.js.map +1 -0
  604. package/src/lib/server/contact-update.d.ts +92 -0
  605. package/src/lib/server/contact-update.js +512 -0
  606. package/src/lib/server/contact-update.js.map +1 -0
  607. package/src/lib/server/contacts-import.d.ts +73 -0
  608. package/src/lib/server/contacts-import.js +263 -0
  609. package/src/lib/server/contacts-import.js.map +1 -0
  610. package/src/lib/server/contacts-merge.d.ts +86 -0
  611. package/src/lib/server/contacts-merge.js +206 -0
  612. package/src/lib/server/contacts-merge.js.map +1 -0
  613. package/src/lib/server/deals-import.d.ts +76 -0
  614. package/src/lib/server/deals-import.js +246 -0
  615. package/src/lib/server/deals-import.js.map +1 -0
  616. package/src/lib/server/email-send.d.ts +119 -0
  617. package/src/lib/server/email-send.js +667 -0
  618. package/src/lib/server/email-send.js.map +1 -0
  619. package/src/lib/server/email-template-duplicate.d.ts +19 -0
  620. package/src/lib/server/email-template-duplicate.js +206 -0
  621. package/src/lib/server/email-template-duplicate.js.map +1 -0
  622. package/src/lib/server/erase-person.d.ts +108 -0
  623. package/src/lib/server/erase-person.js +309 -0
  624. package/src/lib/server/erase-person.js.map +1 -0
  625. package/src/lib/server/import-context.d.ts +85 -0
  626. package/src/lib/server/import-context.js +181 -0
  627. package/src/lib/server/import-context.js.map +1 -0
  628. package/src/lib/server/inbound-address.d.ts +61 -0
  629. package/src/lib/server/inbound-address.js +188 -0
  630. package/src/lib/server/inbound-address.js.map +1 -0
  631. package/src/lib/server/lead-convert.d.ts +78 -0
  632. package/src/lib/server/lead-convert.js +250 -0
  633. package/src/lib/server/lead-convert.js.map +1 -0
  634. package/src/lib/server/leads-import.d.ts +84 -0
  635. package/src/lib/server/leads-import.js +261 -0
  636. package/src/lib/server/leads-import.js.map +1 -0
  637. package/src/lib/server/next-activity-routes.d.ts +33 -0
  638. package/src/lib/server/next-activity-routes.js +110 -0
  639. package/src/lib/server/next-activity-routes.js.map +1 -0
  640. package/src/lib/server/org-activity.d.ts +61 -0
  641. package/src/lib/server/org-activity.js +120 -0
  642. package/src/lib/server/org-activity.js.map +1 -0
  643. package/src/lib/server/org-caller.d.ts +110 -0
  644. package/src/lib/server/org-caller.js +154 -0
  645. package/src/lib/server/org-caller.js.map +1 -0
  646. package/src/lib/server/recipe-routes.d.ts +75 -0
  647. package/src/lib/server/recipe-routes.js +442 -0
  648. package/src/lib/server/recipe-routes.js.map +1 -0
  649. package/src/lib/server/record-facts.d.ts +65 -0
  650. package/src/lib/server/record-facts.js +337 -0
  651. package/src/lib/server/record-facts.js.map +1 -0
  652. package/src/lib/server/record-timeline.d.ts +51 -0
  653. package/src/lib/server/record-timeline.js +215 -0
  654. package/src/lib/server/record-timeline.js.map +1 -0
  655. package/src/lib/server/suite-gate.d.ts +42 -0
  656. package/src/lib/server/suite-gate.js +87 -0
  657. package/src/lib/server/suite-gate.js.map +1 -0
  658. package/src/lib/server/task-routes.d.ts +132 -0
  659. package/src/lib/server/task-routes.js +699 -0
  660. package/src/lib/server/task-routes.js.map +1 -0
  661. package/src/lib/server/tasks-import.d.ts +54 -0
  662. package/src/lib/server/tasks-import.js +157 -0
  663. package/src/lib/server/tasks-import.js.map +1 -0
  664. package/src/lib/server-deal-stage.d.ts +88 -0
  665. package/src/lib/server-deal-stage.js +316 -0
  666. package/src/lib/server-deal-stage.js.map +1 -0
  667. package/src/lib/server.d.ts +149 -0
  668. package/src/lib/server.js +615 -0
  669. package/src/lib/server.js.map +1 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * `POST /api/crm/leads-import` — one chunk of a leads file, written
19
+ * (AGL-2701).
20
+ *
21
+ * The browser has already read the file and applied the operator's column
22
+ * mapping; what arrives here is up to {@link LEAD_IMPORT_CHUNK_SIZE} raw
23
+ * rows in the vocabulary `crm-lead-import.ts` defines. This route judges
24
+ * each one through the same normalizer, resolves the owner against the
25
+ * org's roster, and writes it in two halves.
26
+ *
27
+ * ## The capture half goes through the door every capture goes through
28
+ *
29
+ * `addHostLead` — the ONE writer of `hosts/{hostId}/leads` for the sign-up
30
+ * handler and both booking paths — is the writer here too. That is what
31
+ * makes an imported row key on `personKey` the way a second form
32
+ * submission does, land under the site by path with `capturedByHostIds`
33
+ * naming it, count against `LEADS_MAX_PER_HOST` inside the transaction
34
+ * that writes, and record NO marketing basis. A bulk path with its own
35
+ * `add()` would grow an unkeyed, unbounded copy of the site's leads under
36
+ * a second set of rules.
37
+ *
38
+ * ## A lead is host-scoped by path, so nothing here stamps `visibleTo`
39
+ *
40
+ * The five org collections carry `visibleTo` because they sit under
41
+ * `orgs/{orgId}` and the rules decide per document which sites may read
42
+ * them. A lead does not: `hosts/{hostId}/leads` is private to the site by
43
+ * path, the rules admit the site's own members, and the list therefore
44
+ * reads it with no scope clause. An import that stamped scope tokens onto
45
+ * a lead would be writing a field nothing reads, and would suggest a
46
+ * sharing decision the collection does not have. The site is the whole
47
+ * scope, and the drawer's picker is where it is chosen.
48
+ *
49
+ * ## No file may hand a lead a consent it did not give
50
+ *
51
+ * A capture writes a marketing basis only when the visitor ticked a box in
52
+ * front of them. A CSV row has no such event behind it, so the lead
53
+ * vocabulary has no consent column and this route passes no
54
+ * `marketingConsent`: an imported lead is mailable only if some earlier
55
+ * capture on this site already recorded a basis, which `addHostLead`
56
+ * carries forward untouched. The contacts import has a consent column
57
+ * because its own export writes one and the merchant is asserting a basis
58
+ * they hold per person; the leads export writes none, and a column the
59
+ * file cannot fill is a column that cannot be misread.
60
+ *
61
+ * ## The working half is written the way the list writes it
62
+ *
63
+ * A status, an owner, a reason and notes are the CRM's annotations, not
64
+ * the capture's, and the leads list already writes them client-direct onto
65
+ * the same document. A row that carries any of them gets one merge write
66
+ * after the door's, stamped `updatedAt` exactly as the list stamps it. A
67
+ * row that carries none costs nothing extra.
68
+ *
69
+ * ## Created or merged is read once for the chunk
70
+ *
71
+ * The door reports only whether the lead was STORED, and the result panel
72
+ * has to say how many people were added and how many updated. One
73
+ * `getAll` over the chunk's document ids answers that for every row in a
74
+ * single round trip, before any of them is written — which is also the
75
+ * only moment the answer is still true.
76
+ */
77
+ import { type PluginApiHandler } from '@aglyn/aglyn/server';
78
+ /**
79
+ * `POST crm/leads-import` — `{ hostId, rows }` → a {@link LeadImportChunkResult}.
80
+ *
81
+ * Rows are written one after another so the ceiling's local count stays
82
+ * honest across the request.
83
+ */
84
+ export declare const crmLeadsImportHandler: PluginApiHandler;
@@ -0,0 +1,261 @@
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
+ */ /**
18
+ * `POST /api/crm/leads-import` — one chunk of a leads file, written
19
+ * (AGL-2701).
20
+ *
21
+ * The browser has already read the file and applied the operator's column
22
+ * mapping; what arrives here is up to {@link LEAD_IMPORT_CHUNK_SIZE} raw
23
+ * rows in the vocabulary `crm-lead-import.ts` defines. This route judges
24
+ * each one through the same normalizer, resolves the owner against the
25
+ * org's roster, and writes it in two halves.
26
+ *
27
+ * ## The capture half goes through the door every capture goes through
28
+ *
29
+ * `addHostLead` — the ONE writer of `hosts/{hostId}/leads` for the sign-up
30
+ * handler and both booking paths — is the writer here too. That is what
31
+ * makes an imported row key on `personKey` the way a second form
32
+ * submission does, land under the site by path with `capturedByHostIds`
33
+ * naming it, count against `LEADS_MAX_PER_HOST` inside the transaction
34
+ * that writes, and record NO marketing basis. A bulk path with its own
35
+ * `add()` would grow an unkeyed, unbounded copy of the site's leads under
36
+ * a second set of rules.
37
+ *
38
+ * ## A lead is host-scoped by path, so nothing here stamps `visibleTo`
39
+ *
40
+ * The five org collections carry `visibleTo` because they sit under
41
+ * `orgs/{orgId}` and the rules decide per document which sites may read
42
+ * them. A lead does not: `hosts/{hostId}/leads` is private to the site by
43
+ * path, the rules admit the site's own members, and the list therefore
44
+ * reads it with no scope clause. An import that stamped scope tokens onto
45
+ * a lead would be writing a field nothing reads, and would suggest a
46
+ * sharing decision the collection does not have. The site is the whole
47
+ * scope, and the drawer's picker is where it is chosen.
48
+ *
49
+ * ## No file may hand a lead a consent it did not give
50
+ *
51
+ * A capture writes a marketing basis only when the visitor ticked a box in
52
+ * front of them. A CSV row has no such event behind it, so the lead
53
+ * vocabulary has no consent column and this route passes no
54
+ * `marketingConsent`: an imported lead is mailable only if some earlier
55
+ * capture on this site already recorded a basis, which `addHostLead`
56
+ * carries forward untouched. The contacts import has a consent column
57
+ * because its own export writes one and the merchant is asserting a basis
58
+ * they hold per person; the leads export writes none, and a column the
59
+ * file cannot fill is a column that cannot be misread.
60
+ *
61
+ * ## The working half is written the way the list writes it
62
+ *
63
+ * A status, an owner, a reason and notes are the CRM's annotations, not
64
+ * the capture's, and the leads list already writes them client-direct onto
65
+ * the same document. A row that carries any of them gets one merge write
66
+ * after the door's, stamped `updatedAt` exactly as the list stamps it. A
67
+ * row that carries none costs nothing extra.
68
+ *
69
+ * ## Created or merged is read once for the chunk
70
+ *
71
+ * The door reports only whether the lead was STORED, and the result panel
72
+ * has to say how many people were added and how many updated. One
73
+ * `getAll` over the chunk's document ids answers that for every row in a
74
+ * single round trip, before any of them is written — which is also the
75
+ * only moment the answer is still true.
76
+ */ import { checkVisitorRecordCeiling, LEADS_MAX_PER_HOST, personKey } from "@aglyn/aglyn/server";
77
+ import { LEAD_IMPORT_CHUNK_SIZE, LEAD_IMPORT_MAX_BODY_BYTES, normalizeLeadImportRow } from "../model/crm-lead-import.js";
78
+ import { addHostLead, firebaseAdmin } from "@aglyn/tenant-data-admin";
79
+ import { FieldValue } from "firebase-admin/firestore";
80
+ import { ownerDirectory, readImportRows, resolveImportContext } from "./import-context.js";
81
+ /**
82
+ * The surface an imported lead names, beside `signup`, `booking` and
83
+ * `form:{formId}`.
84
+ *
85
+ * Typed as the capture-source union rather than a bare string, which is
86
+ * what the contacts import gets for free from the door it calls: a lead's
87
+ * `source` is plain text on the way in, so this is the only place the word
88
+ * can be held to the same vocabulary the source filters and the labels
89
+ * read. One person brought in by one file reads the same on both records.
90
+ */ const LEAD_IMPORT_SOURCE = 'import';
91
+ /** The team's annotations on one row, or nothing when the file named none. */ function workingState(row, ownerUid) {
92
+ const fields = _extends({}, row.status ? {
93
+ status: row.status
94
+ } : {}, ownerUid ? {
95
+ ownerUid
96
+ } : {}, row.unqualifiedReason ? {
97
+ unqualifiedReason: row.unqualifiedReason
98
+ } : {}, row.notes ? {
99
+ notes: row.notes
100
+ } : {});
101
+ return Object.keys(fields).length ? fields : null;
102
+ }
103
+ /**
104
+ * `POST crm/leads-import` — `{ hostId, rows }` → a {@link LeadImportChunkResult}.
105
+ *
106
+ * Rows are written one after another so the ceiling's local count stays
107
+ * honest across the request.
108
+ */ export const crmLeadsImportHandler = async (req, res)=>{
109
+ if (req.method !== 'POST') {
110
+ res.setHeader('Allow', 'POST');
111
+ return res.status(405).json({
112
+ error: 'Method not allowed'
113
+ });
114
+ }
115
+ const read = readImportRows(req, {
116
+ maxBodyBytes: LEAD_IMPORT_MAX_BODY_BYTES,
117
+ chunkSize: LEAD_IMPORT_CHUNK_SIZE
118
+ });
119
+ if ('error' in read) return res.status(read.status).json({
120
+ error: read.error
121
+ });
122
+ try {
123
+ const context = await resolveImportContext(req);
124
+ if (context.ok === false) return res.status(context.status).json(context.body);
125
+ const skipped = [];
126
+ const dropped = {};
127
+ const normalized = [];
128
+ /*
129
+ * A duplicate WITHIN the request is skipped rather than merged, for
130
+ * the reason the contacts import gives: the second row would merge
131
+ * onto the first's document and the tally would read one created and
132
+ * one merged for one person in one file. Across requests the door's
133
+ * own dedupe answers, and reports a merge.
134
+ */ const seen = new Set();
135
+ read.rows.forEach((raw, index)=>{
136
+ const verdict = normalizeLeadImportRow(raw);
137
+ if (verdict.ok === false) {
138
+ skipped.push({
139
+ index,
140
+ email: verdict.input,
141
+ reason: verdict.reason
142
+ });
143
+ return;
144
+ }
145
+ // Non-null by construction: the normalizer refused every address
146
+ // this derivation could not key.
147
+ const key = personKey(verdict.row.email);
148
+ if (seen.has(key)) {
149
+ skipped.push({
150
+ index,
151
+ email: verdict.row.email,
152
+ reason: 'duplicate'
153
+ });
154
+ return;
155
+ }
156
+ seen.add(key);
157
+ for (const entry of verdict.row.dropped){
158
+ var _dropped_entry_field;
159
+ dropped[entry.field] = ((_dropped_entry_field = dropped[entry.field]) != null ? _dropped_entry_field : 0) + 1;
160
+ }
161
+ normalized.push({
162
+ index,
163
+ row: verdict.row,
164
+ key
165
+ });
166
+ });
167
+ const firestore = firebaseAdmin.app().firestore();
168
+ const hostRef = firestore.collection('hosts').doc(context.hostId);
169
+ const leadsRef = hostRef.collection('leads');
170
+ const refs = normalized.map((entry)=>leadsRef.doc(entry.key));
171
+ const [owners, before] = await Promise.all([
172
+ ownerDirectory(context.orgId, normalized.map((entry)=>entry.row)),
173
+ refs.length ? firestore.getAll(...refs) : Promise.resolve([])
174
+ ]);
175
+ const held = new Set(before.filter((snapshot)=>snapshot.exists).map((snapshot)=>snapshot.id));
176
+ const ownersUnresolved = new Set();
177
+ let counted = null;
178
+ let createdHere = 0;
179
+ let created = 0;
180
+ let merged = 0;
181
+ for (const { index, row, key } of normalized){
182
+ const isNew = !held.has(key);
183
+ /*
184
+ * The platform lead ceiling, judged the way the deals import judges
185
+ * the records band: one count at the first create, re-judged locally
186
+ * as the request creates more. The door re-judges it authoritatively
187
+ * inside its own transaction, so a race is still refused there — this
188
+ * is what lets the operator's skipped file say WHY rather than only
189
+ * that the row could not be saved.
190
+ */ if (isNew) {
191
+ if (counted === null) {
192
+ counted = (await leadsRef.count().get()).data().count;
193
+ }
194
+ if (checkVisitorRecordCeiling(counted + createdHere, LEADS_MAX_PER_HOST).exceeded) {
195
+ skipped.push({
196
+ index,
197
+ email: row.email,
198
+ reason: 'lead-ceiling'
199
+ });
200
+ continue;
201
+ }
202
+ }
203
+ let ownerUid;
204
+ if (row.ownerEmail) {
205
+ ownerUid = owners.get(row.ownerEmail);
206
+ if (!ownerUid) ownersUnresolved.add(row.ownerEmail);
207
+ }
208
+ const stored = await addHostLead({
209
+ hostRef,
210
+ hostId: context.hostId,
211
+ lead: _extends({
212
+ email: row.email
213
+ }, row.name ? {
214
+ name: row.name
215
+ } : {}, {
216
+ source: LEAD_IMPORT_SOURCE
217
+ })
218
+ });
219
+ if (!stored) {
220
+ skipped.push({
221
+ index,
222
+ email: row.email,
223
+ reason: 'write-failed'
224
+ });
225
+ continue;
226
+ }
227
+ const working = workingState(row, ownerUid);
228
+ if (working) {
229
+ await leadsRef.doc(key).set(_extends({}, working, {
230
+ updatedAt: FieldValue.serverTimestamp()
231
+ }), {
232
+ merge: true
233
+ });
234
+ }
235
+ if (isNew) {
236
+ created += 1;
237
+ createdHere += 1;
238
+ } else {
239
+ merged += 1;
240
+ }
241
+ }
242
+ const result = {
243
+ received: read.rows.length,
244
+ created,
245
+ merged,
246
+ skipped: skipped.sort((a, b)=>a.index - b.index),
247
+ dropped,
248
+ ownersUnresolved: [
249
+ ...ownersUnresolved
250
+ ]
251
+ };
252
+ return res.status(200).json(result);
253
+ } catch (error) {
254
+ console.error('crm/leads-import failed', error);
255
+ return res.status(500).json({
256
+ error: 'The import could not continue.'
257
+ });
258
+ }
259
+ };
260
+
261
+ //# sourceMappingURL=leads-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/server/leads-import.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * `POST /api/crm/leads-import` — one chunk of a leads file, written\n * (AGL-2701).\n *\n * The browser has already read the file and applied the operator's column\n * mapping; what arrives here is up to {@link LEAD_IMPORT_CHUNK_SIZE} raw\n * rows in the vocabulary `crm-lead-import.ts` defines. This route judges\n * each one through the same normalizer, resolves the owner against the\n * org's roster, and writes it in two halves.\n *\n * ## The capture half goes through the door every capture goes through\n *\n * `addHostLead` — the ONE writer of `hosts/{hostId}/leads` for the sign-up\n * handler and both booking paths — is the writer here too. That is what\n * makes an imported row key on `personKey` the way a second form\n * submission does, land under the site by path with `capturedByHostIds`\n * naming it, count against `LEADS_MAX_PER_HOST` inside the transaction\n * that writes, and record NO marketing basis. A bulk path with its own\n * `add()` would grow an unkeyed, unbounded copy of the site's leads under\n * a second set of rules.\n *\n * ## A lead is host-scoped by path, so nothing here stamps `visibleTo`\n *\n * The five org collections carry `visibleTo` because they sit under\n * `orgs/{orgId}` and the rules decide per document which sites may read\n * them. A lead does not: `hosts/{hostId}/leads` is private to the site by\n * path, the rules admit the site's own members, and the list therefore\n * reads it with no scope clause. An import that stamped scope tokens onto\n * a lead would be writing a field nothing reads, and would suggest a\n * sharing decision the collection does not have. The site is the whole\n * scope, and the drawer's picker is where it is chosen.\n *\n * ## No file may hand a lead a consent it did not give\n *\n * A capture writes a marketing basis only when the visitor ticked a box in\n * front of them. A CSV row has no such event behind it, so the lead\n * vocabulary has no consent column and this route passes no\n * `marketingConsent`: an imported lead is mailable only if some earlier\n * capture on this site already recorded a basis, which `addHostLead`\n * carries forward untouched. The contacts import has a consent column\n * because its own export writes one and the merchant is asserting a basis\n * they hold per person; the leads export writes none, and a column the\n * file cannot fill is a column that cannot be misread.\n *\n * ## The working half is written the way the list writes it\n *\n * A status, an owner, a reason and notes are the CRM's annotations, not\n * the capture's, and the leads list already writes them client-direct onto\n * the same document. A row that carries any of them gets one merge write\n * after the door's, stamped `updatedAt` exactly as the list stamps it. A\n * row that carries none costs nothing extra.\n *\n * ## Created or merged is read once for the chunk\n *\n * The door reports only whether the lead was STORED, and the result panel\n * has to say how many people were added and how many updated. One\n * `getAll` over the chunk's document ids answers that for every row in a\n * single round trip, before any of them is written — which is also the\n * only moment the answer is still true.\n */\n\nimport {\n checkVisitorRecordCeiling,\n type ContactSource,\n LEADS_MAX_PER_HOST,\n personKey,\n type PluginApiHandler,\n} from '@aglyn/aglyn/server'\nimport {\n LEAD_IMPORT_CHUNK_SIZE,\n LEAD_IMPORT_MAX_BODY_BYTES,\n type LeadImportChunkResult,\n type LeadImportRawRow,\n type LeadImportRow,\n type LeadImportSkippedRow,\n normalizeLeadImportRow,\n} from '../model/crm-lead-import'\nimport { addHostLead, firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport { FieldValue } from 'firebase-admin/firestore'\nimport {\n ownerDirectory,\n readImportRows,\n resolveImportContext,\n} from './import-context'\n\n/**\n * The surface an imported lead names, beside `signup`, `booking` and\n * `form:{formId}`.\n *\n * Typed as the capture-source union rather than a bare string, which is\n * what the contacts import gets for free from the door it calls: a lead's\n * `source` is plain text on the way in, so this is the only place the word\n * can be held to the same vocabulary the source filters and the labels\n * read. One person brought in by one file reads the same on both records.\n */\nconst LEAD_IMPORT_SOURCE: ContactSource = 'import'\n\n/** The team's annotations on one row, or nothing when the file named none. */\nfunction workingState(\n row: LeadImportRow,\n ownerUid: string | undefined,\n): Record<string, unknown> | null {\n const fields: Record<string, unknown> = {\n ...(row.status ? { status: row.status } : {}),\n ...(ownerUid ? { ownerUid } : {}),\n ...(row.unqualifiedReason ? { unqualifiedReason: row.unqualifiedReason } : {}),\n ...(row.notes ? { notes: row.notes } : {}),\n }\n return Object.keys(fields).length ? fields : null\n}\n\n/**\n * `POST crm/leads-import` — `{ hostId, rows }` → a {@link LeadImportChunkResult}.\n *\n * Rows are written one after another so the ceiling's local count stays\n * honest across the request.\n */\nexport const crmLeadsImportHandler: PluginApiHandler = async (req, res) => {\n if (req.method !== 'POST') {\n res.setHeader('Allow', 'POST')\n return res.status(405).json({ error: 'Method not allowed' })\n }\n const read = readImportRows<LeadImportRawRow>(req, {\n maxBodyBytes: LEAD_IMPORT_MAX_BODY_BYTES,\n chunkSize: LEAD_IMPORT_CHUNK_SIZE,\n })\n if ('error' in read) return res.status(read.status).json({ error: read.error })\n try {\n const context = await resolveImportContext(req)\n if (context.ok === false) return res.status(context.status).json(context.body)\n\n const skipped: LeadImportSkippedRow[] = []\n const dropped: Record<string, number> = {}\n const normalized: { index: number; row: LeadImportRow; key: string }[] = []\n /*\n * A duplicate WITHIN the request is skipped rather than merged, for\n * the reason the contacts import gives: the second row would merge\n * onto the first's document and the tally would read one created and\n * one merged for one person in one file. Across requests the door's\n * own dedupe answers, and reports a merge.\n */\n const seen = new Set<string>()\n read.rows.forEach((raw, index) => {\n const verdict = normalizeLeadImportRow(raw)\n if (verdict.ok === false) {\n skipped.push({ index, email: verdict.input, reason: verdict.reason })\n return\n }\n // Non-null by construction: the normalizer refused every address\n // this derivation could not key.\n const key = personKey(verdict.row.email) as string\n if (seen.has(key)) {\n skipped.push({ index, email: verdict.row.email, reason: 'duplicate' })\n return\n }\n seen.add(key)\n for (const entry of verdict.row.dropped) {\n dropped[entry.field] = (dropped[entry.field] ?? 0) + 1\n }\n normalized.push({ index, row: verdict.row, key })\n })\n\n const firestore = firebaseAdmin.app().firestore()\n const hostRef = firestore.collection('hosts').doc(context.hostId)\n const leadsRef = hostRef.collection('leads')\n const refs = normalized.map((entry) => leadsRef.doc(entry.key))\n const [owners, before] = await Promise.all([\n ownerDirectory(\n context.orgId,\n normalized.map((entry) => entry.row),\n ),\n refs.length ? firestore.getAll(...refs) : Promise.resolve([]),\n ])\n const held = new Set(\n before.filter((snapshot) => snapshot.exists).map((snapshot) => snapshot.id),\n )\n const ownersUnresolved = new Set<string>()\n let counted: number | null = null\n let createdHere = 0\n let created = 0\n let merged = 0\n\n for (const { index, row, key } of normalized) {\n const isNew = !held.has(key)\n /*\n * The platform lead ceiling, judged the way the deals import judges\n * the records band: one count at the first create, re-judged locally\n * as the request creates more. The door re-judges it authoritatively\n * inside its own transaction, so a race is still refused there — this\n * is what lets the operator's skipped file say WHY rather than only\n * that the row could not be saved.\n */\n if (isNew) {\n if (counted === null) {\n counted = (await leadsRef.count().get()).data().count\n }\n if (\n checkVisitorRecordCeiling(counted + createdHere, LEADS_MAX_PER_HOST)\n .exceeded\n ) {\n skipped.push({ index, email: row.email, reason: 'lead-ceiling' })\n continue\n }\n }\n let ownerUid: string | undefined\n if (row.ownerEmail) {\n ownerUid = owners.get(row.ownerEmail)\n if (!ownerUid) ownersUnresolved.add(row.ownerEmail)\n }\n const stored = await addHostLead({\n hostRef,\n hostId: context.hostId,\n lead: {\n email: row.email,\n ...(row.name ? { name: row.name } : {}),\n source: LEAD_IMPORT_SOURCE,\n },\n })\n if (!stored) {\n skipped.push({ index, email: row.email, reason: 'write-failed' })\n continue\n }\n const working = workingState(row, ownerUid)\n if (working) {\n await leadsRef\n .doc(key)\n .set(\n { ...working, updatedAt: FieldValue.serverTimestamp() },\n { merge: true },\n )\n }\n if (isNew) {\n created += 1\n createdHere += 1\n } else {\n merged += 1\n }\n }\n\n const result: LeadImportChunkResult = {\n received: read.rows.length,\n created,\n merged,\n skipped: skipped.sort((a, b) => a.index - b.index),\n dropped,\n ownersUnresolved: [...ownersUnresolved],\n }\n return res.status(200).json(result)\n } catch (error) {\n console.error('crm/leads-import failed', error)\n return res.status(500).json({ error: 'The import could not continue.' })\n }\n}\n"],"names":["checkVisitorRecordCeiling","LEADS_MAX_PER_HOST","personKey","LEAD_IMPORT_CHUNK_SIZE","LEAD_IMPORT_MAX_BODY_BYTES","normalizeLeadImportRow","addHostLead","firebaseAdmin","FieldValue","ownerDirectory","readImportRows","resolveImportContext","LEAD_IMPORT_SOURCE","workingState","row","ownerUid","fields","status","unqualifiedReason","notes","Object","keys","length","crmLeadsImportHandler","req","res","method","setHeader","json","error","read","maxBodyBytes","chunkSize","context","ok","body","skipped","dropped","normalized","seen","Set","rows","forEach","raw","index","verdict","push","email","input","reason","key","has","add","entry","field","firestore","app","hostRef","collection","doc","hostId","leadsRef","refs","map","owners","before","Promise","all","orgId","getAll","resolve","held","filter","snapshot","exists","id","ownersUnresolved","counted","createdHere","created","merged","isNew","count","get","data","exceeded","ownerEmail","stored","lead","name","source","working","set","updatedAt","serverTimestamp","merge","result","received","sort","a","b","console"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { PluginApiHandler } from '@aglyn/aglyn/server';
18
+ /**
19
+ * `POST crm/next-activity` — recompute `nextTaskAtMs` (AGL-2661).
20
+ *
21
+ * Body: `{ hostId | orgId, links: [{ contactId?, companyId?, dealId? }] }`
22
+ * after a client-direct task write, or `{ hostId | orgId, all: true }` for
23
+ * the Fields section's whole-organization recompute. Authorized the way the
24
+ * task routes are — a member who may write this CRM — and never more
25
+ * revealing than a task write: the route stores a figure derived from
26
+ * tasks the caller could already read, and answers with counts.
27
+ *
28
+ * The links are not checked against the caller's scope. A scoped member
29
+ * naming a record they cannot see gets that record's figure recomputed
30
+ * from its own tasks, which is the figure it should carry anyway; nothing
31
+ * about the record comes back.
32
+ */
33
+ export declare const crmNextActivityHandler: PluginApiHandler;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { _ as _extends } from "@swc/helpers/_/_extends";
17
+ import { firebaseAdmin, recomputeCrmNextTaskAt, sweepCrmNextTaskAt } from "@aglyn/tenant-data-admin";
18
+ import { CRM_NEXT_ACTIVITY_LINKS_MAX } from "../model/next-activity.js";
19
+ import { readCrmRouteScope } from "./org-caller.js";
20
+ import { authorizeCrmWriter } from "./task-routes.js";
21
+ /**
22
+ * `POST crm/next-activity` — recompute `nextTaskAtMs` (AGL-2661).
23
+ *
24
+ * Body: `{ hostId | orgId, links: [{ contactId?, companyId?, dealId? }] }`
25
+ * after a client-direct task write, or `{ hostId | orgId, all: true }` for
26
+ * the Fields section's whole-organization recompute. Authorized the way the
27
+ * task routes are — a member who may write this CRM — and never more
28
+ * revealing than a task write: the route stores a figure derived from
29
+ * tasks the caller could already read, and answers with counts.
30
+ *
31
+ * The links are not checked against the caller's scope. A scoped member
32
+ * naming a record they cannot see gets that record's figure recomputed
33
+ * from its own tasks, which is the figure it should carry anyway; nothing
34
+ * about the record comes back.
35
+ */ export const crmNextActivityHandler = async (req, res)=>{
36
+ var _req_body;
37
+ if (req.method !== 'POST') {
38
+ res.status(405).json({
39
+ error: 'Method not allowed'
40
+ });
41
+ return;
42
+ }
43
+ const body = (_req_body = req.body) != null ? _req_body : {};
44
+ const scope = readCrmRouteScope(body);
45
+ if (!scope) {
46
+ res.status(400).json({
47
+ error: 'Missing hostId'
48
+ });
49
+ return;
50
+ }
51
+ try {
52
+ const writer = await authorizeCrmWriter(req, scope);
53
+ if (writer.ok === false) {
54
+ res.status(writer.status).json(writer.body);
55
+ return;
56
+ }
57
+ const firestore = firebaseAdmin.app().firestore();
58
+ if (body['all'] === true) {
59
+ const sweep = await sweepCrmNextTaskAt(firestore, writer.orgId);
60
+ const answer = {
61
+ ok: true,
62
+ records: sweep.scheduled + sweep.cleared,
63
+ missing: 0,
64
+ tasks: sweep.tasks,
65
+ cleared: sweep.cleared,
66
+ truncated: sweep.truncated
67
+ };
68
+ res.status(200).json(answer);
69
+ return;
70
+ }
71
+ const links = readLinks(body['links']);
72
+ if (!links) {
73
+ res.status(400).json({
74
+ error: 'Name the records to recompute, or ask for all of them.'
75
+ });
76
+ return;
77
+ }
78
+ const result = await recomputeCrmNextTaskAt(firestore, writer.orgId, links);
79
+ const answer = _extends({
80
+ ok: true
81
+ }, result);
82
+ res.status(200).json(answer);
83
+ } catch (error) {
84
+ console.error('[crm] next-activity failed', error);
85
+ res.status(500).json({
86
+ error: 'The next activity could not be recomputed.'
87
+ });
88
+ }
89
+ };
90
+ /** The links off the body, held to ids: a string each, trimmed, capped. */ function readLinks(raw) {
91
+ if (!Array.isArray(raw)) return null;
92
+ const links = [];
93
+ for (const entry of raw.slice(0, CRM_NEXT_ACTIVITY_LINKS_MAX)){
94
+ const record = entry != null ? entry : {};
95
+ const link = {};
96
+ for (const field of [
97
+ 'contactId',
98
+ 'companyId',
99
+ 'dealId'
100
+ ]){
101
+ var _record_field;
102
+ const id = String((_record_field = record[field]) != null ? _record_field : '').trim().slice(0, 128);
103
+ if (id) link[field] = id;
104
+ }
105
+ if (Object.keys(link).length) links.push(link);
106
+ }
107
+ return links;
108
+ }
109
+
110
+ //# sourceMappingURL=next-activity-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/server/next-activity-routes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { CrmNextActivityLink, PluginApiHandler } from '@aglyn/aglyn/server'\nimport {\n firebaseAdmin,\n recomputeCrmNextTaskAt,\n sweepCrmNextTaskAt,\n} from '@aglyn/tenant-data-admin'\nimport {\n CRM_NEXT_ACTIVITY_LINKS_MAX,\n type CrmNextActivityResponse,\n} from '../model/next-activity'\nimport { readCrmRouteScope } from './org-caller'\nimport { authorizeCrmWriter } from './task-routes'\n\n/**\n * `POST crm/next-activity` — recompute `nextTaskAtMs` (AGL-2661).\n *\n * Body: `{ hostId | orgId, links: [{ contactId?, companyId?, dealId? }] }`\n * after a client-direct task write, or `{ hostId | orgId, all: true }` for\n * the Fields section's whole-organization recompute. Authorized the way the\n * task routes are — a member who may write this CRM — and never more\n * revealing than a task write: the route stores a figure derived from\n * tasks the caller could already read, and answers with counts.\n *\n * The links are not checked against the caller's scope. A scoped member\n * naming a record they cannot see gets that record's figure recomputed\n * from its own tasks, which is the figure it should carry anyway; nothing\n * about the record comes back.\n */\nexport const crmNextActivityHandler: PluginApiHandler = async (req, res) => {\n if (req.method !== 'POST') {\n res.status(405).json({ error: 'Method not allowed' })\n return\n }\n const body = (req.body ?? {}) as Record<string, unknown>\n const scope = readCrmRouteScope(body)\n if (!scope) {\n res.status(400).json({ error: 'Missing hostId' })\n return\n }\n try {\n const writer = await authorizeCrmWriter(req, scope)\n if (writer.ok === false) {\n res.status(writer.status).json(writer.body)\n return\n }\n const firestore = firebaseAdmin.app().firestore()\n if (body['all'] === true) {\n const sweep = await sweepCrmNextTaskAt(firestore, writer.orgId)\n const answer: CrmNextActivityResponse = {\n ok: true,\n records: sweep.scheduled + sweep.cleared,\n missing: 0,\n tasks: sweep.tasks,\n cleared: sweep.cleared,\n truncated: sweep.truncated,\n }\n res.status(200).json(answer)\n return\n }\n const links = readLinks(body['links'])\n if (!links) {\n res.status(400).json({ error: 'Name the records to recompute, or ask for all of them.' })\n return\n }\n const result = await recomputeCrmNextTaskAt(firestore, writer.orgId, links)\n const answer: CrmNextActivityResponse = { ok: true, ...result }\n res.status(200).json(answer)\n } catch (error) {\n console.error('[crm] next-activity failed', error)\n res.status(500).json({ error: 'The next activity could not be recomputed.' })\n }\n}\n\n/** The links off the body, held to ids: a string each, trimmed, capped. */\nfunction readLinks(raw: unknown): CrmNextActivityLink[] | null {\n if (!Array.isArray(raw)) return null\n const links: CrmNextActivityLink[] = []\n for (const entry of raw.slice(0, CRM_NEXT_ACTIVITY_LINKS_MAX)) {\n const record = (entry ?? {}) as Record<string, unknown>\n const link: CrmNextActivityLink = {}\n for (const field of ['contactId', 'companyId', 'dealId'] as const) {\n const id = String(record[field] ?? '').trim().slice(0, 128)\n if (id) link[field] = id\n }\n if (Object.keys(link).length) links.push(link)\n }\n return links\n}\n"],"names":["firebaseAdmin","recomputeCrmNextTaskAt","sweepCrmNextTaskAt","CRM_NEXT_ACTIVITY_LINKS_MAX","readCrmRouteScope","authorizeCrmWriter","crmNextActivityHandler","req","res","method","status","json","error","body","scope","writer","ok","firestore","app","sweep","orgId","answer","records","scheduled","cleared","missing","tasks","truncated","links","readLinks","result","console","raw","Array","isArray","entry","slice","record","link","field","id","String","trim","Object","keys","length","push"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC;AAGD,SACEA,aAAa,EACbC,sBAAsB,EACtBC,kBAAkB,QACb,2BAA0B;AACjC,SACEC,2BAA2B,QAEtB,4BAAwB;AAC/B,SAASC,iBAAiB,QAAQ,kBAAc;AAChD,SAASC,kBAAkB,QAAQ,mBAAe;AAElD;;;;;;;;;;;;;;CAcC,GACD,OAAO,MAAMC,yBAA2C,OAAOC,KAAKC;QAKpDD;IAJd,IAAIA,IAAIE,MAAM,KAAK,QAAQ;QACzBD,IAAIE,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAO;QAAqB;QACnD;IACF;IACA,MAAMC,QAAQN,YAAAA,IAAIM,IAAI,YAARN,YAAY,CAAC;IAC3B,MAAMO,QAAQV,kBAAkBS;IAChC,IAAI,CAACC,OAAO;QACVN,IAAIE,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAO;QAAiB;QAC/C;IACF;IACA,IAAI;QACF,MAAMG,SAAS,MAAMV,mBAAmBE,KAAKO;QAC7C,IAAIC,OAAOC,EAAE,KAAK,OAAO;YACvBR,IAAIE,MAAM,CAACK,OAAOL,MAAM,EAAEC,IAAI,CAACI,OAAOF,IAAI;YAC1C;QACF;QACA,MAAMI,YAAYjB,cAAckB,GAAG,GAAGD,SAAS;QAC/C,IAAIJ,IAAI,CAAC,MAAM,KAAK,MAAM;YACxB,MAAMM,QAAQ,MAAMjB,mBAAmBe,WAAWF,OAAOK,KAAK;YAC9D,MAAMC,SAAkC;gBACtCL,IAAI;gBACJM,SAASH,MAAMI,SAAS,GAAGJ,MAAMK,OAAO;gBACxCC,SAAS;gBACTC,OAAOP,MAAMO,KAAK;gBAClBF,SAASL,MAAMK,OAAO;gBACtBG,WAAWR,MAAMQ,SAAS;YAC5B;YACAnB,IAAIE,MAAM,CAAC,KAAKC,IAAI,CAACU;YACrB;QACF;QACA,MAAMO,QAAQC,UAAUhB,IAAI,CAAC,QAAQ;QACrC,IAAI,CAACe,OAAO;YACVpB,IAAIE,MAAM,CAAC,KAAKC,IAAI,CAAC;gBAAEC,OAAO;YAAyD;YACvF;QACF;QACA,MAAMkB,SAAS,MAAM7B,uBAAuBgB,WAAWF,OAAOK,KAAK,EAAEQ;QACrE,MAAMP,SAAkC;YAAEL,IAAI;WAASc;QACvDtB,IAAIE,MAAM,CAAC,KAAKC,IAAI,CAACU;IACvB,EAAE,OAAOT,OAAO;QACdmB,QAAQnB,KAAK,CAAC,8BAA8BA;QAC5CJ,IAAIE,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAO;QAA6C;IAC7E;AACF,EAAC;AAED,yEAAyE,GACzE,SAASiB,UAAUG,GAAY;IAC7B,IAAI,CAACC,MAAMC,OAAO,CAACF,MAAM,OAAO;IAChC,MAAMJ,QAA+B,EAAE;IACvC,KAAK,MAAMO,SAASH,IAAII,KAAK,CAAC,GAAGjC,6BAA8B;QAC7D,MAAMkC,SAAUF,gBAAAA,QAAS,CAAC;QAC1B,MAAMG,OAA4B,CAAC;QACnC,KAAK,MAAMC,SAAS;YAAC;YAAa;YAAa;SAAS,CAAW;gBAC/CF;YAAlB,MAAMG,KAAKC,QAAOJ,gBAAAA,MAAM,CAACE,MAAM,YAAbF,gBAAiB,IAAIK,IAAI,GAAGN,KAAK,CAAC,GAAG;YACvD,IAAII,IAAIF,IAAI,CAACC,MAAM,GAAGC;QACxB;QACA,IAAIG,OAAOC,IAAI,CAACN,MAAMO,MAAM,EAAEjB,MAAMkB,IAAI,CAACR;IAC3C;IACA,OAAOV;AACT"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * `POST /api/crm/org-activity` — one line in the organization's activity
19
+ * feed (AGL-2634).
20
+ *
21
+ * Body: `{ orgId, action, target: { type, id?, name? } }`. Answers
22
+ * `{ ok: true }` once the line is appended.
23
+ *
24
+ * ## Why a route, when the site feed takes the browser's word for it
25
+ *
26
+ * A site's feed at `hosts/{hostId}/activity` is written client-direct: the
27
+ * bulk bars log "Deleted deal" per row through `useHostActivityLogger`,
28
+ * under a rule that lets a member holding a content role append. The
29
+ * organization's feed at `orgs/{orgId}/activity` is not — `allow write: if
30
+ * false` for every client, because the feed names who did what across every
31
+ * site and its only reader is `/api/orgs/activity`, gated on `org.auditLog`
32
+ * with the Admin SDK. So an act performed at the ORGANIZATION level with a
33
+ * client-direct write — a bulk bar over the org's deals, which writes the
34
+ * documents from the browser — has no feed it can reach, and the org hub
35
+ * wrote no line at all for its bulk actions. This is the door: the same
36
+ * trust the site feed extends to the browser (a verified member, holding
37
+ * the permission the CRM is gated on), narrowed to the org hub's reach
38
+ * (org-wide, never a site collaborator) and to the CRM's own record kinds.
39
+ *
40
+ * What it does NOT vouch for is that the act happened: like every
41
+ * client-written feed line, the sentence is the caller's. The routes that
42
+ * perform an org-level act themselves — the stage move, the merge, the
43
+ * erasure, the email — write their own line with the Admin SDK and never
44
+ * call here.
45
+ */
46
+ import type { PluginApiHandler } from '@aglyn/aglyn/server';
47
+ import { type CrmOrgActivityKind } from '../constants/api-routes';
48
+ export declare const CRM_ORG_ACTIVITY_ROUTE: "crm/org-activity";
49
+ /** The body the org-level bulk bars post. */
50
+ export interface OrgActivityRequest {
51
+ orgId: string;
52
+ /** The sentence — "Owner set on 3 deals" — as the bar's snackbar said it. */
53
+ action: string;
54
+ target: {
55
+ type: CrmOrgActivityKind;
56
+ id?: string;
57
+ name?: string;
58
+ };
59
+ }
60
+ export declare const crmOrgActivityHandler: PluginApiHandler;
61
+ export default crmOrgActivityHandler;