@kelpie/server 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (679) hide show
  1. package/dist/lib/consumerEmailDomains.d.ts +2 -0
  2. package/dist/lib/consumerEmailDomains.d.ts.map +1 -0
  3. package/dist/lib/consumerEmailDomains.js +62 -0
  4. package/dist/lib/consumerEmailDomains.js.map +1 -0
  5. package/dist/lib/email.d.ts +7 -0
  6. package/dist/lib/email.d.ts.map +1 -1
  7. package/dist/lib/email.js.map +1 -1
  8. package/dist/lib/emailContent.d.ts +33 -0
  9. package/dist/lib/emailContent.d.ts.map +1 -0
  10. package/dist/lib/emailContent.js +54 -0
  11. package/dist/lib/emailContent.js.map +1 -0
  12. package/dist/lib/emailDomainAutoLink.d.ts +27 -0
  13. package/dist/lib/emailDomainAutoLink.d.ts.map +1 -0
  14. package/dist/lib/emailDomainAutoLink.js +119 -0
  15. package/dist/lib/emailDomainAutoLink.js.map +1 -0
  16. package/dist/lib/ids.d.ts +13 -0
  17. package/dist/lib/ids.d.ts.map +1 -1
  18. package/dist/lib/ids.js +13 -0
  19. package/dist/lib/ids.js.map +1 -1
  20. package/dist/modules/activities/repository.d.ts.map +1 -1
  21. package/dist/modules/activities/repository.js +19 -20
  22. package/dist/modules/activities/repository.js.map +1 -1
  23. package/dist/modules/activities/wording.d.ts +12 -0
  24. package/dist/modules/activities/wording.d.ts.map +1 -1
  25. package/dist/modules/activities/wording.js +16 -0
  26. package/dist/modules/activities/wording.js.map +1 -1
  27. package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
  28. package/dist/modules/agent-tasks/catalog.js +62 -0
  29. package/dist/modules/agent-tasks/catalog.js.map +1 -1
  30. package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
  31. package/dist/modules/agent-tasks/resolve.js +42 -9
  32. package/dist/modules/agent-tasks/resolve.js.map +1 -1
  33. package/dist/modules/agent-tasks/routes.d.ts +2 -0
  34. package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
  35. package/dist/modules/attachedRecords.d.ts +6 -1
  36. package/dist/modules/attachedRecords.d.ts.map +1 -1
  37. package/dist/modules/attachedRecords.js +18 -2
  38. package/dist/modules/attachedRecords.js.map +1 -1
  39. package/dist/modules/auth/preferences.d.ts +11 -1
  40. package/dist/modules/auth/preferences.d.ts.map +1 -1
  41. package/dist/modules/auth/preferences.js +11 -0
  42. package/dist/modules/auth/preferences.js.map +1 -1
  43. package/dist/modules/auth/routes.d.ts.map +1 -1
  44. package/dist/modules/auth/routes.js +18 -0
  45. package/dist/modules/auth/routes.js.map +1 -1
  46. package/dist/modules/auth/schema.d.ts +20 -0
  47. package/dist/modules/auth/schema.d.ts.map +1 -1
  48. package/dist/modules/auth/schema.js +11 -1
  49. package/dist/modules/auth/schema.js.map +1 -1
  50. package/dist/modules/auth/service.d.ts.map +1 -1
  51. package/dist/modules/auth/service.js +27 -3
  52. package/dist/modules/auth/service.js.map +1 -1
  53. package/dist/modules/companies/index.d.ts.map +1 -1
  54. package/dist/modules/companies/index.js +3 -1
  55. package/dist/modules/companies/index.js.map +1 -1
  56. package/dist/modules/companies/repository.d.ts +2 -0
  57. package/dist/modules/companies/repository.d.ts.map +1 -1
  58. package/dist/modules/companies/repository.js +1 -0
  59. package/dist/modules/companies/repository.js.map +1 -1
  60. package/dist/modules/companies/routes.d.ts +16 -0
  61. package/dist/modules/companies/routes.d.ts.map +1 -1
  62. package/dist/modules/companies/routes.js +18 -0
  63. package/dist/modules/companies/routes.js.map +1 -1
  64. package/dist/modules/companies/schema.d.ts +37 -0
  65. package/dist/modules/companies/schema.d.ts.map +1 -1
  66. package/dist/modules/companies/schema.js +10 -1
  67. package/dist/modules/companies/schema.js.map +1 -1
  68. package/dist/modules/companies/service.d.ts +6 -0
  69. package/dist/modules/companies/service.d.ts.map +1 -1
  70. package/dist/modules/companies/service.js +45 -11
  71. package/dist/modules/companies/service.js.map +1 -1
  72. package/dist/modules/consent-purposes/capabilities.d.ts +7 -0
  73. package/dist/modules/consent-purposes/capabilities.d.ts.map +1 -0
  74. package/dist/modules/consent-purposes/capabilities.js +10 -0
  75. package/dist/modules/consent-purposes/capabilities.js.map +1 -0
  76. package/dist/modules/consent-purposes/events.d.ts +38 -0
  77. package/dist/modules/consent-purposes/events.d.ts.map +1 -0
  78. package/dist/modules/consent-purposes/events.js +17 -0
  79. package/dist/modules/consent-purposes/events.js.map +1 -0
  80. package/dist/modules/consent-purposes/index.d.ts +13 -0
  81. package/dist/modules/consent-purposes/index.d.ts.map +1 -0
  82. package/dist/modules/consent-purposes/index.js +41 -0
  83. package/dist/modules/consent-purposes/index.js.map +1 -0
  84. package/dist/modules/consent-purposes/repository.d.ts +21 -0
  85. package/dist/modules/consent-purposes/repository.d.ts.map +1 -0
  86. package/dist/modules/consent-purposes/repository.js +98 -0
  87. package/dist/modules/consent-purposes/repository.js.map +1 -0
  88. package/dist/modules/consent-purposes/routes.d.ts +39 -0
  89. package/dist/modules/consent-purposes/routes.d.ts.map +1 -0
  90. package/dist/modules/consent-purposes/routes.js +79 -0
  91. package/dist/modules/consent-purposes/routes.js.map +1 -0
  92. package/dist/modules/consent-purposes/schema.d.ts +175 -0
  93. package/dist/modules/consent-purposes/schema.d.ts.map +1 -0
  94. package/dist/modules/consent-purposes/schema.js +35 -0
  95. package/dist/modules/consent-purposes/schema.js.map +1 -0
  96. package/dist/modules/consent-purposes/service.d.ts +50 -0
  97. package/dist/modules/consent-purposes/service.d.ts.map +1 -0
  98. package/dist/modules/consent-purposes/service.js +263 -0
  99. package/dist/modules/consent-purposes/service.js.map +1 -0
  100. package/dist/modules/consent-purposes/starters.d.ts +17 -0
  101. package/dist/modules/consent-purposes/starters.d.ts.map +1 -0
  102. package/dist/modules/consent-purposes/starters.js +15 -0
  103. package/dist/modules/consent-purposes/starters.js.map +1 -0
  104. package/dist/modules/consent-purposes/tools.d.ts +4 -0
  105. package/dist/modules/consent-purposes/tools.d.ts.map +1 -0
  106. package/dist/modules/consent-purposes/tools.js +29 -0
  107. package/dist/modules/consent-purposes/tools.js.map +1 -0
  108. package/dist/modules/core.d.ts.map +1 -1
  109. package/dist/modules/core.js +21 -0
  110. package/dist/modules/core.js.map +1 -1
  111. package/dist/modules/custom-fields/capabilities.d.ts +12 -0
  112. package/dist/modules/custom-fields/capabilities.d.ts.map +1 -0
  113. package/dist/modules/custom-fields/capabilities.js +15 -0
  114. package/dist/modules/custom-fields/capabilities.js.map +1 -0
  115. package/dist/modules/custom-fields/events.d.ts +49 -0
  116. package/dist/modules/custom-fields/events.d.ts.map +1 -0
  117. package/dist/modules/custom-fields/events.js +25 -0
  118. package/dist/modules/custom-fields/events.js.map +1 -0
  119. package/dist/modules/custom-fields/index.d.ts +19 -0
  120. package/dist/modules/custom-fields/index.d.ts.map +1 -0
  121. package/dist/modules/custom-fields/index.js +46 -0
  122. package/dist/modules/custom-fields/index.js.map +1 -0
  123. package/dist/modules/custom-fields/repository.d.ts +37 -0
  124. package/dist/modules/custom-fields/repository.d.ts.map +1 -0
  125. package/dist/modules/custom-fields/repository.js +144 -0
  126. package/dist/modules/custom-fields/repository.js.map +1 -0
  127. package/dist/modules/custom-fields/routes.d.ts +44 -0
  128. package/dist/modules/custom-fields/routes.d.ts.map +1 -0
  129. package/dist/modules/custom-fields/routes.js +103 -0
  130. package/dist/modules/custom-fields/routes.js.map +1 -0
  131. package/dist/modules/custom-fields/schema.d.ts +215 -0
  132. package/dist/modules/custom-fields/schema.d.ts.map +1 -0
  133. package/dist/modules/custom-fields/schema.js +43 -0
  134. package/dist/modules/custom-fields/schema.js.map +1 -0
  135. package/dist/modules/custom-fields/service.d.ts +57 -0
  136. package/dist/modules/custom-fields/service.d.ts.map +1 -0
  137. package/dist/modules/custom-fields/service.js +273 -0
  138. package/dist/modules/custom-fields/service.js.map +1 -0
  139. package/dist/modules/custom-fields/tools.d.ts +4 -0
  140. package/dist/modules/custom-fields/tools.d.ts.map +1 -0
  141. package/dist/modules/custom-fields/tools.js +38 -0
  142. package/dist/modules/custom-fields/tools.js.map +1 -0
  143. package/dist/modules/custom-fields/values.d.ts +49 -0
  144. package/dist/modules/custom-fields/values.d.ts.map +1 -0
  145. package/dist/modules/custom-fields/values.js +249 -0
  146. package/dist/modules/custom-fields/values.js.map +1 -0
  147. package/dist/modules/custom-fields/wire.d.ts +12 -0
  148. package/dist/modules/custom-fields/wire.d.ts.map +1 -0
  149. package/dist/modules/custom-fields/wire.js +30 -0
  150. package/dist/modules/custom-fields/wire.js.map +1 -0
  151. package/dist/modules/dashboard/repository.d.ts.map +1 -1
  152. package/dist/modules/dashboard/repository.js +4 -3
  153. package/dist/modules/dashboard/repository.js.map +1 -1
  154. package/dist/modules/deals/index.d.ts +2 -1
  155. package/dist/modules/deals/index.d.ts.map +1 -1
  156. package/dist/modules/deals/index.js +5 -2
  157. package/dist/modules/deals/index.js.map +1 -1
  158. package/dist/modules/deals/repository.d.ts +0 -16
  159. package/dist/modules/deals/repository.d.ts.map +1 -1
  160. package/dist/modules/deals/repository.js +6 -76
  161. package/dist/modules/deals/repository.js.map +1 -1
  162. package/dist/modules/deals/routes.d.ts +14 -0
  163. package/dist/modules/deals/routes.d.ts.map +1 -1
  164. package/dist/modules/deals/routes.js +7 -0
  165. package/dist/modules/deals/routes.js.map +1 -1
  166. package/dist/modules/deals/schema.d.ts +20 -42
  167. package/dist/modules/deals/schema.d.ts.map +1 -1
  168. package/dist/modules/deals/schema.js +6 -11
  169. package/dist/modules/deals/schema.js.map +1 -1
  170. package/dist/modules/deals/service.d.ts +13 -2
  171. package/dist/modules/deals/service.d.ts.map +1 -1
  172. package/dist/modules/deals/service.js +43 -20
  173. package/dist/modules/deals/service.js.map +1 -1
  174. package/dist/modules/decisions/repository.d.ts.map +1 -1
  175. package/dist/modules/decisions/repository.js +2 -0
  176. package/dist/modules/decisions/repository.js.map +1 -1
  177. package/dist/modules/decisions/routes.d.ts +1 -0
  178. package/dist/modules/decisions/routes.d.ts.map +1 -1
  179. package/dist/modules/email-domain-linker/index.d.ts +12 -0
  180. package/dist/modules/email-domain-linker/index.d.ts.map +1 -0
  181. package/dist/modules/email-domain-linker/index.js +34 -0
  182. package/dist/modules/email-domain-linker/index.js.map +1 -0
  183. package/dist/modules/email-domain-linker/routes.d.ts +14 -0
  184. package/dist/modules/email-domain-linker/routes.d.ts.map +1 -0
  185. package/dist/modules/email-domain-linker/routes.js +15 -0
  186. package/dist/modules/email-domain-linker/routes.js.map +1 -0
  187. package/dist/modules/email-domain-linker/service.d.ts +37 -0
  188. package/dist/modules/email-domain-linker/service.d.ts.map +1 -0
  189. package/dist/modules/email-domain-linker/service.js +63 -0
  190. package/dist/modules/email-domain-linker/service.js.map +1 -0
  191. package/dist/modules/enquiries/events.d.ts +44 -0
  192. package/dist/modules/enquiries/events.d.ts.map +1 -0
  193. package/dist/modules/enquiries/events.js +19 -0
  194. package/dist/modules/enquiries/events.js.map +1 -0
  195. package/dist/modules/enquiries/index.d.ts +13 -0
  196. package/dist/modules/enquiries/index.d.ts.map +1 -0
  197. package/dist/modules/enquiries/index.js +44 -0
  198. package/dist/modules/enquiries/index.js.map +1 -0
  199. package/dist/modules/enquiries/repository.d.ts +30 -0
  200. package/dist/modules/enquiries/repository.d.ts.map +1 -0
  201. package/dist/modules/enquiries/repository.js +94 -0
  202. package/dist/modules/enquiries/repository.js.map +1 -0
  203. package/dist/modules/enquiries/routes.d.ts +52 -0
  204. package/dist/modules/enquiries/routes.d.ts.map +1 -0
  205. package/dist/modules/enquiries/routes.js +127 -0
  206. package/dist/modules/enquiries/routes.js.map +1 -0
  207. package/dist/modules/enquiries/schema.d.ts +290 -0
  208. package/dist/modules/enquiries/schema.d.ts.map +1 -0
  209. package/dist/modules/enquiries/schema.js +52 -0
  210. package/dist/modules/enquiries/schema.js.map +1 -0
  211. package/dist/modules/enquiries/service.d.ts +85 -0
  212. package/dist/modules/enquiries/service.d.ts.map +1 -0
  213. package/dist/modules/enquiries/service.js +370 -0
  214. package/dist/modules/enquiries/service.js.map +1 -0
  215. package/dist/modules/enquiries/tools.d.ts +4 -0
  216. package/dist/modules/enquiries/tools.d.ts.map +1 -0
  217. package/dist/modules/enquiries/tools.js +50 -0
  218. package/dist/modules/enquiries/tools.js.map +1 -0
  219. package/dist/modules/eventCatalogs.d.ts +4 -0
  220. package/dist/modules/eventCatalogs.d.ts.map +1 -1
  221. package/dist/modules/eventCatalogs.js +4 -0
  222. package/dist/modules/eventCatalogs.js.map +1 -1
  223. package/dist/modules/forms/embed.d.ts +20 -6
  224. package/dist/modules/forms/embed.d.ts.map +1 -1
  225. package/dist/modules/forms/embed.js +359 -43
  226. package/dist/modules/forms/embed.js.map +1 -1
  227. package/dist/modules/forms/events.d.ts +20 -7
  228. package/dist/modules/forms/events.d.ts.map +1 -1
  229. package/dist/modules/forms/events.js +20 -2
  230. package/dist/modules/forms/events.js.map +1 -1
  231. package/dist/modules/forms/fields.d.ts +14 -1
  232. package/dist/modules/forms/fields.d.ts.map +1 -1
  233. package/dist/modules/forms/fields.js +87 -3
  234. package/dist/modules/forms/fields.js.map +1 -1
  235. package/dist/modules/forms/index.d.ts.map +1 -1
  236. package/dist/modules/forms/index.js +12 -1
  237. package/dist/modules/forms/index.js.map +1 -1
  238. package/dist/modules/forms/mapping.d.ts +62 -5
  239. package/dist/modules/forms/mapping.d.ts.map +1 -1
  240. package/dist/modules/forms/mapping.js +139 -5
  241. package/dist/modules/forms/mapping.js.map +1 -1
  242. package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
  243. package/dist/modules/forms/publicRoutes.js +29 -1
  244. package/dist/modules/forms/publicRoutes.js.map +1 -1
  245. package/dist/modules/forms/repository.d.ts +31 -0
  246. package/dist/modules/forms/repository.d.ts.map +1 -1
  247. package/dist/modules/forms/repository.js +90 -1
  248. package/dist/modules/forms/repository.js.map +1 -1
  249. package/dist/modules/forms/routes.d.ts +83 -1
  250. package/dist/modules/forms/routes.d.ts.map +1 -1
  251. package/dist/modules/forms/routes.js +185 -2
  252. package/dist/modules/forms/routes.js.map +1 -1
  253. package/dist/modules/forms/schema.d.ts +672 -1
  254. package/dist/modules/forms/schema.d.ts.map +1 -1
  255. package/dist/modules/forms/schema.js +146 -3
  256. package/dist/modules/forms/schema.js.map +1 -1
  257. package/dist/modules/forms/service.d.ts +54 -1
  258. package/dist/modules/forms/service.d.ts.map +1 -1
  259. package/dist/modules/forms/service.js +338 -28
  260. package/dist/modules/forms/service.js.map +1 -1
  261. package/dist/modules/forms/submission.d.ts +15 -0
  262. package/dist/modules/forms/submission.d.ts.map +1 -1
  263. package/dist/modules/forms/submission.js +418 -40
  264. package/dist/modules/forms/submission.js.map +1 -1
  265. package/dist/modules/import-export/drafts.d.ts +10 -0
  266. package/dist/modules/import-export/drafts.d.ts.map +1 -1
  267. package/dist/modules/import-export/drafts.js +16 -2
  268. package/dist/modules/import-export/drafts.js.map +1 -1
  269. package/dist/modules/import-export/exportRows.d.ts +7 -4
  270. package/dist/modules/import-export/exportRows.d.ts.map +1 -1
  271. package/dist/modules/import-export/exportRows.js +20 -5
  272. package/dist/modules/import-export/exportRows.js.map +1 -1
  273. package/dist/modules/import-export/plan.d.ts +12 -1
  274. package/dist/modules/import-export/plan.d.ts.map +1 -1
  275. package/dist/modules/import-export/plan.js +29 -2
  276. package/dist/modules/import-export/plan.js.map +1 -1
  277. package/dist/modules/import-export/presets.d.ts.map +1 -1
  278. package/dist/modules/import-export/presets.js +10 -0
  279. package/dist/modules/import-export/presets.js.map +1 -1
  280. package/dist/modules/import-export/repository.d.ts +11 -1
  281. package/dist/modules/import-export/repository.d.ts.map +1 -1
  282. package/dist/modules/import-export/repository.js +42 -9
  283. package/dist/modules/import-export/repository.js.map +1 -1
  284. package/dist/modules/import-export/routes.d.ts.map +1 -1
  285. package/dist/modules/import-export/routes.js +4 -0
  286. package/dist/modules/import-export/routes.js.map +1 -1
  287. package/dist/modules/import-export/schema.d.ts +17 -0
  288. package/dist/modules/import-export/schema.d.ts.map +1 -1
  289. package/dist/modules/import-export/schema.js +11 -0
  290. package/dist/modules/import-export/schema.js.map +1 -1
  291. package/dist/modules/import-export/service.d.ts +6 -0
  292. package/dist/modules/import-export/service.d.ts.map +1 -1
  293. package/dist/modules/import-export/service.js +14 -2
  294. package/dist/modules/import-export/service.js.map +1 -1
  295. package/dist/modules/import-export/streams.d.ts.map +1 -1
  296. package/dist/modules/import-export/streams.js +3 -3
  297. package/dist/modules/import-export/streams.js.map +1 -1
  298. package/dist/modules/import-export/tools.d.ts.map +1 -1
  299. package/dist/modules/import-export/tools.js +8 -0
  300. package/dist/modules/import-export/tools.js.map +1 -1
  301. package/dist/modules/import-export/validation.d.ts.map +1 -1
  302. package/dist/modules/import-export/validation.js +22 -1
  303. package/dist/modules/import-export/validation.js.map +1 -1
  304. package/dist/modules/import-export/writes.d.ts.map +1 -1
  305. package/dist/modules/import-export/writes.js +37 -4
  306. package/dist/modules/import-export/writes.js.map +1 -1
  307. package/dist/modules/lists/events.d.ts +42 -0
  308. package/dist/modules/lists/events.d.ts.map +1 -0
  309. package/dist/modules/lists/events.js +16 -0
  310. package/dist/modules/lists/events.js.map +1 -0
  311. package/dist/modules/lists/index.d.ts +10 -0
  312. package/dist/modules/lists/index.d.ts.map +1 -0
  313. package/dist/modules/lists/index.js +35 -0
  314. package/dist/modules/lists/index.js.map +1 -0
  315. package/dist/modules/lists/repository.d.ts +80 -0
  316. package/dist/modules/lists/repository.d.ts.map +1 -0
  317. package/dist/modules/lists/repository.js +178 -0
  318. package/dist/modules/lists/repository.js.map +1 -0
  319. package/dist/modules/lists/routes.d.ts +55 -0
  320. package/dist/modules/lists/routes.d.ts.map +1 -0
  321. package/dist/modules/lists/routes.js +168 -0
  322. package/dist/modules/lists/routes.js.map +1 -0
  323. package/dist/modules/lists/schema.d.ts +281 -0
  324. package/dist/modules/lists/schema.d.ts.map +1 -0
  325. package/dist/modules/lists/schema.js +83 -0
  326. package/dist/modules/lists/schema.js.map +1 -0
  327. package/dist/modules/lists/service.d.ts +82 -0
  328. package/dist/modules/lists/service.d.ts.map +1 -0
  329. package/dist/modules/lists/service.js +262 -0
  330. package/dist/modules/lists/service.js.map +1 -0
  331. package/dist/modules/lists/tools.d.ts +4 -0
  332. package/dist/modules/lists/tools.d.ts.map +1 -0
  333. package/dist/modules/lists/tools.js +86 -0
  334. package/dist/modules/lists/tools.js.map +1 -0
  335. package/dist/modules/mcp/index.d.ts.map +1 -1
  336. package/dist/modules/mcp/index.js +5 -0
  337. package/dist/modules/mcp/index.js.map +1 -1
  338. package/dist/modules/notes/routes.d.ts +1 -0
  339. package/dist/modules/notes/routes.d.ts.map +1 -1
  340. package/dist/modules/opportunities/index.d.ts.map +1 -1
  341. package/dist/modules/opportunities/index.js +3 -1
  342. package/dist/modules/opportunities/index.js.map +1 -1
  343. package/dist/modules/opportunities/repository.d.ts +2 -0
  344. package/dist/modules/opportunities/repository.d.ts.map +1 -1
  345. package/dist/modules/opportunities/repository.js +4 -0
  346. package/dist/modules/opportunities/repository.js.map +1 -1
  347. package/dist/modules/opportunities/routes.d.ts +16 -0
  348. package/dist/modules/opportunities/routes.d.ts.map +1 -1
  349. package/dist/modules/opportunities/routes.js +13 -0
  350. package/dist/modules/opportunities/routes.js.map +1 -1
  351. package/dist/modules/opportunities/schema.d.ts +20 -0
  352. package/dist/modules/opportunities/schema.d.ts.map +1 -1
  353. package/dist/modules/opportunities/schema.js +6 -1
  354. package/dist/modules/opportunities/schema.js.map +1 -1
  355. package/dist/modules/opportunities/service.d.ts +20 -3
  356. package/dist/modules/opportunities/service.d.ts.map +1 -1
  357. package/dist/modules/opportunities/service.js +99 -18
  358. package/dist/modules/opportunities/service.js.map +1 -1
  359. package/dist/modules/opportunities/tools.d.ts.map +1 -1
  360. package/dist/modules/opportunities/tools.js +2 -0
  361. package/dist/modules/opportunities/tools.js.map +1 -1
  362. package/dist/modules/partnerships/index.d.ts.map +1 -1
  363. package/dist/modules/partnerships/index.js +3 -1
  364. package/dist/modules/partnerships/index.js.map +1 -1
  365. package/dist/modules/partnerships/repository.d.ts +0 -17
  366. package/dist/modules/partnerships/repository.d.ts.map +1 -1
  367. package/dist/modules/partnerships/repository.js +6 -82
  368. package/dist/modules/partnerships/repository.js.map +1 -1
  369. package/dist/modules/partnerships/routes.d.ts +14 -0
  370. package/dist/modules/partnerships/routes.d.ts.map +1 -1
  371. package/dist/modules/partnerships/routes.js +7 -0
  372. package/dist/modules/partnerships/routes.js.map +1 -1
  373. package/dist/modules/partnerships/schema.d.ts +20 -41
  374. package/dist/modules/partnerships/schema.d.ts.map +1 -1
  375. package/dist/modules/partnerships/schema.js +6 -10
  376. package/dist/modules/partnerships/schema.js.map +1 -1
  377. package/dist/modules/partnerships/service.d.ts +11 -1
  378. package/dist/modules/partnerships/service.d.ts.map +1 -1
  379. package/dist/modules/partnerships/service.js +43 -20
  380. package/dist/modules/partnerships/service.js.map +1 -1
  381. package/dist/modules/people/consentHydration.d.ts +26 -0
  382. package/dist/modules/people/consentHydration.d.ts.map +1 -0
  383. package/dist/modules/people/consentHydration.js +100 -0
  384. package/dist/modules/people/consentHydration.js.map +1 -0
  385. package/dist/modules/people/index.d.ts.map +1 -1
  386. package/dist/modules/people/index.js +3 -1
  387. package/dist/modules/people/index.js.map +1 -1
  388. package/dist/modules/people/personConsentWrites.d.ts +40 -0
  389. package/dist/modules/people/personConsentWrites.d.ts.map +1 -0
  390. package/dist/modules/people/personConsentWrites.js +98 -0
  391. package/dist/modules/people/personConsentWrites.js.map +1 -0
  392. package/dist/modules/people/repository.d.ts +11 -0
  393. package/dist/modules/people/repository.d.ts.map +1 -1
  394. package/dist/modules/people/repository.js +21 -1
  395. package/dist/modules/people/repository.js.map +1 -1
  396. package/dist/modules/people/routes.d.ts +57 -4
  397. package/dist/modules/people/routes.d.ts.map +1 -1
  398. package/dist/modules/people/routes.js +104 -5
  399. package/dist/modules/people/routes.js.map +1 -1
  400. package/dist/modules/people/schema.d.ts +366 -1
  401. package/dist/modules/people/schema.d.ts.map +1 -1
  402. package/dist/modules/people/schema.js +92 -2
  403. package/dist/modules/people/schema.js.map +1 -1
  404. package/dist/modules/people/service.d.ts +30 -1
  405. package/dist/modules/people/service.d.ts.map +1 -1
  406. package/dist/modules/people/service.js +131 -36
  407. package/dist/modules/people/service.js.map +1 -1
  408. package/dist/modules/people/tools.d.ts.map +1 -1
  409. package/dist/modules/people/tools.js +4 -1
  410. package/dist/modules/people/tools.js.map +1 -1
  411. package/dist/modules/personLinks.d.ts +79 -0
  412. package/dist/modules/personLinks.d.ts.map +1 -0
  413. package/dist/modules/personLinks.js +155 -0
  414. package/dist/modules/personLinks.js.map +1 -0
  415. package/dist/modules/pipelines/routes.d.ts +1 -0
  416. package/dist/modules/pipelines/routes.d.ts.map +1 -1
  417. package/dist/modules/plans/routes.d.ts +1 -0
  418. package/dist/modules/plans/routes.d.ts.map +1 -1
  419. package/dist/modules/positions/routes.d.ts.map +1 -1
  420. package/dist/modules/positions/routes.js +4 -2
  421. package/dist/modules/positions/routes.js.map +1 -1
  422. package/dist/modules/raises/index.d.ts.map +1 -1
  423. package/dist/modules/raises/index.js +3 -1
  424. package/dist/modules/raises/index.js.map +1 -1
  425. package/dist/modules/raises/repository.d.ts +0 -17
  426. package/dist/modules/raises/repository.d.ts.map +1 -1
  427. package/dist/modules/raises/repository.js +6 -77
  428. package/dist/modules/raises/repository.js.map +1 -1
  429. package/dist/modules/raises/routes.d.ts +14 -0
  430. package/dist/modules/raises/routes.d.ts.map +1 -1
  431. package/dist/modules/raises/routes.js +7 -0
  432. package/dist/modules/raises/routes.js.map +1 -1
  433. package/dist/modules/raises/schema.d.ts +20 -41
  434. package/dist/modules/raises/schema.d.ts.map +1 -1
  435. package/dist/modules/raises/schema.js +6 -10
  436. package/dist/modules/raises/schema.js.map +1 -1
  437. package/dist/modules/raises/service.d.ts +11 -1
  438. package/dist/modules/raises/service.d.ts.map +1 -1
  439. package/dist/modules/raises/service.js +41 -18
  440. package/dist/modules/raises/service.js.map +1 -1
  441. package/dist/modules/recordTargets.d.ts.map +1 -1
  442. package/dist/modules/recordTargets.js +2 -0
  443. package/dist/modules/recordTargets.js.map +1 -1
  444. package/dist/modules/references.d.ts +10 -0
  445. package/dist/modules/references.d.ts.map +1 -1
  446. package/dist/modules/references.js +27 -4
  447. package/dist/modules/references.js.map +1 -1
  448. package/dist/modules/sample-data/fixture.d.ts +160 -0
  449. package/dist/modules/sample-data/fixture.d.ts.map +1 -0
  450. package/dist/modules/sample-data/fixture.js +501 -0
  451. package/dist/modules/sample-data/fixture.js.map +1 -0
  452. package/dist/modules/sample-data/index.d.ts +11 -0
  453. package/dist/modules/sample-data/index.d.ts.map +1 -0
  454. package/dist/modules/sample-data/index.js +44 -0
  455. package/dist/modules/sample-data/index.js.map +1 -0
  456. package/dist/modules/sample-data/routes.d.ts +15 -0
  457. package/dist/modules/sample-data/routes.d.ts.map +1 -0
  458. package/dist/modules/sample-data/routes.js +25 -0
  459. package/dist/modules/sample-data/routes.js.map +1 -0
  460. package/dist/modules/sample-data/service.d.ts +39 -0
  461. package/dist/modules/sample-data/service.d.ts.map +1 -0
  462. package/dist/modules/sample-data/service.js +481 -0
  463. package/dist/modules/sample-data/service.js.map +1 -0
  464. package/dist/modules/sample-data/tools.d.ts +4 -0
  465. package/dist/modules/sample-data/tools.d.ts.map +1 -0
  466. package/dist/modules/sample-data/tools.js +22 -0
  467. package/dist/modules/sample-data/tools.js.map +1 -0
  468. package/dist/modules/search/index.d.ts +1 -1
  469. package/dist/modules/search/index.d.ts.map +1 -1
  470. package/dist/modules/search/index.js +2 -1
  471. package/dist/modules/search/index.js.map +1 -1
  472. package/dist/modules/search/repository.d.ts +1 -0
  473. package/dist/modules/search/repository.d.ts.map +1 -1
  474. package/dist/modules/search/repository.js +23 -0
  475. package/dist/modules/search/repository.js.map +1 -1
  476. package/dist/modules/search/service.d.ts +3 -3
  477. package/dist/modules/search/service.d.ts.map +1 -1
  478. package/dist/modules/search/service.js +5 -4
  479. package/dist/modules/search/service.js.map +1 -1
  480. package/dist/modules/smtp-email/index.d.ts +1 -0
  481. package/dist/modules/smtp-email/index.d.ts.map +1 -1
  482. package/dist/modules/smtp-email/index.js +1 -0
  483. package/dist/modules/smtp-email/index.js.map +1 -1
  484. package/dist/modules/stagedRecords.d.ts +3 -3
  485. package/dist/modules/stagedRecords.d.ts.map +1 -1
  486. package/dist/modules/stagedRecords.js +9 -0
  487. package/dist/modules/stagedRecords.js.map +1 -1
  488. package/dist/modules/webhooks/payloads.d.ts.map +1 -1
  489. package/dist/modules/webhooks/payloads.js +15 -2
  490. package/dist/modules/webhooks/payloads.js.map +1 -1
  491. package/dist/modules/workspace/repository.d.ts +2 -0
  492. package/dist/modules/workspace/repository.d.ts.map +1 -1
  493. package/dist/modules/workspace/repository.js +7 -0
  494. package/dist/modules/workspace/repository.js.map +1 -1
  495. package/dist/modules/workspace/service.d.ts.map +1 -1
  496. package/dist/modules/workspace/service.js +20 -1
  497. package/dist/modules/workspace/service.js.map +1 -1
  498. package/dist/modules/workspace/starters.d.ts.map +1 -1
  499. package/dist/modules/workspace/starters.js +5 -0
  500. package/dist/modules/workspace/starters.js.map +1 -1
  501. package/dist/runtime/events.d.ts +1 -1
  502. package/dist/runtime/events.d.ts.map +1 -1
  503. package/dist/runtime/events.js +1 -0
  504. package/dist/runtime/events.js.map +1 -1
  505. package/dist/schema/index.d.ts +4 -0
  506. package/dist/schema/index.d.ts.map +1 -1
  507. package/dist/schema/index.js +4 -0
  508. package/dist/schema/index.js.map +1 -1
  509. package/dist/testing/database.d.ts +5 -1
  510. package/dist/testing/database.d.ts.map +1 -1
  511. package/dist/testing/database.js +81 -10
  512. package/dist/testing/database.js.map +1 -1
  513. package/migrations/0021_certain_maggott.sql +30 -0
  514. package/migrations/0022_stormy_manta.sql +1 -0
  515. package/migrations/0023_funny_maddog.sql +1 -0
  516. package/migrations/0024_third_king_cobra.sql +46 -0
  517. package/migrations/0025_worthless_chimera.sql +3 -0
  518. package/migrations/0026_late_aqueduct.sql +46 -0
  519. package/migrations/0027_brainy_silver_sable.sql +3 -0
  520. package/migrations/0028_freezing_scrambler.sql +19 -0
  521. package/migrations/0029_custom_fields.sql +26 -0
  522. package/migrations/0030_enquiries.sql +79 -0
  523. package/migrations/0031_consent.sql +45 -0
  524. package/migrations/0032_form_field_statement.sql +1 -0
  525. package/migrations/0033_form_field_consent_purpose_ids.sql +5 -0
  526. package/migrations/0034_drop_form_field_consent_purpose_id.sql +1 -0
  527. package/migrations/0035_form_field_consent_purpose_labels.sql +1 -0
  528. package/migrations/0036_form_field_notice_type.sql +2 -0
  529. package/migrations/meta/0021_snapshot.json +5389 -0
  530. package/migrations/meta/0022_snapshot.json +5396 -0
  531. package/migrations/meta/0023_snapshot.json +5403 -0
  532. package/migrations/meta/0024_snapshot.json +5516 -0
  533. package/migrations/meta/0025_snapshot.json +5336 -0
  534. package/migrations/meta/0026_snapshot.json +5710 -0
  535. package/migrations/meta/0027_snapshot.json +5716 -0
  536. package/migrations/meta/0028_snapshot.json +5740 -0
  537. package/migrations/meta/0029_snapshot.json +5935 -0
  538. package/migrations/meta/0030_snapshot.json +6245 -0
  539. package/migrations/meta/0031_snapshot.json +6572 -0
  540. package/migrations/meta/0032_snapshot.json +6578 -0
  541. package/migrations/meta/0033_snapshot.json +6572 -0
  542. package/migrations/meta/0034_snapshot.json +6566 -0
  543. package/migrations/meta/0035_snapshot.json +6573 -0
  544. package/migrations/meta/0036_snapshot.json +6573 -0
  545. package/migrations/meta/_journal.json +112 -0
  546. package/package.json +3 -2
  547. package/src/lib/consumerEmailDomains.ts +62 -0
  548. package/src/lib/email.ts +7 -0
  549. package/src/lib/emailContent.ts +91 -0
  550. package/src/lib/emailDomainAutoLink.ts +165 -0
  551. package/src/lib/ids.ts +13 -0
  552. package/src/modules/activities/repository.ts +22 -23
  553. package/src/modules/activities/wording.ts +18 -0
  554. package/src/modules/agent-tasks/catalog.ts +63 -0
  555. package/src/modules/agent-tasks/resolve.ts +64 -24
  556. package/src/modules/attachedRecords.ts +37 -3
  557. package/src/modules/auth/preferences.ts +13 -1
  558. package/src/modules/auth/routes.ts +22 -0
  559. package/src/modules/auth/schema.ts +12 -2
  560. package/src/modules/auth/service.ts +37 -3
  561. package/src/modules/companies/index.ts +3 -1
  562. package/src/modules/companies/repository.ts +3 -0
  563. package/src/modules/companies/routes.ts +20 -0
  564. package/src/modules/companies/schema.ts +11 -1
  565. package/src/modules/companies/service.ts +72 -12
  566. package/src/modules/consent-purposes/capabilities.ts +12 -0
  567. package/src/modules/consent-purposes/events.ts +38 -0
  568. package/src/modules/consent-purposes/index.ts +48 -0
  569. package/src/modules/consent-purposes/repository.ts +163 -0
  570. package/src/modules/consent-purposes/routes.ts +122 -0
  571. package/src/modules/consent-purposes/schema.ts +46 -0
  572. package/src/modules/consent-purposes/service.ts +423 -0
  573. package/src/modules/consent-purposes/starters.ts +32 -0
  574. package/src/modules/consent-purposes/tools.ts +44 -0
  575. package/src/modules/core.ts +21 -0
  576. package/src/modules/custom-fields/capabilities.ts +17 -0
  577. package/src/modules/custom-fields/events.ts +51 -0
  578. package/src/modules/custom-fields/index.ts +61 -0
  579. package/src/modules/custom-fields/repository.ts +225 -0
  580. package/src/modules/custom-fields/routes.ts +155 -0
  581. package/src/modules/custom-fields/schema.ts +61 -0
  582. package/src/modules/custom-fields/service.ts +439 -0
  583. package/src/modules/custom-fields/tools.ts +53 -0
  584. package/src/modules/custom-fields/values.ts +352 -0
  585. package/src/modules/custom-fields/wire.ts +32 -0
  586. package/src/modules/dashboard/repository.ts +4 -3
  587. package/src/modules/deals/index.ts +5 -2
  588. package/src/modules/deals/repository.ts +6 -106
  589. package/src/modules/deals/routes.ts +7 -0
  590. package/src/modules/deals/schema.ts +7 -15
  591. package/src/modules/deals/service.ts +92 -23
  592. package/src/modules/decisions/repository.ts +2 -0
  593. package/src/modules/email-domain-linker/index.ts +40 -0
  594. package/src/modules/email-domain-linker/routes.ts +40 -0
  595. package/src/modules/email-domain-linker/service.ts +122 -0
  596. package/src/modules/enquiries/events.ts +45 -0
  597. package/src/modules/enquiries/index.ts +50 -0
  598. package/src/modules/enquiries/repository.ts +164 -0
  599. package/src/modules/enquiries/routes.ts +172 -0
  600. package/src/modules/enquiries/schema.ts +59 -0
  601. package/src/modules/enquiries/service.ts +644 -0
  602. package/src/modules/enquiries/tools.ts +66 -0
  603. package/src/modules/eventCatalogs.ts +4 -0
  604. package/src/modules/forms/embed.ts +391 -44
  605. package/src/modules/forms/events.ts +30 -2
  606. package/src/modules/forms/fields.ts +102 -2
  607. package/src/modules/forms/index.ts +12 -1
  608. package/src/modules/forms/mapping.ts +183 -6
  609. package/src/modules/forms/publicRoutes.ts +43 -1
  610. package/src/modules/forms/repository.ts +162 -1
  611. package/src/modules/forms/routes.ts +212 -2
  612. package/src/modules/forms/schema.ts +166 -4
  613. package/src/modules/forms/service.ts +565 -41
  614. package/src/modules/forms/submission.ts +718 -44
  615. package/src/modules/import-export/drafts.ts +20 -1
  616. package/src/modules/import-export/exportRows.ts +21 -5
  617. package/src/modules/import-export/plan.ts +47 -2
  618. package/src/modules/import-export/presets.ts +10 -0
  619. package/src/modules/import-export/repository.ts +73 -8
  620. package/src/modules/import-export/routes.ts +4 -0
  621. package/src/modules/import-export/schema.ts +11 -0
  622. package/src/modules/import-export/service.ts +28 -2
  623. package/src/modules/import-export/streams.ts +3 -1
  624. package/src/modules/import-export/tools.ts +10 -0
  625. package/src/modules/import-export/validation.ts +28 -0
  626. package/src/modules/import-export/writes.ts +70 -5
  627. package/src/modules/lists/events.ts +41 -0
  628. package/src/modules/lists/index.ts +41 -0
  629. package/src/modules/lists/repository.ts +343 -0
  630. package/src/modules/lists/routes.ts +255 -0
  631. package/src/modules/lists/schema.ts +95 -0
  632. package/src/modules/lists/service.ts +505 -0
  633. package/src/modules/lists/tools.ts +128 -0
  634. package/src/modules/mcp/index.ts +5 -0
  635. package/src/modules/opportunities/index.ts +3 -1
  636. package/src/modules/opportunities/repository.ts +11 -0
  637. package/src/modules/opportunities/routes.ts +13 -0
  638. package/src/modules/opportunities/schema.ts +7 -1
  639. package/src/modules/opportunities/service.ts +188 -22
  640. package/src/modules/opportunities/tools.ts +2 -0
  641. package/src/modules/partnerships/index.ts +3 -1
  642. package/src/modules/partnerships/repository.ts +6 -117
  643. package/src/modules/partnerships/routes.ts +7 -0
  644. package/src/modules/partnerships/schema.ts +7 -14
  645. package/src/modules/partnerships/service.ts +93 -22
  646. package/src/modules/people/consentHydration.ts +167 -0
  647. package/src/modules/people/index.ts +3 -1
  648. package/src/modules/people/personConsentWrites.ts +177 -0
  649. package/src/modules/people/repository.ts +31 -0
  650. package/src/modules/people/routes.ts +127 -18
  651. package/src/modules/people/schema.ts +109 -3
  652. package/src/modules/people/service.ts +205 -39
  653. package/src/modules/people/tools.ts +5 -1
  654. package/src/modules/personLinks.ts +278 -0
  655. package/src/modules/positions/routes.ts +4 -2
  656. package/src/modules/raises/index.ts +3 -1
  657. package/src/modules/raises/repository.ts +6 -107
  658. package/src/modules/raises/routes.ts +7 -0
  659. package/src/modules/raises/schema.ts +7 -14
  660. package/src/modules/raises/service.ts +91 -20
  661. package/src/modules/recordTargets.ts +2 -0
  662. package/src/modules/references.ts +43 -4
  663. package/src/modules/sample-data/fixture.ts +690 -0
  664. package/src/modules/sample-data/index.ts +51 -0
  665. package/src/modules/sample-data/routes.ts +50 -0
  666. package/src/modules/sample-data/service.ts +679 -0
  667. package/src/modules/sample-data/tools.ts +32 -0
  668. package/src/modules/search/index.ts +2 -1
  669. package/src/modules/search/repository.ts +33 -1
  670. package/src/modules/search/service.ts +7 -5
  671. package/src/modules/smtp-email/index.ts +8 -1
  672. package/src/modules/stagedRecords.ts +18 -3
  673. package/src/modules/webhooks/payloads.ts +20 -2
  674. package/src/modules/workspace/repository.ts +12 -0
  675. package/src/modules/workspace/service.ts +27 -1
  676. package/src/modules/workspace/starters.ts +5 -0
  677. package/src/runtime/events.ts +1 -0
  678. package/src/schema/index.ts +4 -0
  679. package/src/testing/database.ts +97 -11
