@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,699 @@
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 { consentGroupForHost, CRM_COLLECTIONS, crmScopeTokens, crmTaskReminderAfterEdit, crmTaskReminderPending, isOrgWideMember, memberCanSee } from "@aglyn/aglyn/server";
18
+ import { crmNextActivityLinksOf, firebaseAdmin, getOrgForHost, memberHasOrgPermission, notifyUsers, recomputeCrmNextTaskAt, resolveOrgMembership } from "@aglyn/tenant-data-admin";
19
+ import { emitHostEvent } from "@aglyn/tenant-runtime";
20
+ import { FieldValue } from "firebase-admin/firestore";
21
+ import { CRM_TASK_BATCH_MAX, readCrmTaskFields } from "../model/task-routes.js";
22
+ import { CRM_ORG_TASK_SCOPE } from "../model/task-scope.js";
23
+ import { authorizeOrgCaller, readCrmRouteScope } from "./org-caller.js";
24
+ import { crmSuiteRefusal } from "./suite-gate.js";
25
+ /** What the suite gate names when a task route refuses a plan without it. */ const TASKS_ACT = "Working a record's tasks";
26
+ export const refuse = (status, error)=>({
27
+ ok: false,
28
+ status,
29
+ body: {
30
+ error
31
+ }
32
+ });
33
+ const ORG_REFUSAL = 'Editing tasks at the organization level requires the "Manage data" ' + 'permission across the whole workspace.';
34
+ /**
35
+ * Who is asking, and whether they may write this CRM at all.
36
+ *
37
+ * Under a site: the org resolved from the site and the rules' own role and
38
+ * permission questions. At the organization level: the org the body names,
39
+ * for an org-wide member with the permission. The scope question — may they
40
+ * reach THIS task — is asked by the caller against the document, because on
41
+ * a create the document does not exist yet and its scope is what the route
42
+ * is about to stamp.
43
+ */ export async function authorizeCrmWriter(req, scope, options = {}) {
44
+ var _req_headers_authorization, _ref;
45
+ const suiteAct = options.suiteAct === undefined ? TASKS_ACT : options.suiteAct;
46
+ if (scope.level === 'org') {
47
+ const caller = await authorizeOrgCaller(req, scope.orgId, {
48
+ needs: 'data.manage',
49
+ refusal: ORG_REFUSAL
50
+ });
51
+ if (caller.ok === false) return refuse(caller.status, caller.error);
52
+ // The plan after the person (AGL-2787): see `suite-gate.ts`.
53
+ const suite = suiteAct ? crmSuiteRefusal(caller.org, suiteAct) : null;
54
+ if (suite) return {
55
+ ok: false,
56
+ status: suite.status,
57
+ body: suite.body
58
+ };
59
+ return {
60
+ ok: true,
61
+ uid: caller.uid,
62
+ staff: caller.staff,
63
+ orgId: caller.orgId,
64
+ org: caller.org,
65
+ member: null,
66
+ level: 'org'
67
+ };
68
+ }
69
+ const authorization = String((_req_headers_authorization = req.headers.authorization) != null ? _req_headers_authorization : '');
70
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
71
+ if (!idToken) return refuse(401, 'Unauthenticated');
72
+ const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
73
+ const staff = decoded['staff'] === true;
74
+ const resolved = await getOrgForHost(scope.hostId).catch(()=>null);
75
+ if (!resolved) {
76
+ return refuse(404, 'This site has no organization, so it has no CRM.');
77
+ }
78
+ const { orgId, org } = resolved;
79
+ const membership = await resolveOrgMembership(decoded.uid, orgId).catch(()=>null);
80
+ const member = (_ref = membership == null ? void 0 : membership.member) != null ? _ref : null;
81
+ if (!staff) {
82
+ var _ref1;
83
+ const role = String((_ref1 = member == null ? void 0 : member.role) != null ? _ref1 : '');
84
+ /*
85
+ * The rules' `canWriteOrgData()` restated: the role list is what an
86
+ * unstamped permission map falls through to, and the permission is the
87
+ * only half a custom role's revocation can reach. A route that checked
88
+ * one and not the other would open a door the rules keep shut.
89
+ */ const writerRole = role === 'owner' || role === 'admin' || role === 'editor';
90
+ const suspended = (member == null ? void 0 : member.orgSuspended) === true;
91
+ if (!member || !writerRole || suspended) {
92
+ return refuse(403, 'Your organization role does not allow editing the CRM.');
93
+ }
94
+ if (!await memberHasOrgPermission(orgId, member, 'data.manage')) {
95
+ return refuse(403, 'Your organization role does not allow editing the CRM.');
96
+ }
97
+ }
98
+ const suite = suiteAct ? crmSuiteRefusal(org, suiteAct) : null;
99
+ if (suite) return {
100
+ ok: false,
101
+ status: suite.status,
102
+ body: suite.body
103
+ };
104
+ return {
105
+ ok: true,
106
+ uid: decoded.uid,
107
+ staff,
108
+ orgId,
109
+ org: org != null ? org : {},
110
+ member,
111
+ level: 'site'
112
+ };
113
+ }
114
+ /**
115
+ * The rules' `canReadScoped()`, for a document the route has in hand. An
116
+ * org-level writer was admitted as org-wide, and an org-wide member reads
117
+ * every row.
118
+ */ export const canReach = (writer, visibleTo)=>writer.staff || writer.level === 'org' || isOrgWideMember(writer.member) || memberCanSee(writer.member, visibleTo);
119
+ /**
120
+ * The records the task names carry `nextTaskAtMs` (AGL-2661), recomputed
121
+ * after every write here. Its own catch: the task IS saved by now, and a
122
+ * denormalized figure that could not move is logged and left for the
123
+ * Fields section's recompute, not reported as a task that failed to save.
124
+ */ async function settleNextActivity(orgId, links) {
125
+ try {
126
+ await recomputeCrmNextTaskAt(firebaseAdmin.app().firestore(), orgId, links.map((link)=>crmNextActivityLinksOf(link)));
127
+ } catch (error) {
128
+ console.error('[crm] next activity could not be recomputed', orgId, error);
129
+ }
130
+ }
131
+ /**
132
+ * The console path the assignee's notification opens: the record the task
133
+ * is for, in the hub, or the tasks list when it is for nobody in particular.
134
+ *
135
+ * In the `/{hostDocId}/rest` shape every host notification uses — the
136
+ * console rewrites it to `/{orgSlug}/hosts/{subdomain}/rest` when the link
137
+ * is followed, which is why `hostId` and `orgId` travel on the document. An
138
+ * organization task has no site to open under, so its link is the `/org`
139
+ * shape the console rewrites onto the organization's own hub.
140
+ */ function assignmentLink(hostId, fields) {
141
+ const base = hostId ? `/${hostId}/crm` : '/org/crm';
142
+ if (fields.contactId) return `${base}/contacts/${encodeURIComponent(fields.contactId)}`;
143
+ if (fields.dealId) return `${base}/deals/${encodeURIComponent(fields.dealId)}`;
144
+ if (fields.companyId) return `${base}/companies/${encodeURIComponent(fields.companyId)}`;
145
+ return `${base}/tasks`;
146
+ }
147
+ /**
148
+ * The editable fields as a Firestore write.
149
+ *
150
+ * The optional ids and the assignee are ABSENT on the document when unset,
151
+ * never `null` — the record cards query `where('contactId', '==', id)` and
152
+ * the "My tasks" view `where('assigneeUid', '==', uid)`, and neither is
153
+ * helped by a null. So a create leaves an unset optional out, and an update
154
+ * DELETES it: an assignee cleared in the drawer has to come off the
155
+ * document, and an update that merely omitted the key would keep them.
156
+ * `dueAtMs` is the one field written as `null` when unset, because every
157
+ * view orders by it and a document missing the field drops out of an
158
+ * `orderBy` entirely.
159
+ */ function storedFields(fields, mode) {
160
+ const absent = mode === 'update' ? FieldValue.delete() : undefined;
161
+ const optional = (value)=>value ? {
162
+ present: true,
163
+ value
164
+ } : {
165
+ present: mode === 'update',
166
+ value: absent
167
+ };
168
+ const out = {
169
+ title: fields.title,
170
+ kind: fields.kind,
171
+ priority: fields.priority,
172
+ dueAtMs: fields.dueAtMs,
173
+ notes: fields.notes
174
+ };
175
+ for (const [key, value] of [
176
+ [
177
+ 'assigneeUid',
178
+ fields.assigneeUid
179
+ ],
180
+ [
181
+ 'contactId',
182
+ fields.contactId
183
+ ],
184
+ [
185
+ 'companyId',
186
+ fields.companyId
187
+ ],
188
+ [
189
+ 'dealId',
190
+ fields.dealId
191
+ ]
192
+ ]){
193
+ const slot = optional(value);
194
+ if (slot.present) out[key] = slot.value;
195
+ }
196
+ return out;
197
+ }
198
+ /**
199
+ * The reminder a save leaves (AGL-2659), as a Firestore write.
200
+ *
201
+ * `crmTaskReminderAfterEdit` decides which reminder the task ends up with;
202
+ * this turns the decision into fields. Written as `null` when unset, like
203
+ * `dueAtMs`, so the document says the reminder was decided. A reminder that
204
+ * MOVED — to a new time, or to none — is a reminder not yet sent, so the
205
+ * runner's mark comes off with it; one that stayed keeps its mark, which is
206
+ * what stops a title correction from re-sending last week's reminder.
207
+ */ function reminderFields(fields, existing) {
208
+ var _existing_get, _existing_get1;
209
+ const previous = existing ? {
210
+ dueAtMs: (_existing_get = existing.get('dueAtMs')) != null ? _existing_get : null,
211
+ remindAtMs: (_existing_get1 = existing.get('remindAtMs')) != null ? _existing_get1 : null
212
+ } : null;
213
+ const remindAtMs = crmTaskReminderAfterEdit({
214
+ dueAtMs: fields.dueAtMs,
215
+ remindAtMs: fields.remindAtMs,
216
+ previous
217
+ });
218
+ const out = {
219
+ remindAtMs
220
+ };
221
+ if (previous && remindAtMs !== previous.remindAtMs) {
222
+ out['reminderSentAtMs'] = FieldValue.delete();
223
+ }
224
+ return out;
225
+ }
226
+ const tasksCollection = (orgId)=>firebaseAdmin.app().firestore().collection('orgs').doc(orgId).collection(CRM_COLLECTIONS.tasks);
227
+ /**
228
+ * Whether a uid names a member of the org, answered once per uid across a
229
+ * batch: a bar reassigning forty tasks to one person asks the roster once.
230
+ */ function rosterOf(orgId) {
231
+ const known = new Map();
232
+ return (uid)=>{
233
+ let answer = known.get(uid);
234
+ if (!answer) {
235
+ answer = resolveOrgMembership(uid, orgId).then((found)=>Boolean(found == null ? void 0 : found.member)).catch(()=>false);
236
+ known.set(uid, answer);
237
+ }
238
+ return answer;
239
+ };
240
+ }
241
+ /** Tell the assignee, when they are somebody new and somebody else. */ async function notifyAssignee(writer, fields, previousAssignee, hostId) {
242
+ const assignee = fields.assigneeUid;
243
+ const notified = Boolean(assignee && assignee !== writer.uid && assignee !== previousAssignee);
244
+ if (!notified || !assignee) return false;
245
+ const due = typeof fields.dueAtMs === 'number' ? ` · due ${new Date(fields.dueAtMs).toLocaleString()}` : '';
246
+ await notifyUsers([
247
+ assignee
248
+ ], _extends({
249
+ type: 'content.taskAssigned',
250
+ title: 'Task assigned to you',
251
+ body: `${fields.title}${due}`,
252
+ link: assignmentLink(hostId, fields),
253
+ orgId: writer.orgId
254
+ }, hostId ? {
255
+ hostId
256
+ } : {}));
257
+ return true;
258
+ }
259
+ /**
260
+ * Rewrite one existing task's editable fields, and tell a new assignee.
261
+ *
262
+ * `visibleTo` is not touched: the rules let only an org-wide member move a
263
+ * record's scope, and this route is not the place that does it. `hostId`
264
+ * and `createdByUid` are provenance and never rewritten. The notification
265
+ * opens under the site the caller is on, or — at the organization level —
266
+ * under the task's own site, and under the org hub for a task with none.
267
+ */ async function updateTask(writer, scope, tasks, taskId, fields, onRoster) {
268
+ var _existing_get, _existing_get1;
269
+ if (fields.assigneeUid && !await onRoster(fields.assigneeUid)) {
270
+ return refuse(400, 'The assignee is not a member of this organization.');
271
+ }
272
+ const existing = await tasks.doc(taskId).get();
273
+ if (!existing.exists) return refuse(404, 'That task no longer exists.');
274
+ if (!canReach(writer, existing.get('visibleTo'))) {
275
+ return refuse(403, 'That task is not visible to you.');
276
+ }
277
+ const previousAssignee = String((_existing_get = existing.get('assigneeUid')) != null ? _existing_get : '') || null;
278
+ const previousLinks = crmNextActivityLinksOf(existing.data());
279
+ await tasks.doc(taskId).update(_extends({}, storedFields(fields, 'update'), reminderFields(fields, existing), {
280
+ updatedAt: FieldValue.serverTimestamp()
281
+ }));
282
+ // Both sides: a task moved off one deal onto another leaves neither stale.
283
+ await settleNextActivity(writer.orgId, [
284
+ previousLinks,
285
+ fields
286
+ ]);
287
+ const linkHostId = scope.level === 'site' ? scope.hostId : String((_existing_get1 = existing.get('hostId')) != null ? _existing_get1 : '').trim() || null;
288
+ const notified = await notifyAssignee(writer, fields, previousAssignee, linkHostId);
289
+ return {
290
+ ok: true,
291
+ notified
292
+ };
293
+ }
294
+ /**
295
+ * Where a NEW task is filed from: the mounted site, or at the organization
296
+ * level the site the body names — which has to be one of THIS org's, or an
297
+ * org-wide member of one org could stamp a task with another org's site
298
+ * token — or no site at all, the organization's own.
299
+ */ async function resolveFiledFrom(writer, scope) {
300
+ if (scope.level === 'site') return {
301
+ ok: true,
302
+ hostId: scope.hostId
303
+ };
304
+ if (!scope.hostId) return {
305
+ ok: true,
306
+ hostId: null
307
+ };
308
+ const owner = await getOrgForHost(scope.hostId).catch(()=>null);
309
+ if (!owner || owner.orgId !== writer.orgId) {
310
+ return refuse(400, 'That site is not one of this organization’s.');
311
+ }
312
+ return {
313
+ ok: true,
314
+ hostId: scope.hostId
315
+ };
316
+ }
317
+ /**
318
+ * Create one task, stamped with its scope and provenance.
319
+ *
320
+ * The scope every CRM creator stamps for a task filed from a site: the
321
+ * whole org when the org has chosen that, and otherwise the sites this
322
+ * site presents as one sender with — which, undeclared, is this site
323
+ * alone. A scoped member creating a record they could not then see is
324
+ * refused, which is the rules' `canCreateScoped()` said before the write
325
+ * instead of after. An organization task — no site — carries
326
+ * `CRM_ORG_TASK_SCOPE` and `hostId: null`.
327
+ */ async function createTask(writer, scope, tasks, fields, onRoster) {
328
+ if (fields.assigneeUid && !await onRoster(fields.assigneeUid)) {
329
+ return refuse(400, 'The assignee is not a member of this organization.');
330
+ }
331
+ const filed = await resolveFiledFrom(writer, scope);
332
+ if (filed.ok === false) return filed;
333
+ const { hostId } = filed;
334
+ const visibleTo = hostId ? crmScopeTokens(writer.org, consentGroupForHost(writer.org, hostId)) : [
335
+ ...CRM_ORG_TASK_SCOPE
336
+ ];
337
+ if (!canReach(writer, visibleTo)) {
338
+ return refuse(403, 'Your access to this organization does not reach this site.');
339
+ }
340
+ const ref = tasks.doc();
341
+ await ref.set(_extends({}, storedFields(fields, 'create'), reminderFields(fields, null), {
342
+ status: 'open',
343
+ completedAtMs: null,
344
+ visibleTo,
345
+ hostId,
346
+ createdByUid: writer.uid,
347
+ createdAt: FieldValue.serverTimestamp(),
348
+ updatedAt: FieldValue.serverTimestamp()
349
+ }));
350
+ await settleNextActivity(writer.orgId, [
351
+ fields
352
+ ]);
353
+ const notified = await notifyAssignee(writer, fields, null, hostId);
354
+ return {
355
+ ok: true,
356
+ taskId: ref.id,
357
+ notified
358
+ };
359
+ }
360
+ /**
361
+ * `POST crm/task-save` — create or update a task, and tell its assignee.
362
+ *
363
+ * Body: `{ hostId, taskId?, task: CrmTaskFields }` under a site;
364
+ * `{ orgId, hostId?, taskId?, task }` at the organization level; or the
365
+ * org-level batch `{ orgId, tasks: [{ taskId, task }] }`. Answers
366
+ * `{ ok, taskId, notified }`, or `{ ok, results }` for the batch.
367
+ *
368
+ * The NOTIFICATION fires when the saved assignee is somebody other than the
369
+ * person saving AND is not who the task was already assigned to. Assigning
370
+ * a task to yourself is a note to self; re-saving a task's title does not
371
+ * re-announce it to the person who already has it. The assignee must be a
372
+ * member of the org — a uid nobody can find in the roster is refused rather
373
+ * than written, because a notification to a stranger's inbox is the one
374
+ * thing this route must never do.
375
+ */ export const crmTaskSaveHandler = async (req, res)=>{
376
+ var _ref;
377
+ var _req_body, _req_body1, _req_body2;
378
+ if (req.method !== 'POST') {
379
+ res.setHeader('Allow', 'POST');
380
+ res.status(405).json({
381
+ error: 'Method not allowed'
382
+ });
383
+ return;
384
+ }
385
+ const scope = readCrmRouteScope(req.body);
386
+ if (!scope) {
387
+ res.status(400).json({
388
+ error: 'Missing hostId'
389
+ });
390
+ return;
391
+ }
392
+ if (Array.isArray((_req_body = req.body) == null ? void 0 : _req_body.tasks)) {
393
+ await saveBatch(req, res, scope);
394
+ return;
395
+ }
396
+ const taskId = String((_ref = (_req_body1 = req.body) == null ? void 0 : _req_body1.taskId) != null ? _ref : '').trim();
397
+ const read = readCrmTaskFields((_req_body2 = req.body) == null ? void 0 : _req_body2.task);
398
+ if (read.ok === false) {
399
+ res.status(400).json({
400
+ error: read.error
401
+ });
402
+ return;
403
+ }
404
+ const fields = read.fields;
405
+ try {
406
+ const writer = await authorizeCrmWriter(req, scope);
407
+ if (writer.ok === false) {
408
+ res.status(writer.status).json(writer.body);
409
+ return;
410
+ }
411
+ const tasks = tasksCollection(writer.orgId);
412
+ const onRoster = rosterOf(writer.orgId);
413
+ let body;
414
+ if (taskId) {
415
+ const saved = await updateTask(writer, scope, tasks, taskId, fields, onRoster);
416
+ if (saved.ok === false) {
417
+ res.status(saved.status).json(saved.body);
418
+ return;
419
+ }
420
+ body = {
421
+ ok: true,
422
+ taskId,
423
+ notified: saved.notified
424
+ };
425
+ } else {
426
+ const saved = await createTask(writer, scope, tasks, fields, onRoster);
427
+ if (saved.ok === false) {
428
+ res.status(saved.status).json(saved.body);
429
+ return;
430
+ }
431
+ body = {
432
+ ok: true,
433
+ taskId: saved.taskId,
434
+ notified: saved.notified
435
+ };
436
+ }
437
+ res.status(200).json(body);
438
+ } catch (error) {
439
+ console.error('[crm] task-save failed', error);
440
+ res.status(500).json({
441
+ error: 'The task could not be saved.'
442
+ });
443
+ }
444
+ };
445
+ /**
446
+ * The batch: every entry read before any is written, so a body with one
447
+ * unreadable entry is refused whole rather than half-applied; then each
448
+ * task in order, each answered on its own.
449
+ */ async function saveBatch(req, res, scope) {
450
+ var _req_body;
451
+ if (scope.level !== 'org') {
452
+ res.status(400).json({
453
+ error: 'A batch of tasks is saved at the organization level only.'
454
+ });
455
+ return;
456
+ }
457
+ const entries = ((_req_body = req.body) == null ? void 0 : _req_body.tasks).slice(0, CRM_TASK_BATCH_MAX + 1);
458
+ if (!entries.length || entries.length > CRM_TASK_BATCH_MAX) {
459
+ res.status(400).json({
460
+ error: `Save between 1 and ${CRM_TASK_BATCH_MAX} tasks at a time.`
461
+ });
462
+ return;
463
+ }
464
+ const parsed = [];
465
+ for (const entry of entries){
466
+ var _raw_taskId;
467
+ const raw = entry != null ? entry : {};
468
+ const taskId = String((_raw_taskId = raw['taskId']) != null ? _raw_taskId : '').trim();
469
+ const read = readCrmTaskFields(raw['task']);
470
+ if (!taskId || read.ok === false) {
471
+ res.status(400).json({
472
+ error: read.ok === false ? read.error : 'Every task in a batch names its taskId.'
473
+ });
474
+ return;
475
+ }
476
+ parsed.push({
477
+ taskId,
478
+ fields: read.fields
479
+ });
480
+ }
481
+ try {
482
+ const writer = await authorizeCrmWriter(req, scope);
483
+ if (writer.ok === false) {
484
+ res.status(writer.status).json(writer.body);
485
+ return;
486
+ }
487
+ const tasks = tasksCollection(writer.orgId);
488
+ const onRoster = rosterOf(writer.orgId);
489
+ const results = [];
490
+ for (const { taskId, fields } of parsed){
491
+ const saved = await updateTask(writer, scope, tasks, taskId, fields, onRoster);
492
+ results.push(saved.ok === false ? {
493
+ taskId,
494
+ ok: false,
495
+ error: saved.body.error
496
+ } : {
497
+ taskId,
498
+ ok: true,
499
+ notified: saved.notified
500
+ });
501
+ }
502
+ const body = {
503
+ ok: true,
504
+ results
505
+ };
506
+ res.status(200).json(body);
507
+ } catch (error) {
508
+ console.error('[crm] task-save batch failed', error);
509
+ res.status(500).json({
510
+ error: 'The tasks could not be saved.'
511
+ });
512
+ }
513
+ }
514
+ /**
515
+ * Mark one task done and fire `taskCompleted` on the site whose automations
516
+ * hear it: under a site, the site whose console ticked the box — workflows
517
+ * belong to a site, and the person is on that site's console. At the
518
+ * organization level there is no such console, so the event goes to the
519
+ * task's OWN site, and an organization task, having none, fires nothing.
520
+ * The task's own `hostId` rides in the payload as `taskHostId` either way,
521
+ * for a workflow that cares about the difference.
522
+ *
523
+ * Idempotent on purpose: two people ticking the same box, or one person
524
+ * double-clicking, completes a task once and fires its event once. The
525
+ * second call reads the stored `completedAtMs` back and writes nothing.
526
+ */ async function completeTask(writer, scope, tasks, taskId) {
527
+ var _task_hostId;
528
+ const ref = tasks.doc(taskId);
529
+ const snapshot = await ref.get();
530
+ if (!snapshot.exists) {
531
+ return {
532
+ taskId,
533
+ ok: false,
534
+ error: 'That task no longer exists.'
535
+ };
536
+ }
537
+ const task = snapshot.data();
538
+ if (!canReach(writer, task.visibleTo)) {
539
+ return {
540
+ taskId,
541
+ ok: false,
542
+ error: 'That task is not visible to you.'
543
+ };
544
+ }
545
+ if (task.status === 'done') {
546
+ var _task_completedAtMs;
547
+ return {
548
+ taskId,
549
+ ok: true,
550
+ completedAtMs: Number((_task_completedAtMs = task.completedAtMs) != null ? _task_completedAtMs : 0),
551
+ alreadyDone: true
552
+ };
553
+ }
554
+ const completedAtMs = Date.now();
555
+ await ref.update(_extends({
556
+ status: 'done',
557
+ completedAtMs,
558
+ completedByUid: writer.uid
559
+ }, crmTaskReminderPending(task) ? {
560
+ remindAtMs: null
561
+ } : {}, {
562
+ updatedAt: FieldValue.serverTimestamp()
563
+ }));
564
+ await settleNextActivity(writer.orgId, [
565
+ task
566
+ ]);
567
+ const eventHostId = scope.level === 'site' ? scope.hostId : String((_task_hostId = task.hostId) != null ? _task_hostId : '').trim();
568
+ if (eventHostId) {
569
+ var _task_title, _task_kind, _task_priority, _task_assigneeUid, _task_createdByUid, _task_contactId, _task_companyId, _task_dealId, _task_hostId1;
570
+ /*
571
+ * The payload is what a workflow filter can read: every field a string,
572
+ * number or boolean, and every optional one present as an empty string
573
+ * rather than absent, so `contactId != ""` is a filter somebody can
574
+ * write without knowing whether the key exists.
575
+ */ await emitHostEvent(eventHostId, 'taskCompleted', {
576
+ taskId,
577
+ title: String((_task_title = task.title) != null ? _task_title : ''),
578
+ kind: String((_task_kind = task.kind) != null ? _task_kind : ''),
579
+ priority: String((_task_priority = task.priority) != null ? _task_priority : ''),
580
+ dueAtMs: typeof task.dueAtMs === 'number' ? task.dueAtMs : 0,
581
+ completedAtMs,
582
+ completedByUid: writer.uid,
583
+ assigneeUid: String((_task_assigneeUid = task.assigneeUid) != null ? _task_assigneeUid : ''),
584
+ createdByUid: String((_task_createdByUid = task.createdByUid) != null ? _task_createdByUid : ''),
585
+ contactId: String((_task_contactId = task.contactId) != null ? _task_contactId : ''),
586
+ companyId: String((_task_companyId = task.companyId) != null ? _task_companyId : ''),
587
+ dealId: String((_task_dealId = task.dealId) != null ? _task_dealId : ''),
588
+ taskHostId: String((_task_hostId1 = task.hostId) != null ? _task_hostId1 : '')
589
+ });
590
+ }
591
+ return {
592
+ taskId,
593
+ ok: true,
594
+ completedAtMs
595
+ };
596
+ }
597
+ /** A per-task outcome as the single-task route has always answered. */ const completeStatus = (outcome)=>outcome.error === 'That task no longer exists.' ? 404 : 403;
598
+ /**
599
+ * `POST crm/task-complete` — mark a task done and fire `taskCompleted`.
600
+ *
601
+ * Body: `{ hostId, taskId }` under a site, `{ orgId, taskId }` at the
602
+ * organization level, or the org-level batch `{ orgId, taskIds }`. Answers
603
+ * `{ ok, completedAtMs, alreadyDone? }`, or `{ ok, results }` for the batch.
604
+ */ export const crmTaskCompleteHandler = async (req, res)=>{
605
+ var _ref;
606
+ var _req_body, _req_body1;
607
+ if (req.method !== 'POST') {
608
+ res.setHeader('Allow', 'POST');
609
+ res.status(405).json({
610
+ error: 'Method not allowed'
611
+ });
612
+ return;
613
+ }
614
+ const scope = readCrmRouteScope(req.body);
615
+ if (Array.isArray((_req_body = req.body) == null ? void 0 : _req_body.taskIds)) {
616
+ await completeBatch(req, res, scope);
617
+ return;
618
+ }
619
+ const taskId = String((_ref = (_req_body1 = req.body) == null ? void 0 : _req_body1.taskId) != null ? _ref : '').trim();
620
+ if (!scope || !taskId) {
621
+ res.status(400).json({
622
+ error: 'Missing hostId or taskId'
623
+ });
624
+ return;
625
+ }
626
+ try {
627
+ const writer = await authorizeCrmWriter(req, scope);
628
+ if (writer.ok === false) {
629
+ res.status(writer.status).json(writer.body);
630
+ return;
631
+ }
632
+ const outcome = await completeTask(writer, scope, tasksCollection(writer.orgId), taskId);
633
+ if (outcome.ok === false) {
634
+ res.status(completeStatus(outcome)).json({
635
+ error: outcome.error
636
+ });
637
+ return;
638
+ }
639
+ const body = _extends({
640
+ ok: true,
641
+ completedAtMs: outcome.completedAtMs
642
+ }, outcome.alreadyDone ? {
643
+ alreadyDone: true
644
+ } : {});
645
+ res.status(200).json(body);
646
+ } catch (error) {
647
+ console.error('[crm] task-complete failed', error);
648
+ res.status(500).json({
649
+ error: 'The task could not be completed.'
650
+ });
651
+ }
652
+ };
653
+ /**
654
+ * The batch: the ids deduplicated and capped, then each task in order —
655
+ * in order rather than at once, because each completion may run a site's
656
+ * workflows, and two hundred runners started together is the burst the
657
+ * per-task client call was written to avoid.
658
+ */ async function completeBatch(req, res, scope) {
659
+ var _req_body;
660
+ if (!scope || scope.level !== 'org') {
661
+ res.status(400).json({
662
+ error: 'A batch of tasks is completed at the organization level only.'
663
+ });
664
+ return;
665
+ }
666
+ const taskIds = [
667
+ ...new Set(((_req_body = req.body) == null ? void 0 : _req_body.taskIds).map((id)=>String(id != null ? id : '').trim()).filter(Boolean))
668
+ ];
669
+ if (!taskIds.length || taskIds.length > CRM_TASK_BATCH_MAX) {
670
+ res.status(400).json({
671
+ error: `Complete between 1 and ${CRM_TASK_BATCH_MAX} tasks at a time.`
672
+ });
673
+ return;
674
+ }
675
+ try {
676
+ const writer = await authorizeCrmWriter(req, scope);
677
+ if (writer.ok === false) {
678
+ res.status(writer.status).json(writer.body);
679
+ return;
680
+ }
681
+ const tasks = tasksCollection(writer.orgId);
682
+ const results = [];
683
+ for (const taskId of taskIds){
684
+ results.push(await completeTask(writer, scope, tasks, taskId));
685
+ }
686
+ const body = {
687
+ ok: true,
688
+ results
689
+ };
690
+ res.status(200).json(body);
691
+ } catch (error) {
692
+ console.error('[crm] task-complete batch failed', error);
693
+ res.status(500).json({
694
+ error: 'The tasks could not be completed.'
695
+ });
696
+ }
697
+ }
698
+
699
+ //# sourceMappingURL=task-routes.js.map