@@ -6,6 +6,7 @@ import {
6
6
  PREFERRED_CHANNELS,
7
7
  RELATIONSHIP_LEVELS,
8
8
  SIZE_BANDS,
9
+ composeName,
9
10
  } from '@kelpie/schemas'
10
11
 
11
12
  import { normaliseDomain, normaliseEmail } from '../../lib/normalisation.ts'
@@ -43,6 +44,10 @@ export interface CompanyDraft {
43
44
 
44
45
  export interface PersonDraft {
45
46
  readonly name?: string
47
+ readonly salutation?: string
48
+ readonly firstName?: string
49
+ readonly lastName?: string
50
+ readonly suffix?: string
46
51
  readonly email?: string
47
52
  readonly phones?: readonly string[]
48
53
  readonly timezone?: string
@@ -157,11 +162,25 @@ export function companyDraft(mapped: Readonly<Record<string, string>>): CompanyD
157
162
  })
158
163
  }
159
164
 
165
+ /**
166
+ * `name` falls back to the first and last name cells, because most CRMs export
167
+ * those two and no full name at all. Composed only when the row's own `name` is
168
+ * blank, and never the other way round: a `name` cell is never split to fill
169
+ * `first_name`, since a guessed part is stored exactly like one somebody typed.
170
+ */
160
171
  export function personDraft(mapped: Readonly<Record<string, string>>): PersonDraft {
161
172
  const email = text(mapped, 'email')
173
+ const firstName = text(mapped, 'first_name')
174
+ const lastName = text(mapped, 'last_name')
175
+ const suffix = text(mapped, 'suffix')
176
+ const composed = composeName({ firstName, lastName, suffix })
162
177
 
163
178
  return present<PersonDraft>({
164
- name: text(mapped, 'name'),
179
+ name: text(mapped, 'name') ?? (composed.length > 0 ? composed : undefined),
180
+ salutation: text(mapped, 'salutation'),
181
+ firstName,
182
+ lastName,
183
+ suffix,
165
184
  email: email === undefined ? undefined : (normaliseEmail(email) ?? undefined),
166
185
  phones: list(mapped, 'phones'),
167
186
  timezone: text(mapped, 'timezone'),
@@ -30,13 +30,23 @@ function joinList(values: readonly string[]): string {
30
30
  * The header row of an export and of a template.
31
31
  *
32
32
  * `importOnly` columns are left out: a People import may map `company_domain`,
33
- * `company_name` and `title` to drive a Position, but a person holds many
34
- * positions and none of them is a field on the person. Writing one on the export
35
- * would be lossy, so the export and the template carry the round-trippable
36
- * columns only, and each cell function matches this order one for one.
33
+ * `company_name`, `title`, `consent_status`, and `consent_at` to drive extra
34
+ * writes, but none is a field on the person row. A template also leaves out
35
+ * `exportOnly` columns (`do_not_contact`, `consents`), which the export writes
36
+ * for readability but a caller round-trips through the per-purpose columns and
37
+ * `consent_purpose_id` on the job.
37
38
  */
38
39
  export function headersFor(object: ImportObject): readonly string[] {
39
- return OBJECT_COLUMNS[object].filter((column) => column.importOnly !== true).map((column) => column.key)
40
+ return OBJECT_COLUMNS[object]
41
+ .filter((column) => column.importOnly !== true)
42
+ .map((column) => column.key)
43
+ }
44
+
45
+ /** The template's headers — the round-trippable ones for a caller to fill in. */
46
+ export function templateHeadersFor(object: ImportObject): readonly string[] {
47
+ return OBJECT_COLUMNS[object]
48
+ .filter((column) => column.importOnly !== true && column.exportOnly !== true)
49
+ .map((column) => column.key)
40
50
  }
41
51
 
42
52
  export function companyCells(row: ExportCompanyRow): readonly string[] {
@@ -59,6 +69,10 @@ export function companyCells(row: ExportCompanyRow): readonly string[] {
59
69
  export function personCells(row: ExportPersonRow): readonly string[] {
60
70
  return [
61
71
  row.name,
72
+ row.salutation ?? '',
73
+ row.firstName ?? '',
74
+ row.lastName ?? '',
75
+ row.suffix ?? '',
62
76
  row.email ?? '',
63
77
  row.timezone ?? '',
64
78
  row.location ?? '',
@@ -68,6 +82,8 @@ export function personCells(row: ExportPersonRow): readonly string[] {
68
82
  row.summary,
69
83
  joinList(row.tags),
70
84
  joinList(row.phones),
85
+ row.doNotContact ? 'true' : 'false',
86
+ row.consents,
71
87
  ]
72
88
  }
73
89
 
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ ConsentStatus,
2
3
  ImportConflictMode,
3
4
  ImportCounts,
4
5
  ImportObject,
@@ -44,6 +45,8 @@ export interface PlanContext {
44
45
  readonly conflictMode: ImportConflictMode
45
46
  /** What a People row does with an absent company. Ignored by the other objects. */
46
47
  readonly onMissingCompany: OnMissingCompany
48
+ /** The consent purpose the job grants for each row's consent_status. Null when not set. */
49
+ readonly consentPurposeId: string | null
47
50
  readonly lookups: ImportLookups
48
51
  }
49
52
 
@@ -55,6 +58,14 @@ export type PlannedAffiliation =
55
58
  | { readonly kind: 'link'; readonly companyId: string; readonly title: string }
56
59
  | { readonly kind: 'create'; readonly company: CompanyDraft; readonly title: string }
57
60
 
61
+ /** A consent write that rides with a People row when the job has a purpose. */
62
+ export interface ImportConsentGrant {
63
+ readonly purposeId: string
64
+ readonly status: ConsentStatus
65
+ /** ISO date from the `consent_at` column; null when the column is unmapped or blank. */
66
+ readonly notedAt: string | null
67
+ }
68
+
58
69
  /** The values a write applies, once every reference in the row has been resolved. */
59
70
  export type ImportWrite =
60
71
  | { readonly object: 'companies'; readonly draft: CompanyDraft }
@@ -63,6 +74,8 @@ export type ImportWrite =
63
74
  readonly draft: PersonDraft
64
75
  /** A position to upsert alongside the person, when the row named a company and a title. */
65
76
  readonly affiliation?: PlannedAffiliation
77
+ /** Consent to grant against the job's purpose. Absent when consent_status is blank. */
78
+ readonly consent?: ImportConsentGrant
66
79
  }
67
80
  | {
68
81
  readonly object: 'positions'
@@ -249,8 +262,18 @@ function resolveWrite(context: PlanContext, mapped: Readonly<Record<string, stri
249
262
  switch (context.object) {
250
263
  case 'companies':
251
264
  return { object: 'companies', draft: companyDraft(mapped) }
252
- case 'people':
253
- return { object: 'people', draft: personDraft(mapped) }
265
+ case 'people': {
266
+ const write: {
267
+ object: 'people'
268
+ draft: PersonDraft
269
+ consent?: ImportConsentGrant
270
+ } = { object: 'people', draft: personDraft(mapped) }
271
+ const consent = readConsentGrant(context, mapped)
272
+ if (consent !== undefined) {
273
+ write.consent = consent
274
+ }
275
+ return write
276
+ }
254
277
  case 'positions':
255
278
  return planPosition(context, mapped)
256
279
  case 'deals':
@@ -258,6 +281,28 @@ function resolveWrite(context: PlanContext, mapped: Readonly<Record<string, stri
258
281
  }
259
282
  }
260
283
 
284
+ /**
285
+ * The consent grant a People row carries. Absent unless the job has a purpose
286
+ * set on it AND the row has a non-blank `consent_status`. `validateRow` has
287
+ * already refused an unknown status by the time this runs, so the coercion
288
+ * below is safe.
289
+ */
290
+ function readConsentGrant(
291
+ context: PlanContext,
292
+ mapped: Readonly<Record<string, string>>,
293
+ ): ImportConsentGrant | undefined {
294
+ if (context.consentPurposeId === null) return undefined
295
+ const rawStatus = (mapped.consent_status ?? '').trim().toLowerCase()
296
+ if (rawStatus.length === 0) return undefined
297
+ if (rawStatus !== 'granted' && rawStatus !== 'withdrawn') return undefined
298
+ const rawAt = (mapped.consent_at ?? '').trim()
299
+ return {
300
+ purposeId: context.consentPurposeId,
301
+ status: rawStatus as ConsentStatus,
302
+ notedAt: rawAt.length === 0 ? null : rawAt,
303
+ }
304
+ }
305
+
261
306
  /**
262
307
  * The company affiliation a People row asks for, if any, and any note about it.
263
308
  *
@@ -27,7 +27,12 @@ export const SOURCE_PRESETS: Readonly<Record<ImportSource, SourcePreset>> = {
27
27
  description: 'Description',
28
28
  },
29
29
  people: {
30
+ // Both, because a HubSpot contact export carries the parts and often no
31
+ // full name at all. A preset header the file does not have falls through
32
+ // to the exact-key match below, so mapping all three costs a file nothing.
30
33
  name: 'Full Name',
34
+ first_name: 'First Name',
35
+ last_name: 'Last Name',
31
36
  email: 'Email',
32
37
  phones: 'Phone Number',
33
38
  location: 'City',
@@ -59,10 +64,15 @@ export const SOURCE_PRESETS: Readonly<Record<ImportSource, SourcePreset>> = {
59
64
  },
60
65
  people: {
61
66
  name: 'Full Name',
67
+ salutation: 'Salutation',
68
+ first_name: 'First Name',
69
+ last_name: 'Last Name',
62
70
  email: 'Email',
63
71
  phones: 'Phone',
64
72
  location: 'Mailing City',
65
73
  company_name: 'Account Name',
74
+ // Salesforce's Contact.Title is the job title, and a job title is a
75
+ // Position. It is not this object's `suffix`, which stays unmapped.
66
76
  title: 'Title',
67
77
  },
68
78
  positions: {
@@ -3,8 +3,9 @@ import { and, asc, eq, gt, inArray, sql } from 'drizzle-orm'
3
3
  import type { Queryable } from '../../runtime/transaction.ts'
4
4
  import { users } from '../auth/schema.ts'
5
5
  import { companies } from '../companies/schema.ts'
6
- import { dealPeople, deals } from '../deals/schema.ts'
7
- import { people } from '../people/schema.ts'
6
+ import { consentPurposes } from '../consent-purposes/schema.ts'
7
+ import { deals } from '../deals/schema.ts'
8
+ import { people, personConsents, personLinks } from '../people/schema.ts'
8
9
  import { pipelineStages } from '../pipelines/schema.ts'
9
10
  import { positions } from '../positions/schema.ts'
10
11
  import { workspaceMembers } from '../workspace/schema.ts'
@@ -487,6 +488,10 @@ export function readCompanies(
487
488
  export interface ExportPersonRow {
488
489
  readonly id: string
489
490
  readonly name: string
491
+ readonly salutation: string | null
492
+ readonly firstName: string | null
493
+ readonly lastName: string | null
494
+ readonly suffix: string | null
490
495
  readonly email: string | null
491
496
  readonly timezone: string | null
492
497
  readonly location: string | null
@@ -496,17 +501,27 @@ export interface ExportPersonRow {
496
501
  readonly summary: string
497
502
  readonly tags: readonly string[]
498
503
  readonly phones: readonly string[]
504
+ readonly doNotContact: boolean
505
+ /**
506
+ * `<purpose_slug>:<status>` pairs joined with '; ', in purpose sort order.
507
+ * Purposes at their default (no explicit `person_consents` row) are omitted.
508
+ */
509
+ readonly consents: string
499
510
  }
500
511
 
501
- export function readPeople(
512
+ export async function readPeople(
502
513
  db: Queryable,
503
514
  workspaceId: string,
504
515
  after: string,
505
516
  ): Promise<ExportPersonRow[]> {
506
- return db
517
+ const rows = await db
507
518
  .select({
508
519
  id: people.id,
509
520
  name: people.name,
521
+ salutation: people.salutation,
522
+ firstName: people.firstName,
523
+ lastName: people.lastName,
524
+ suffix: people.suffix,
510
525
  email: people.email,
511
526
  timezone: people.timezone,
512
527
  location: people.location,
@@ -516,11 +531,54 @@ export function readPeople(
516
531
  summary: people.summary,
517
532
  tags: people.tags,
518
533
  phones: people.phones,
534
+ doNotContact: people.doNotContact,
519
535
  })
520
536
  .from(people)
521
537
  .where(and(eq(people.workspaceId, workspaceId), gt(people.id, after)))
522
538
  .orderBy(asc(people.id))
523
539
  .limit(EXPORT_PAGE)
540
+
541
+ if (rows.length === 0) return []
542
+ const consentsByPerson = await readConsentsForExport(
543
+ db,
544
+ workspaceId,
545
+ rows.map((row) => row.id),
546
+ )
547
+ return rows.map((row) => ({
548
+ ...row,
549
+ consents: consentsByPerson.get(row.id) ?? '',
550
+ }))
551
+ }
552
+
553
+ async function readConsentsForExport(
554
+ db: Queryable,
555
+ workspaceId: string,
556
+ personIds: readonly string[],
557
+ ): Promise<ReadonlyMap<string, string>> {
558
+ const rows = await db
559
+ .select({
560
+ personId: personConsents.personId,
561
+ slug: consentPurposes.slug,
562
+ status: personConsents.status,
563
+ sortOrder: consentPurposes.sortOrder,
564
+ })
565
+ .from(personConsents)
566
+ .innerJoin(consentPurposes, eq(consentPurposes.id, personConsents.purposeId))
567
+ .where(
568
+ and(
569
+ eq(personConsents.workspaceId, workspaceId),
570
+ inArray(personConsents.personId, [...personIds]),
571
+ ),
572
+ )
573
+ .orderBy(asc(consentPurposes.sortOrder), asc(consentPurposes.slug))
574
+
575
+ const out = new Map<string, string[]>()
576
+ for (const row of rows) {
577
+ const list = out.get(row.personId) ?? []
578
+ list.push(`${row.slug}:${row.status}`)
579
+ out.set(row.personId, list)
580
+ }
581
+ return new Map(Array.from(out, ([personId, list]) => [personId, list.join('; ')]))
524
582
  }
525
583
 
526
584
  export interface ExportPositionRow {
@@ -604,6 +662,7 @@ export function readDeals(
604
662
  /** The addresses of the people on each of a page of deals, in one query. */
605
663
  export async function readDealPersonEmails(
606
664
  db: Queryable,
665
+ workspaceId: string,
607
666
  dealIds: readonly string[],
608
667
  ): Promise<ReadonlyMap<string, readonly string[]>> {
609
668
  if (dealIds.length === 0) {
@@ -611,10 +670,16 @@ export async function readDealPersonEmails(
611
670
  }
612
671
 
613
672
  const rows = await db
614
- .select({ dealId: dealPeople.dealId, email: people.email })
615
- .from(dealPeople)
616
- .innerJoin(people, eq(people.id, dealPeople.personId))
617
- .where(inArray(dealPeople.dealId, [...dealIds]))
673
+ .select({ dealId: personLinks.targetId, email: people.email })
674
+ .from(personLinks)
675
+ .innerJoin(people, eq(people.id, personLinks.personId))
676
+ .where(
677
+ and(
678
+ eq(personLinks.workspaceId, workspaceId),
679
+ eq(personLinks.targetType, 'deal'),
680
+ inArray(personLinks.targetId, [...dealIds]),
681
+ ),
682
+ )
618
683
  .orderBy(asc(people.email))
619
684
 
620
685
  const byDeal = new Map<string, string[]>()
@@ -46,6 +46,8 @@ const createJobForm = z.object({
46
46
  on_missing_company: z.enum(ON_MISSING_COMPANY).default('skip'),
47
47
  match_key: z.string().min(1).optional(),
48
48
  column_map: z.string().optional(),
49
+ /** People imports only — mirrors on_missing_company's per-object gate. */
50
+ consent_purpose_id: z.string().min(1).optional(),
49
51
  dry_run: z.enum(['true', 'false']).default('true'),
50
52
  })
51
53
 
@@ -63,6 +65,7 @@ export function importJobResponse(job: ImportJobView): Record<string, unknown> {
63
65
  on_missing_company: job.onMissingCompany,
64
66
  match_key: job.matchKey,
65
67
  column_map: job.columnMap,
68
+ consent_purpose_id: job.consentPurposeId,
66
69
  source_headers: job.sourceHeaders,
67
70
  file_name: job.fileName,
68
71
  counts: job.counts,
@@ -237,6 +240,7 @@ export function mountImportExportRoutes(
237
240
  onMissingCompany: parsed.data.on_missing_company,
238
241
  matchKeyId: parsed.data.match_key ?? defaultMatchKeyId(parsed.data.object),
239
242
  columnMap: readColumnMap(parsed.data.column_map),
243
+ consentPurposeId: parsed.data.consent_purpose_id ?? null,
240
244
  fileName: file.name.length === 0 ? null : file.name,
241
245
  csv: await file.text(),
242
246
  })
@@ -15,6 +15,7 @@ import type {
15
15
  import { index, integer, jsonb, pgTable, primaryKey, text } from 'drizzle-orm/pg-core'
16
16
 
17
17
  import { checkOneOf, createdAt, primaryId, updatedAt } from '../../lib/columns.ts'
18
+ import { consentPurposes } from '../consent-purposes/schema.ts'
18
19
  import { workspaces } from '../workspace/schema.ts'
19
20
 
20
21
  /**
@@ -78,6 +79,16 @@ export const importJobs = pgTable(
78
79
  onMissingCompany: text('on_missing_company').notNull().default('skip'),
79
80
  matchKey: text('match_key').notNull(),
80
81
  columnMap: jsonb('column_map').$type<ImportColumnMap>().notNull().default({}),
82
+ /**
83
+ * The consent purpose a People import grants for each row that carries a
84
+ * `consent_status`. Required whenever the map names `consent_status` or
85
+ * `consent_at`; null on every other object and on People jobs that skip
86
+ * consent columns. `set null` on delete so a purpose can be removed
87
+ * without invalidating an old job.
88
+ */
89
+ consentPurposeId: text('consent_purpose_id').references(() => consentPurposes.id, {
90
+ onDelete: 'set null',
91
+ }),
81
92
  sourceHeaders: jsonb('source_headers').$type<readonly string[]>().notNull().default([]),
82
93
  counts: jsonb('counts').$type<ImportCounts>().notNull(),
83
94
  /** The first `IMPORT_REPORTED_ERRORS` failing rows. `counts.error` is the true number. */
@@ -99,7 +99,7 @@ function emitImportedRecordUpdated(
99
99
  }
100
100
  import { CsvFormatError, csvLine, fileDigest, parseCsv } from './csv.ts'
101
101
  import type { CsvRow, ParsedCsv } from './csv.ts'
102
- import { headersFor } from './exportRows.ts'
102
+ import { templateHeadersFor } from './exportRows.ts'
103
103
  import { buildMatchKey, mapRow, splitList } from './mapping.ts'
104
104
  import { applyWrite } from './writes.ts'
105
105
  import { countPlans, planRow, planRows } from './plan.ts'
@@ -146,6 +146,7 @@ export interface ImportJobView {
146
146
  readonly onMissingCompany: OnMissingCompany
147
147
  readonly matchKey: string
148
148
  readonly columnMap: ImportColumnMap
149
+ readonly consentPurposeId: string | null
149
150
  readonly sourceHeaders: readonly string[]
150
151
  readonly fileName: string | null
151
152
  readonly counts: ImportCounts
@@ -164,6 +165,11 @@ export interface CreateImportJobInput {
164
165
  readonly matchKeyId: string
165
166
  /** Absent means "derive one from the source preset and the file's own headers". */
166
167
  readonly columnMap: ImportColumnMap | undefined
168
+ /**
169
+ * People imports only. Required whenever the mapping names `consent_status`
170
+ * or `consent_at`, refused with `422` for any other object.
171
+ */
172
+ readonly consentPurposeId: string | null
167
173
  readonly fileName: string | null
168
174
  readonly csv: string
169
175
  }
@@ -460,6 +466,7 @@ export function createImportExportService(
460
466
  matchKey: requireMatchKey(job.object as ImportObject, job.matchKey),
461
467
  conflictMode: job.conflictMode as ImportConflictMode,
462
468
  onMissingCompany: job.onMissingCompany as OnMissingCompany,
469
+ consentPurposeId: job.consentPurposeId,
463
470
  lookups,
464
471
  }
465
472
  }
@@ -837,6 +844,24 @@ export function createImportExportService(
837
844
 
838
845
  requireUsableColumnMap(input.object, matchKey, columnMap, parsed.headers)
839
846
 
847
+ // Consent is a People-only feature. A purpose on any other object is
848
+ // refused up front; mapping the consent columns without one is refused
849
+ // too — the writer would have no purpose to grant against.
850
+ const mapsConsentColumn =
851
+ columnMap.consent_status !== null || columnMap.consent_at !== null
852
+ if (input.consentPurposeId !== null && input.object !== 'people') {
853
+ throw AppError.validationFailed(
854
+ 'consent_purpose_id is only accepted on people imports',
855
+ [{ field: 'consent_purpose_id', message: 'People imports only' }],
856
+ )
857
+ }
858
+ if (input.object === 'people' && mapsConsentColumn && input.consentPurposeId === null) {
859
+ throw AppError.validationFailed(
860
+ 'Mapping consent_status or consent_at needs a consent_purpose_id on the job',
861
+ [{ field: 'consent_purpose_id', message: 'Required when consent columns are mapped' }],
862
+ )
863
+ }
864
+
840
865
  const id = dependencies.createId('importJob')
841
866
  const now = dependencies.now()
842
867
 
@@ -853,6 +878,7 @@ export function createImportExportService(
853
878
  onMissingCompany: input.onMissingCompany,
854
879
  matchKey: matchKey.id,
855
880
  columnMap,
881
+ consentPurposeId: input.consentPurposeId,
856
882
  sourceHeaders: parsed.headers,
857
883
  counts: { ...EMPTY_COUNTS, total: parsed.rows.length },
858
884
  errors: [],
@@ -970,7 +996,7 @@ export function createImportExportService(
970
996
  },
971
997
 
972
998
  templateCsv(object) {
973
- return csvLine(headersFor(object))
999
+ return csvLine(templateHeadersFor(object))
974
1000
  },
975
1001
  }
976
1002
  }
@@ -52,10 +52,12 @@ async function* pageThrough<TRow extends { readonly id: string }>(
52
52
  /** The rows of one page, all their people in one query rather than one per deal. */
53
53
  async function dealPage(
54
54
  db: Database,
55
+ workspaceId: string,
55
56
  rows: readonly repository.ExportDealRow[],
56
57
  ): Promise<readonly (readonly string[])[]> {
57
58
  const emails = await repository.readDealPersonEmails(
58
59
  db,
60
+ workspaceId,
59
61
  rows.map((row) => row.id),
60
62
  )
61
63
 
@@ -91,7 +93,7 @@ export async function* streamExport(
91
93
  case 'deals':
92
94
  yield* pageThrough({
93
95
  read: (after) => repository.readDeals(db, workspaceId, after),
94
- cells: (rows) => dealPage(db, rows),
96
+ cells: (rows) => dealPage(db, workspaceId, rows),
95
97
  })
96
98
  return
97
99
  }
@@ -69,6 +69,15 @@ const previewArgs = z.strictObject({
69
69
  ),
70
70
  match_key: z.string().min(1).optional().describe('Which field decides that match.'),
71
71
  column_map: columnMapArg.optional(),
72
+ consent_purpose_id: z
73
+ .string()
74
+ .min(1)
75
+ .nullable()
76
+ .default(null)
77
+ .describe(
78
+ 'People imports only: the consent purpose a row grants for each `consent_status`. ' +
79
+ 'Required whenever consent_status or consent_at is mapped.',
80
+ ),
72
81
  file_name: z.string().min(1).nullable().default(null).describe('Recorded on the job, for the log.'),
73
82
  })
74
83
 
@@ -135,6 +144,7 @@ export function registerImportExportTools(mcp: McpToolRegistry, service: ImportE
135
144
  onMissingCompany: args.on_missing_company,
136
145
  matchKeyId: args.match_key ?? defaultMatchKeyId(args.object),
137
146
  columnMap: args.column_map,
147
+ consentPurposeId: args.consent_purpose_id,
138
148
  fileName: args.file_name,
139
149
  csv: args.csv,
140
150
  }),
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  ACCOUNT_TYPES,
3
3
  COMPANY_STAGES,
4
+ CONSENT_STATUSES,
4
5
  ICP_FITS,
5
6
  INFLUENCE_LEVELS,
6
7
  PREFERRED_CHANNELS,
@@ -90,7 +91,28 @@ function checkCompany(errors: StoredRowError[], mapped: Readonly<Record<string,
90
91
  checkEnum(errors, 'icp_fit', ICP_FITS, mapped.icp_fit)
91
92
  }
92
93
 
94
+ /**
95
+ * A People row names its person one way or the other.
96
+ *
97
+ * `name` is not a `required` column, because the requirement is really about a
98
+ * pair of them: the row carries a full `name`, or the `first_name` /
99
+ * `last_name` cells for one to be composed from. Most CRMs export the parts and
100
+ * no full name, and refusing every row of such a file over a column it was
101
+ * never going to have is the migration nobody finishes.
102
+ */
103
+ function checkPersonName(errors: StoredRowError[], mapped: Readonly<Record<string, string>>): void {
104
+ const named = ['name', 'first_name', 'last_name'].some(
105
+ (column) => (mapped[column] ?? '').trim().length > 0,
106
+ )
107
+
108
+ if (!named) {
109
+ errors.push({ field: 'name', message: 'Missing a name, first_name or last_name' })
110
+ }
111
+ }
112
+
93
113
  function checkPerson(errors: StoredRowError[], mapped: Readonly<Record<string, string>>): void {
114
+ checkPersonName(errors, mapped)
115
+
94
116
  const email = (mapped.email ?? '').trim()
95
117
 
96
118
  if (email.length > 0 && !EMAIL_SHAPE.test(email)) {
@@ -100,6 +122,12 @@ function checkPerson(errors: StoredRowError[], mapped: Readonly<Record<string, s
100
122
  checkEnum(errors, 'preferred_channel', PREFERRED_CHANNELS, mapped.preferred_channel)
101
123
  checkEnum(errors, 'influence', INFLUENCE_LEVELS, mapped.influence)
102
124
  checkEnum(errors, 'relationship', RELATIONSHIP_LEVELS, mapped.relationship)
125
+ checkEnum(errors, 'consent_status', CONSENT_STATUSES, mapped.consent_status)
126
+
127
+ const consentAt = (mapped.consent_at ?? '').trim()
128
+ if (consentAt.length > 0 && !isoDateSchema.safeParse(consentAt).success) {
129
+ errors.push({ field: 'consent_at', message: `"${consentAt}" is not a date. Use YYYY-MM-DD` })
130
+ }
103
131
  }
104
132
 
105
133
  function checkPosition(errors: StoredRowError[], mapped: Readonly<Record<string, string>>): void {