@kelpie/server 0.8.0 → 0.10.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 (594) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/ids.d.ts +11 -0
  6. package/dist/lib/ids.d.ts.map +1 -1
  7. package/dist/lib/ids.js +11 -0
  8. package/dist/lib/ids.js.map +1 -1
  9. package/dist/modules/activities/repository.d.ts.map +1 -1
  10. package/dist/modules/activities/repository.js +19 -20
  11. package/dist/modules/activities/repository.js.map +1 -1
  12. package/dist/modules/activities/wording.d.ts +12 -0
  13. package/dist/modules/activities/wording.d.ts.map +1 -1
  14. package/dist/modules/activities/wording.js +16 -0
  15. package/dist/modules/activities/wording.js.map +1 -1
  16. package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
  17. package/dist/modules/agent-tasks/catalog.js +62 -0
  18. package/dist/modules/agent-tasks/catalog.js.map +1 -1
  19. package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
  20. package/dist/modules/agent-tasks/resolve.js +42 -9
  21. package/dist/modules/agent-tasks/resolve.js.map +1 -1
  22. package/dist/modules/agent-tasks/routes.d.ts +2 -0
  23. package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
  24. package/dist/modules/attachedRecords.d.ts +6 -1
  25. package/dist/modules/attachedRecords.d.ts.map +1 -1
  26. package/dist/modules/attachedRecords.js +15 -1
  27. package/dist/modules/attachedRecords.js.map +1 -1
  28. package/dist/modules/companies/index.d.ts.map +1 -1
  29. package/dist/modules/companies/index.js +3 -1
  30. package/dist/modules/companies/index.js.map +1 -1
  31. package/dist/modules/companies/routes.d.ts +14 -0
  32. package/dist/modules/companies/routes.d.ts.map +1 -1
  33. package/dist/modules/companies/routes.js +7 -0
  34. package/dist/modules/companies/routes.js.map +1 -1
  35. package/dist/modules/companies/schema.d.ts +20 -0
  36. package/dist/modules/companies/schema.d.ts.map +1 -1
  37. package/dist/modules/companies/schema.js +6 -1
  38. package/dist/modules/companies/schema.js.map +1 -1
  39. package/dist/modules/companies/service.d.ts +5 -0
  40. package/dist/modules/companies/service.d.ts.map +1 -1
  41. package/dist/modules/companies/service.js +24 -12
  42. package/dist/modules/companies/service.js.map +1 -1
  43. package/dist/modules/consent-purposes/capabilities.d.ts +7 -0
  44. package/dist/modules/consent-purposes/capabilities.d.ts.map +1 -0
  45. package/dist/modules/consent-purposes/capabilities.js +10 -0
  46. package/dist/modules/consent-purposes/capabilities.js.map +1 -0
  47. package/dist/modules/consent-purposes/events.d.ts +38 -0
  48. package/dist/modules/consent-purposes/events.d.ts.map +1 -0
  49. package/dist/modules/consent-purposes/events.js +17 -0
  50. package/dist/modules/consent-purposes/events.js.map +1 -0
  51. package/dist/modules/consent-purposes/index.d.ts +13 -0
  52. package/dist/modules/consent-purposes/index.d.ts.map +1 -0
  53. package/dist/modules/consent-purposes/index.js +41 -0
  54. package/dist/modules/consent-purposes/index.js.map +1 -0
  55. package/dist/modules/consent-purposes/repository.d.ts +21 -0
  56. package/dist/modules/consent-purposes/repository.d.ts.map +1 -0
  57. package/dist/modules/consent-purposes/repository.js +98 -0
  58. package/dist/modules/consent-purposes/repository.js.map +1 -0
  59. package/dist/modules/consent-purposes/routes.d.ts +39 -0
  60. package/dist/modules/consent-purposes/routes.d.ts.map +1 -0
  61. package/dist/modules/consent-purposes/routes.js +79 -0
  62. package/dist/modules/consent-purposes/routes.js.map +1 -0
  63. package/dist/modules/consent-purposes/schema.d.ts +175 -0
  64. package/dist/modules/consent-purposes/schema.d.ts.map +1 -0
  65. package/dist/modules/consent-purposes/schema.js +35 -0
  66. package/dist/modules/consent-purposes/schema.js.map +1 -0
  67. package/dist/modules/consent-purposes/service.d.ts +50 -0
  68. package/dist/modules/consent-purposes/service.d.ts.map +1 -0
  69. package/dist/modules/consent-purposes/service.js +263 -0
  70. package/dist/modules/consent-purposes/service.js.map +1 -0
  71. package/dist/modules/consent-purposes/starters.d.ts +17 -0
  72. package/dist/modules/consent-purposes/starters.d.ts.map +1 -0
  73. package/dist/modules/consent-purposes/starters.js +15 -0
  74. package/dist/modules/consent-purposes/starters.js.map +1 -0
  75. package/dist/modules/consent-purposes/tools.d.ts +4 -0
  76. package/dist/modules/consent-purposes/tools.d.ts.map +1 -0
  77. package/dist/modules/consent-purposes/tools.js +29 -0
  78. package/dist/modules/consent-purposes/tools.js.map +1 -0
  79. package/dist/modules/core.d.ts.map +1 -1
  80. package/dist/modules/core.js +10 -0
  81. package/dist/modules/core.js.map +1 -1
  82. package/dist/modules/custom-fields/capabilities.d.ts +12 -0
  83. package/dist/modules/custom-fields/capabilities.d.ts.map +1 -0
  84. package/dist/modules/custom-fields/capabilities.js +15 -0
  85. package/dist/modules/custom-fields/capabilities.js.map +1 -0
  86. package/dist/modules/custom-fields/events.d.ts +49 -0
  87. package/dist/modules/custom-fields/events.d.ts.map +1 -0
  88. package/dist/modules/custom-fields/events.js +25 -0
  89. package/dist/modules/custom-fields/events.js.map +1 -0
  90. package/dist/modules/custom-fields/index.d.ts +19 -0
  91. package/dist/modules/custom-fields/index.d.ts.map +1 -0
  92. package/dist/modules/custom-fields/index.js +46 -0
  93. package/dist/modules/custom-fields/index.js.map +1 -0
  94. package/dist/modules/custom-fields/repository.d.ts +37 -0
  95. package/dist/modules/custom-fields/repository.d.ts.map +1 -0
  96. package/dist/modules/custom-fields/repository.js +144 -0
  97. package/dist/modules/custom-fields/repository.js.map +1 -0
  98. package/dist/modules/custom-fields/routes.d.ts +44 -0
  99. package/dist/modules/custom-fields/routes.d.ts.map +1 -0
  100. package/dist/modules/custom-fields/routes.js +103 -0
  101. package/dist/modules/custom-fields/routes.js.map +1 -0
  102. package/dist/modules/custom-fields/schema.d.ts +215 -0
  103. package/dist/modules/custom-fields/schema.d.ts.map +1 -0
  104. package/dist/modules/custom-fields/schema.js +43 -0
  105. package/dist/modules/custom-fields/schema.js.map +1 -0
  106. package/dist/modules/custom-fields/service.d.ts +57 -0
  107. package/dist/modules/custom-fields/service.d.ts.map +1 -0
  108. package/dist/modules/custom-fields/service.js +273 -0
  109. package/dist/modules/custom-fields/service.js.map +1 -0
  110. package/dist/modules/custom-fields/tools.d.ts +4 -0
  111. package/dist/modules/custom-fields/tools.d.ts.map +1 -0
  112. package/dist/modules/custom-fields/tools.js +38 -0
  113. package/dist/modules/custom-fields/tools.js.map +1 -0
  114. package/dist/modules/custom-fields/values.d.ts +49 -0
  115. package/dist/modules/custom-fields/values.d.ts.map +1 -0
  116. package/dist/modules/custom-fields/values.js +249 -0
  117. package/dist/modules/custom-fields/values.js.map +1 -0
  118. package/dist/modules/custom-fields/wire.d.ts +12 -0
  119. package/dist/modules/custom-fields/wire.d.ts.map +1 -0
  120. package/dist/modules/custom-fields/wire.js +30 -0
  121. package/dist/modules/custom-fields/wire.js.map +1 -0
  122. package/dist/modules/dashboard/repository.d.ts.map +1 -1
  123. package/dist/modules/dashboard/repository.js +4 -3
  124. package/dist/modules/dashboard/repository.js.map +1 -1
  125. package/dist/modules/deals/index.d.ts +2 -1
  126. package/dist/modules/deals/index.d.ts.map +1 -1
  127. package/dist/modules/deals/index.js +5 -2
  128. package/dist/modules/deals/index.js.map +1 -1
  129. package/dist/modules/deals/repository.d.ts +0 -16
  130. package/dist/modules/deals/repository.d.ts.map +1 -1
  131. package/dist/modules/deals/repository.js +6 -76
  132. package/dist/modules/deals/repository.js.map +1 -1
  133. package/dist/modules/deals/routes.d.ts +14 -0
  134. package/dist/modules/deals/routes.d.ts.map +1 -1
  135. package/dist/modules/deals/routes.js +7 -0
  136. package/dist/modules/deals/routes.js.map +1 -1
  137. package/dist/modules/deals/schema.d.ts +20 -42
  138. package/dist/modules/deals/schema.d.ts.map +1 -1
  139. package/dist/modules/deals/schema.js +6 -11
  140. package/dist/modules/deals/schema.js.map +1 -1
  141. package/dist/modules/deals/service.d.ts +13 -2
  142. package/dist/modules/deals/service.d.ts.map +1 -1
  143. package/dist/modules/deals/service.js +43 -20
  144. package/dist/modules/deals/service.js.map +1 -1
  145. package/dist/modules/decisions/repository.d.ts.map +1 -1
  146. package/dist/modules/decisions/repository.js +2 -0
  147. package/dist/modules/decisions/repository.js.map +1 -1
  148. package/dist/modules/decisions/routes.d.ts +1 -0
  149. package/dist/modules/decisions/routes.d.ts.map +1 -1
  150. package/dist/modules/enquiries/events.d.ts +44 -0
  151. package/dist/modules/enquiries/events.d.ts.map +1 -0
  152. package/dist/modules/enquiries/events.js +19 -0
  153. package/dist/modules/enquiries/events.js.map +1 -0
  154. package/dist/modules/enquiries/index.d.ts +13 -0
  155. package/dist/modules/enquiries/index.d.ts.map +1 -0
  156. package/dist/modules/enquiries/index.js +44 -0
  157. package/dist/modules/enquiries/index.js.map +1 -0
  158. package/dist/modules/enquiries/repository.d.ts +30 -0
  159. package/dist/modules/enquiries/repository.d.ts.map +1 -0
  160. package/dist/modules/enquiries/repository.js +94 -0
  161. package/dist/modules/enquiries/repository.js.map +1 -0
  162. package/dist/modules/enquiries/routes.d.ts +52 -0
  163. package/dist/modules/enquiries/routes.d.ts.map +1 -0
  164. package/dist/modules/enquiries/routes.js +127 -0
  165. package/dist/modules/enquiries/routes.js.map +1 -0
  166. package/dist/modules/enquiries/schema.d.ts +290 -0
  167. package/dist/modules/enquiries/schema.d.ts.map +1 -0
  168. package/dist/modules/enquiries/schema.js +52 -0
  169. package/dist/modules/enquiries/schema.js.map +1 -0
  170. package/dist/modules/enquiries/service.d.ts +85 -0
  171. package/dist/modules/enquiries/service.d.ts.map +1 -0
  172. package/dist/modules/enquiries/service.js +370 -0
  173. package/dist/modules/enquiries/service.js.map +1 -0
  174. package/dist/modules/enquiries/tools.d.ts +4 -0
  175. package/dist/modules/enquiries/tools.d.ts.map +1 -0
  176. package/dist/modules/enquiries/tools.js +50 -0
  177. package/dist/modules/enquiries/tools.js.map +1 -0
  178. package/dist/modules/eventCatalogs.d.ts +3 -0
  179. package/dist/modules/eventCatalogs.d.ts.map +1 -1
  180. package/dist/modules/eventCatalogs.js +3 -0
  181. package/dist/modules/eventCatalogs.js.map +1 -1
  182. package/dist/modules/forms/embed.d.ts +20 -6
  183. package/dist/modules/forms/embed.d.ts.map +1 -1
  184. package/dist/modules/forms/embed.js +359 -43
  185. package/dist/modules/forms/embed.js.map +1 -1
  186. package/dist/modules/forms/events.d.ts +20 -7
  187. package/dist/modules/forms/events.d.ts.map +1 -1
  188. package/dist/modules/forms/events.js +20 -2
  189. package/dist/modules/forms/events.js.map +1 -1
  190. package/dist/modules/forms/fields.d.ts +14 -1
  191. package/dist/modules/forms/fields.d.ts.map +1 -1
  192. package/dist/modules/forms/fields.js +87 -3
  193. package/dist/modules/forms/fields.js.map +1 -1
  194. package/dist/modules/forms/index.d.ts.map +1 -1
  195. package/dist/modules/forms/index.js +12 -1
  196. package/dist/modules/forms/index.js.map +1 -1
  197. package/dist/modules/forms/mapping.d.ts +62 -5
  198. package/dist/modules/forms/mapping.d.ts.map +1 -1
  199. package/dist/modules/forms/mapping.js +139 -5
  200. package/dist/modules/forms/mapping.js.map +1 -1
  201. package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
  202. package/dist/modules/forms/publicRoutes.js +29 -1
  203. package/dist/modules/forms/publicRoutes.js.map +1 -1
  204. package/dist/modules/forms/repository.d.ts +31 -0
  205. package/dist/modules/forms/repository.d.ts.map +1 -1
  206. package/dist/modules/forms/repository.js +90 -1
  207. package/dist/modules/forms/repository.js.map +1 -1
  208. package/dist/modules/forms/routes.d.ts +83 -1
  209. package/dist/modules/forms/routes.d.ts.map +1 -1
  210. package/dist/modules/forms/routes.js +185 -2
  211. package/dist/modules/forms/routes.js.map +1 -1
  212. package/dist/modules/forms/schema.d.ts +672 -1
  213. package/dist/modules/forms/schema.d.ts.map +1 -1
  214. package/dist/modules/forms/schema.js +146 -3
  215. package/dist/modules/forms/schema.js.map +1 -1
  216. package/dist/modules/forms/service.d.ts +54 -1
  217. package/dist/modules/forms/service.d.ts.map +1 -1
  218. package/dist/modules/forms/service.js +338 -28
  219. package/dist/modules/forms/service.js.map +1 -1
  220. package/dist/modules/forms/submission.d.ts +15 -0
  221. package/dist/modules/forms/submission.d.ts.map +1 -1
  222. package/dist/modules/forms/submission.js +418 -40
  223. package/dist/modules/forms/submission.js.map +1 -1
  224. package/dist/modules/import-export/drafts.d.ts +10 -0
  225. package/dist/modules/import-export/drafts.d.ts.map +1 -1
  226. package/dist/modules/import-export/drafts.js +16 -2
  227. package/dist/modules/import-export/drafts.js.map +1 -1
  228. package/dist/modules/import-export/exportRows.d.ts +7 -4
  229. package/dist/modules/import-export/exportRows.d.ts.map +1 -1
  230. package/dist/modules/import-export/exportRows.js +20 -5
  231. package/dist/modules/import-export/exportRows.js.map +1 -1
  232. package/dist/modules/import-export/plan.d.ts +12 -1
  233. package/dist/modules/import-export/plan.d.ts.map +1 -1
  234. package/dist/modules/import-export/plan.js +29 -2
  235. package/dist/modules/import-export/plan.js.map +1 -1
  236. package/dist/modules/import-export/presets.d.ts.map +1 -1
  237. package/dist/modules/import-export/presets.js +10 -0
  238. package/dist/modules/import-export/presets.js.map +1 -1
  239. package/dist/modules/import-export/repository.d.ts +11 -1
  240. package/dist/modules/import-export/repository.d.ts.map +1 -1
  241. package/dist/modules/import-export/repository.js +42 -9
  242. package/dist/modules/import-export/repository.js.map +1 -1
  243. package/dist/modules/import-export/routes.d.ts.map +1 -1
  244. package/dist/modules/import-export/routes.js +4 -0
  245. package/dist/modules/import-export/routes.js.map +1 -1
  246. package/dist/modules/import-export/schema.d.ts +17 -0
  247. package/dist/modules/import-export/schema.d.ts.map +1 -1
  248. package/dist/modules/import-export/schema.js +11 -0
  249. package/dist/modules/import-export/schema.js.map +1 -1
  250. package/dist/modules/import-export/service.d.ts +6 -0
  251. package/dist/modules/import-export/service.d.ts.map +1 -1
  252. package/dist/modules/import-export/service.js +14 -2
  253. package/dist/modules/import-export/service.js.map +1 -1
  254. package/dist/modules/import-export/streams.d.ts.map +1 -1
  255. package/dist/modules/import-export/streams.js +3 -3
  256. package/dist/modules/import-export/streams.js.map +1 -1
  257. package/dist/modules/import-export/tools.d.ts.map +1 -1
  258. package/dist/modules/import-export/tools.js +8 -0
  259. package/dist/modules/import-export/tools.js.map +1 -1
  260. package/dist/modules/import-export/validation.d.ts.map +1 -1
  261. package/dist/modules/import-export/validation.js +22 -1
  262. package/dist/modules/import-export/validation.js.map +1 -1
  263. package/dist/modules/import-export/writes.d.ts.map +1 -1
  264. package/dist/modules/import-export/writes.js +37 -4
  265. package/dist/modules/import-export/writes.js.map +1 -1
  266. package/dist/modules/lists/index.d.ts +38 -0
  267. package/dist/modules/lists/index.d.ts.map +1 -1
  268. package/dist/modules/lists/index.js +27 -0
  269. package/dist/modules/lists/index.js.map +1 -1
  270. package/dist/modules/lists/repository.d.ts +26 -0
  271. package/dist/modules/lists/repository.d.ts.map +1 -1
  272. package/dist/modules/lists/repository.js +32 -0
  273. package/dist/modules/lists/repository.js.map +1 -1
  274. package/dist/modules/lists/routes.d.ts +4 -0
  275. package/dist/modules/lists/routes.d.ts.map +1 -1
  276. package/dist/modules/lists/routes.js +8 -0
  277. package/dist/modules/lists/routes.js.map +1 -1
  278. package/dist/modules/lists/schema.d.ts +17 -0
  279. package/dist/modules/lists/schema.d.ts.map +1 -1
  280. package/dist/modules/lists/schema.js +10 -0
  281. package/dist/modules/lists/schema.js.map +1 -1
  282. package/dist/modules/lists/service.d.ts +14 -2
  283. package/dist/modules/lists/service.d.ts.map +1 -1
  284. package/dist/modules/lists/service.js +55 -7
  285. package/dist/modules/lists/service.js.map +1 -1
  286. package/dist/modules/mcp/index.d.ts.map +1 -1
  287. package/dist/modules/mcp/index.js +5 -0
  288. package/dist/modules/mcp/index.js.map +1 -1
  289. package/dist/modules/notes/routes.d.ts +1 -0
  290. package/dist/modules/notes/routes.d.ts.map +1 -1
  291. package/dist/modules/opportunities/index.d.ts.map +1 -1
  292. package/dist/modules/opportunities/index.js +3 -1
  293. package/dist/modules/opportunities/index.js.map +1 -1
  294. package/dist/modules/opportunities/repository.d.ts +2 -0
  295. package/dist/modules/opportunities/repository.d.ts.map +1 -1
  296. package/dist/modules/opportunities/repository.js +4 -0
  297. package/dist/modules/opportunities/repository.js.map +1 -1
  298. package/dist/modules/opportunities/routes.d.ts +16 -0
  299. package/dist/modules/opportunities/routes.d.ts.map +1 -1
  300. package/dist/modules/opportunities/routes.js +13 -0
  301. package/dist/modules/opportunities/routes.js.map +1 -1
  302. package/dist/modules/opportunities/schema.d.ts +20 -0
  303. package/dist/modules/opportunities/schema.d.ts.map +1 -1
  304. package/dist/modules/opportunities/schema.js +6 -1
  305. package/dist/modules/opportunities/schema.js.map +1 -1
  306. package/dist/modules/opportunities/service.d.ts +20 -3
  307. package/dist/modules/opportunities/service.d.ts.map +1 -1
  308. package/dist/modules/opportunities/service.js +99 -18
  309. package/dist/modules/opportunities/service.js.map +1 -1
  310. package/dist/modules/opportunities/tools.d.ts.map +1 -1
  311. package/dist/modules/opportunities/tools.js +2 -0
  312. package/dist/modules/opportunities/tools.js.map +1 -1
  313. package/dist/modules/partnerships/index.d.ts.map +1 -1
  314. package/dist/modules/partnerships/index.js +3 -1
  315. package/dist/modules/partnerships/index.js.map +1 -1
  316. package/dist/modules/partnerships/repository.d.ts +0 -17
  317. package/dist/modules/partnerships/repository.d.ts.map +1 -1
  318. package/dist/modules/partnerships/repository.js +6 -82
  319. package/dist/modules/partnerships/repository.js.map +1 -1
  320. package/dist/modules/partnerships/routes.d.ts +14 -0
  321. package/dist/modules/partnerships/routes.d.ts.map +1 -1
  322. package/dist/modules/partnerships/routes.js +7 -0
  323. package/dist/modules/partnerships/routes.js.map +1 -1
  324. package/dist/modules/partnerships/schema.d.ts +20 -41
  325. package/dist/modules/partnerships/schema.d.ts.map +1 -1
  326. package/dist/modules/partnerships/schema.js +6 -10
  327. package/dist/modules/partnerships/schema.js.map +1 -1
  328. package/dist/modules/partnerships/service.d.ts +11 -1
  329. package/dist/modules/partnerships/service.d.ts.map +1 -1
  330. package/dist/modules/partnerships/service.js +43 -20
  331. package/dist/modules/partnerships/service.js.map +1 -1
  332. package/dist/modules/people/consentHydration.d.ts +26 -0
  333. package/dist/modules/people/consentHydration.d.ts.map +1 -0
  334. package/dist/modules/people/consentHydration.js +100 -0
  335. package/dist/modules/people/consentHydration.js.map +1 -0
  336. package/dist/modules/people/index.d.ts.map +1 -1
  337. package/dist/modules/people/index.js +3 -1
  338. package/dist/modules/people/index.js.map +1 -1
  339. package/dist/modules/people/personConsentWrites.d.ts +40 -0
  340. package/dist/modules/people/personConsentWrites.d.ts.map +1 -0
  341. package/dist/modules/people/personConsentWrites.js +98 -0
  342. package/dist/modules/people/personConsentWrites.js.map +1 -0
  343. package/dist/modules/people/repository.d.ts.map +1 -1
  344. package/dist/modules/people/repository.js +5 -1
  345. package/dist/modules/people/repository.js.map +1 -1
  346. package/dist/modules/people/routes.d.ts +57 -4
  347. package/dist/modules/people/routes.d.ts.map +1 -1
  348. package/dist/modules/people/routes.js +104 -5
  349. package/dist/modules/people/routes.js.map +1 -1
  350. package/dist/modules/people/schema.d.ts +366 -1
  351. package/dist/modules/people/schema.d.ts.map +1 -1
  352. package/dist/modules/people/schema.js +92 -2
  353. package/dist/modules/people/schema.js.map +1 -1
  354. package/dist/modules/people/service.d.ts +30 -1
  355. package/dist/modules/people/service.d.ts.map +1 -1
  356. package/dist/modules/people/service.js +115 -38
  357. package/dist/modules/people/service.js.map +1 -1
  358. package/dist/modules/people/tools.d.ts.map +1 -1
  359. package/dist/modules/people/tools.js +4 -1
  360. package/dist/modules/people/tools.js.map +1 -1
  361. package/dist/modules/personLinks.d.ts +79 -0
  362. package/dist/modules/personLinks.d.ts.map +1 -0
  363. package/dist/modules/personLinks.js +155 -0
  364. package/dist/modules/personLinks.js.map +1 -0
  365. package/dist/modules/pipelines/routes.d.ts +1 -0
  366. package/dist/modules/pipelines/routes.d.ts.map +1 -1
  367. package/dist/modules/plans/routes.d.ts +1 -0
  368. package/dist/modules/plans/routes.d.ts.map +1 -1
  369. package/dist/modules/raises/index.d.ts.map +1 -1
  370. package/dist/modules/raises/index.js +3 -1
  371. package/dist/modules/raises/index.js.map +1 -1
  372. package/dist/modules/raises/repository.d.ts +0 -17
  373. package/dist/modules/raises/repository.d.ts.map +1 -1
  374. package/dist/modules/raises/repository.js +6 -77
  375. package/dist/modules/raises/repository.js.map +1 -1
  376. package/dist/modules/raises/routes.d.ts +14 -0
  377. package/dist/modules/raises/routes.d.ts.map +1 -1
  378. package/dist/modules/raises/routes.js +7 -0
  379. package/dist/modules/raises/routes.js.map +1 -1
  380. package/dist/modules/raises/schema.d.ts +20 -41
  381. package/dist/modules/raises/schema.d.ts.map +1 -1
  382. package/dist/modules/raises/schema.js +6 -10
  383. package/dist/modules/raises/schema.js.map +1 -1
  384. package/dist/modules/raises/service.d.ts +11 -1
  385. package/dist/modules/raises/service.d.ts.map +1 -1
  386. package/dist/modules/raises/service.js +41 -18
  387. package/dist/modules/raises/service.js.map +1 -1
  388. package/dist/modules/recordTargets.d.ts.map +1 -1
  389. package/dist/modules/recordTargets.js +2 -0
  390. package/dist/modules/recordTargets.js.map +1 -1
  391. package/dist/modules/references.d.ts +10 -0
  392. package/dist/modules/references.d.ts.map +1 -1
  393. package/dist/modules/references.js +27 -4
  394. package/dist/modules/references.js.map +1 -1
  395. package/dist/modules/sample-data/fixture.d.ts +21 -0
  396. package/dist/modules/sample-data/fixture.d.ts.map +1 -1
  397. package/dist/modules/sample-data/fixture.js +40 -0
  398. package/dist/modules/sample-data/fixture.js.map +1 -1
  399. package/dist/modules/sample-data/index.d.ts.map +1 -1
  400. package/dist/modules/sample-data/index.js +1 -0
  401. package/dist/modules/sample-data/index.js.map +1 -1
  402. package/dist/modules/sample-data/routes.d.ts.map +1 -1
  403. package/dist/modules/sample-data/routes.js +1 -0
  404. package/dist/modules/sample-data/routes.js.map +1 -1
  405. package/dist/modules/sample-data/service.d.ts +1 -0
  406. package/dist/modules/sample-data/service.d.ts.map +1 -1
  407. package/dist/modules/sample-data/service.js +77 -8
  408. package/dist/modules/sample-data/service.js.map +1 -1
  409. package/dist/modules/search/index.d.ts +1 -1
  410. package/dist/modules/search/index.d.ts.map +1 -1
  411. package/dist/modules/search/index.js +2 -1
  412. package/dist/modules/search/index.js.map +1 -1
  413. package/dist/modules/search/repository.d.ts +1 -0
  414. package/dist/modules/search/repository.d.ts.map +1 -1
  415. package/dist/modules/search/repository.js +23 -0
  416. package/dist/modules/search/repository.js.map +1 -1
  417. package/dist/modules/search/service.d.ts +3 -3
  418. package/dist/modules/search/service.d.ts.map +1 -1
  419. package/dist/modules/search/service.js +5 -4
  420. package/dist/modules/search/service.js.map +1 -1
  421. package/dist/modules/stagedRecords.d.ts +3 -3
  422. package/dist/modules/stagedRecords.d.ts.map +1 -1
  423. package/dist/modules/stagedRecords.js +9 -0
  424. package/dist/modules/stagedRecords.js.map +1 -1
  425. package/dist/modules/webhooks/payloads.d.ts.map +1 -1
  426. package/dist/modules/webhooks/payloads.js +15 -2
  427. package/dist/modules/webhooks/payloads.js.map +1 -1
  428. package/dist/modules/workspace/repository.d.ts +2 -0
  429. package/dist/modules/workspace/repository.d.ts.map +1 -1
  430. package/dist/modules/workspace/repository.js +7 -0
  431. package/dist/modules/workspace/repository.js.map +1 -1
  432. package/dist/modules/workspace/service.d.ts.map +1 -1
  433. package/dist/modules/workspace/service.js +10 -0
  434. package/dist/modules/workspace/service.js.map +1 -1
  435. package/dist/modules/workspace/starters.d.ts.map +1 -1
  436. package/dist/modules/workspace/starters.js +5 -0
  437. package/dist/modules/workspace/starters.js.map +1 -1
  438. package/dist/runtime/events.d.ts +1 -1
  439. package/dist/runtime/events.d.ts.map +1 -1
  440. package/dist/runtime/events.js +1 -0
  441. package/dist/runtime/events.js.map +1 -1
  442. package/dist/schema/index.d.ts +3 -0
  443. package/dist/schema/index.d.ts.map +1 -1
  444. package/dist/schema/index.js +3 -0
  445. package/dist/schema/index.js.map +1 -1
  446. package/dist/testing/database.d.ts +5 -1
  447. package/dist/testing/database.d.ts.map +1 -1
  448. package/dist/testing/database.js +81 -10
  449. package/dist/testing/database.js.map +1 -1
  450. package/migrations/0024_third_king_cobra.sql +46 -0
  451. package/migrations/0025_worthless_chimera.sql +3 -0
  452. package/migrations/0026_late_aqueduct.sql +46 -0
  453. package/migrations/0027_brainy_silver_sable.sql +3 -0
  454. package/migrations/0028_freezing_scrambler.sql +19 -0
  455. package/migrations/0029_custom_fields.sql +26 -0
  456. package/migrations/0030_enquiries.sql +79 -0
  457. package/migrations/0031_consent.sql +45 -0
  458. package/migrations/0032_form_field_statement.sql +1 -0
  459. package/migrations/0033_form_field_consent_purpose_ids.sql +5 -0
  460. package/migrations/0034_drop_form_field_consent_purpose_id.sql +1 -0
  461. package/migrations/0035_form_field_consent_purpose_labels.sql +1 -0
  462. package/migrations/0036_form_field_notice_type.sql +2 -0
  463. package/migrations/meta/0024_snapshot.json +5516 -0
  464. package/migrations/meta/0025_snapshot.json +5336 -0
  465. package/migrations/meta/0026_snapshot.json +5710 -0
  466. package/migrations/meta/0027_snapshot.json +5716 -0
  467. package/migrations/meta/0028_snapshot.json +5740 -0
  468. package/migrations/meta/0029_snapshot.json +5935 -0
  469. package/migrations/meta/0030_snapshot.json +6245 -0
  470. package/migrations/meta/0031_snapshot.json +6572 -0
  471. package/migrations/meta/0032_snapshot.json +6578 -0
  472. package/migrations/meta/0033_snapshot.json +6572 -0
  473. package/migrations/meta/0034_snapshot.json +6566 -0
  474. package/migrations/meta/0035_snapshot.json +6573 -0
  475. package/migrations/meta/0036_snapshot.json +6573 -0
  476. package/migrations/meta/_journal.json +91 -0
  477. package/package.json +2 -2
  478. package/src/index.ts +6 -0
  479. package/src/lib/ids.ts +11 -0
  480. package/src/modules/activities/repository.ts +22 -23
  481. package/src/modules/activities/wording.ts +18 -0
  482. package/src/modules/agent-tasks/catalog.ts +63 -0
  483. package/src/modules/agent-tasks/resolve.ts +64 -24
  484. package/src/modules/attachedRecords.ts +29 -2
  485. package/src/modules/companies/index.ts +3 -1
  486. package/src/modules/companies/routes.ts +7 -0
  487. package/src/modules/companies/schema.ts +7 -1
  488. package/src/modules/companies/service.ts +48 -13
  489. package/src/modules/consent-purposes/capabilities.ts +12 -0
  490. package/src/modules/consent-purposes/events.ts +38 -0
  491. package/src/modules/consent-purposes/index.ts +48 -0
  492. package/src/modules/consent-purposes/repository.ts +163 -0
  493. package/src/modules/consent-purposes/routes.ts +122 -0
  494. package/src/modules/consent-purposes/schema.ts +46 -0
  495. package/src/modules/consent-purposes/service.ts +423 -0
  496. package/src/modules/consent-purposes/starters.ts +32 -0
  497. package/src/modules/consent-purposes/tools.ts +44 -0
  498. package/src/modules/core.ts +10 -0
  499. package/src/modules/custom-fields/capabilities.ts +17 -0
  500. package/src/modules/custom-fields/events.ts +51 -0
  501. package/src/modules/custom-fields/index.ts +61 -0
  502. package/src/modules/custom-fields/repository.ts +225 -0
  503. package/src/modules/custom-fields/routes.ts +155 -0
  504. package/src/modules/custom-fields/schema.ts +61 -0
  505. package/src/modules/custom-fields/service.ts +439 -0
  506. package/src/modules/custom-fields/tools.ts +53 -0
  507. package/src/modules/custom-fields/values.ts +352 -0
  508. package/src/modules/custom-fields/wire.ts +32 -0
  509. package/src/modules/dashboard/repository.ts +4 -3
  510. package/src/modules/deals/index.ts +5 -2
  511. package/src/modules/deals/repository.ts +6 -106
  512. package/src/modules/deals/routes.ts +7 -0
  513. package/src/modules/deals/schema.ts +7 -15
  514. package/src/modules/deals/service.ts +92 -23
  515. package/src/modules/decisions/repository.ts +2 -0
  516. package/src/modules/enquiries/events.ts +45 -0
  517. package/src/modules/enquiries/index.ts +50 -0
  518. package/src/modules/enquiries/repository.ts +164 -0
  519. package/src/modules/enquiries/routes.ts +172 -0
  520. package/src/modules/enquiries/schema.ts +59 -0
  521. package/src/modules/enquiries/service.ts +644 -0
  522. package/src/modules/enquiries/tools.ts +66 -0
  523. package/src/modules/eventCatalogs.ts +3 -0
  524. package/src/modules/forms/embed.ts +391 -44
  525. package/src/modules/forms/events.ts +30 -2
  526. package/src/modules/forms/fields.ts +102 -2
  527. package/src/modules/forms/index.ts +12 -1
  528. package/src/modules/forms/mapping.ts +183 -6
  529. package/src/modules/forms/publicRoutes.ts +43 -1
  530. package/src/modules/forms/repository.ts +162 -1
  531. package/src/modules/forms/routes.ts +212 -2
  532. package/src/modules/forms/schema.ts +166 -4
  533. package/src/modules/forms/service.ts +565 -41
  534. package/src/modules/forms/submission.ts +718 -44
  535. package/src/modules/import-export/drafts.ts +20 -1
  536. package/src/modules/import-export/exportRows.ts +21 -5
  537. package/src/modules/import-export/plan.ts +47 -2
  538. package/src/modules/import-export/presets.ts +10 -0
  539. package/src/modules/import-export/repository.ts +73 -8
  540. package/src/modules/import-export/routes.ts +4 -0
  541. package/src/modules/import-export/schema.ts +11 -0
  542. package/src/modules/import-export/service.ts +28 -2
  543. package/src/modules/import-export/streams.ts +3 -1
  544. package/src/modules/import-export/tools.ts +10 -0
  545. package/src/modules/import-export/validation.ts +28 -0
  546. package/src/modules/import-export/writes.ts +70 -5
  547. package/src/modules/lists/index.ts +71 -0
  548. package/src/modules/lists/repository.ts +64 -0
  549. package/src/modules/lists/routes.ts +8 -0
  550. package/src/modules/lists/schema.ts +10 -0
  551. package/src/modules/lists/service.ts +110 -9
  552. package/src/modules/mcp/index.ts +5 -0
  553. package/src/modules/opportunities/index.ts +3 -1
  554. package/src/modules/opportunities/repository.ts +11 -0
  555. package/src/modules/opportunities/routes.ts +13 -0
  556. package/src/modules/opportunities/schema.ts +7 -1
  557. package/src/modules/opportunities/service.ts +188 -22
  558. package/src/modules/opportunities/tools.ts +2 -0
  559. package/src/modules/partnerships/index.ts +3 -1
  560. package/src/modules/partnerships/repository.ts +6 -117
  561. package/src/modules/partnerships/routes.ts +7 -0
  562. package/src/modules/partnerships/schema.ts +7 -14
  563. package/src/modules/partnerships/service.ts +93 -22
  564. package/src/modules/people/consentHydration.ts +167 -0
  565. package/src/modules/people/index.ts +3 -1
  566. package/src/modules/people/personConsentWrites.ts +177 -0
  567. package/src/modules/people/repository.ts +5 -0
  568. package/src/modules/people/routes.ts +127 -18
  569. package/src/modules/people/schema.ts +109 -3
  570. package/src/modules/people/service.ts +186 -40
  571. package/src/modules/people/tools.ts +5 -1
  572. package/src/modules/personLinks.ts +278 -0
  573. package/src/modules/raises/index.ts +3 -1
  574. package/src/modules/raises/repository.ts +6 -107
  575. package/src/modules/raises/routes.ts +7 -0
  576. package/src/modules/raises/schema.ts +7 -14
  577. package/src/modules/raises/service.ts +91 -20
  578. package/src/modules/recordTargets.ts +2 -0
  579. package/src/modules/references.ts +43 -4
  580. package/src/modules/sample-data/fixture.ts +63 -0
  581. package/src/modules/sample-data/index.ts +1 -0
  582. package/src/modules/sample-data/routes.ts +1 -0
  583. package/src/modules/sample-data/service.ts +97 -8
  584. package/src/modules/search/index.ts +2 -1
  585. package/src/modules/search/repository.ts +33 -1
  586. package/src/modules/search/service.ts +7 -5
  587. package/src/modules/stagedRecords.ts +18 -3
  588. package/src/modules/webhooks/payloads.ts +20 -2
  589. package/src/modules/workspace/repository.ts +12 -0
  590. package/src/modules/workspace/service.ts +14 -0
  591. package/src/modules/workspace/starters.ts +5 -0
  592. package/src/runtime/events.ts +1 -0
  593. package/src/schema/index.ts +3 -0
  594. package/src/testing/database.ts +97 -11
@@ -0,0 +1,644 @@
1
+ import type { CustomFieldWireValue } from '@kelpie/schemas'
2
+
3
+ import { changedKeys } from '../../lib/changes.ts'
4
+ import type { Database } from '../../lib/database.ts'
5
+ import { AppError } from '../../lib/errors.ts'
6
+ import type { IdFactory } from '../../lib/ids.ts'
7
+ import { readListWindow, toPage } from '../../lib/pagination.ts'
8
+ import type { ListQueryParameters, Page } from '../../lib/pagination.ts'
9
+ import type { TransactionScope } from '../../runtime/transaction.ts'
10
+ import type { ActivityRecorder } from '../activities/recorder.ts'
11
+ import {
12
+ describeConversion,
13
+ describeCreation,
14
+ describeCreationFrom,
15
+ describeLink,
16
+ describeStageChange,
17
+ describeUnlink,
18
+ describeUpdate,
19
+ } from '../activities/wording.ts'
20
+ import type { FieldLabels } from '../activities/wording.ts'
21
+ import { toEventActor } from '../../lib/actor.ts'
22
+ import type { Actor } from '../auth/actor.ts'
23
+ import { actorMemberId, requireWorkspaceId } from '../auth/actor.ts'
24
+ import './events.ts'
25
+ import '../deals/events.ts'
26
+ import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
27
+ import * as companyRepository from '../companies/repository.ts'
28
+ import type { CustomFieldValuesValidator } from '../custom-fields/values.ts'
29
+ import * as dealRepository from '../deals/repository.ts'
30
+ import type { DealRecord } from '../deals/repository.ts'
31
+ import * as personLinks from '../personLinks.ts'
32
+ import * as pipelineRepository from '../pipelines/repository.ts'
33
+ import type { PipelineStageRecord } from '../pipelines/repository.ts'
34
+ import * as repository from './repository.ts'
35
+ import { DEFAULT_ENQUIRY_SORT, ENQUIRY_SORTS } from './repository.ts'
36
+ import type { EnquiryFilters, EnquiryRecord } from './repository.ts'
37
+
38
+ /**
39
+ * Enquiries: the top-of-funnel pipeline. Inbound requests that may become a
40
+ * Deal once qualified. People attach through `person_links`; company is
41
+ * optional (some enquiries arrive before a company is on file).
42
+ *
43
+ * A stage move is an ordinary PATCH of `stage_id`, and it is the one change
44
+ * that files a `stage_changed` activity and a `stage.changed` event instead of
45
+ * the generic update pair.
46
+ *
47
+ * The one non-CRUD action is `convertToDeal`, which is what
48
+ * `POST /v1/enquiries/:id/convert` calls: it inserts a new deal, copies the
49
+ * enquiry's people to it, sets `convertedDealId`, and moves the enquiry to
50
+ * its first closed stage.
51
+ */
52
+
53
+ export interface EnquiriesDependencies {
54
+ readonly db: Database
55
+ readonly transaction: TransactionScope
56
+ readonly createId: IdFactory
57
+ readonly now: () => Date
58
+ readonly recordActivity: ActivityRecorder
59
+ readonly customFields: CustomFieldValuesValidator
60
+ }
61
+
62
+ /** What a changed column is called on a timeline. */
63
+ const ENQUIRY_FIELD_LABELS: FieldLabels = {
64
+ name: 'Name',
65
+ source: 'Source',
66
+ companyId: 'Company',
67
+ ownerId: 'Owner',
68
+ summary: 'Summary',
69
+ tags: 'Tags',
70
+ }
71
+
72
+ /** An enquiry as the API returns one: the stored row minus tenancy, plus its people. */
73
+ export type EnquiryView = Omit<EnquiryRecord, 'workspaceId'> & {
74
+ readonly personIds: readonly string[]
75
+ }
76
+
77
+ export interface CreateEnquiryInput {
78
+ readonly name: string
79
+ /** Free text ("Website", "Email", "Referral"). Empty means unclassified. */
80
+ readonly source: string
81
+ /** Absent means the pipeline's default stage: the first open one. */
82
+ readonly stageId: string | undefined
83
+ readonly companyId: string | null
84
+ /** Absent means the caller: the member creating an enquiry starts as its owner. */
85
+ readonly ownerId: string | null | undefined
86
+ readonly personIds: readonly string[]
87
+ readonly summary: string
88
+ readonly tags: readonly string[]
89
+ /** Wire shape for a create body: `null` values are ignored, non-null are validated. */
90
+ readonly customFields: Readonly<Record<string, CustomFieldWireValue | null>> | undefined
91
+ }
92
+
93
+ /** PATCH semantics: an absent field is left alone, and null clears a nullable one. */
94
+ export interface UpdateEnquiryInput {
95
+ readonly name?: string | undefined
96
+ readonly source?: string | undefined
97
+ readonly stageId?: string | undefined
98
+ readonly companyId?: string | null | undefined
99
+ readonly ownerId?: string | null | undefined
100
+ /** Replaces the set. The service works out who was added and who left. */
101
+ readonly personIds?: readonly string[] | undefined
102
+ readonly summary?: string | undefined
103
+ readonly tags?: readonly string[] | undefined
104
+ /**
105
+ * Partial merge patch (wire shape): sent keys change, `null` clears a key,
106
+ * absent keys are left alone. Unknown keys are `422`.
107
+ */
108
+ readonly customFields?: Readonly<Record<string, CustomFieldWireValue | null>> | undefined
109
+ }
110
+
111
+ /** What `convertToDeal` returns: the freshly created deal, plus its people. */
112
+ export interface ConvertedDealView {
113
+ readonly deal: DealRecord
114
+ readonly personIds: readonly string[]
115
+ }
116
+
117
+ export interface EnquiriesService {
118
+ list(
119
+ actor: Actor,
120
+ filters: EnquiryFilters,
121
+ query: ListQueryParameters,
122
+ ): Promise<Page<EnquiryView>>
123
+ get(actor: Actor, id: string): Promise<EnquiryView>
124
+ create(actor: Actor, input: CreateEnquiryInput): Promise<EnquiryView>
125
+ update(actor: Actor, id: string, changes: UpdateEnquiryInput): Promise<EnquiryView>
126
+ remove(actor: Actor, id: string): Promise<void>
127
+ convertToDeal(actor: Actor, id: string): Promise<ConvertedDealView>
128
+ }
129
+
130
+ function toView(record: EnquiryRecord, personIds: readonly string[]): EnquiryView {
131
+ const { workspaceId: _workspaceId, ...view } = record
132
+
133
+ return { ...view, personIds }
134
+ }
135
+
136
+ function toStoredColumns(input: UpdateEnquiryInput): Partial<repository.EnquiryColumns> {
137
+ return {
138
+ ...(input.name === undefined ? {} : { name: input.name }),
139
+ ...(input.source === undefined ? {} : { source: input.source }),
140
+ ...(input.stageId === undefined ? {} : { stageId: input.stageId }),
141
+ ...(input.companyId === undefined ? {} : { companyId: input.companyId }),
142
+ ...(input.ownerId === undefined ? {} : { ownerId: input.ownerId }),
143
+ ...(input.summary === undefined ? {} : { summary: input.summary }),
144
+ ...(input.tags === undefined ? {} : { tags: [...input.tags] }),
145
+ }
146
+ }
147
+
148
+ export function createEnquiriesService(dependencies: EnquiriesDependencies): EnquiriesService {
149
+ async function require(workspaceId: string, id: string): Promise<EnquiryRecord> {
150
+ const enquiry = await repository.findEnquiry(dependencies.db, workspaceId, id)
151
+
152
+ if (enquiry === undefined) {
153
+ throw AppError.notFound('Enquiry not found')
154
+ }
155
+
156
+ return enquiry
157
+ }
158
+
159
+ async function requireCompany(workspaceId: string, companyId: string): Promise<void> {
160
+ const company = await companyRepository.findCompany(dependencies.db, workspaceId, companyId)
161
+
162
+ if (company === undefined) {
163
+ throw AppError.notFound('Company not found')
164
+ }
165
+ }
166
+
167
+ /**
168
+ * A stage an enquiry may sit in: exists in this workspace and belongs to the
169
+ * enquiry pipeline. The wrong-workspace case reads as missing; the
170
+ * wrong-pipeline case is a request naming a real stage that can never hold an
171
+ * enquiry, which is a validation error rather than a missing record.
172
+ */
173
+ async function requireEnquiryStage(
174
+ workspaceId: string,
175
+ stageId: string,
176
+ ): Promise<PipelineStageRecord> {
177
+ const stage = await pipelineRepository.findStage(dependencies.db, workspaceId, stageId)
178
+
179
+ if (stage === undefined) {
180
+ throw AppError.notFound('Pipeline stage not found')
181
+ }
182
+
183
+ if (stage.kind !== 'enquiry') {
184
+ throw AppError.validationFailed('That stage is not part of the enquiry pipeline', [
185
+ { field: 'stage_id', message: `It belongs to the ${stage.kind} pipeline` },
186
+ ])
187
+ }
188
+
189
+ return stage
190
+ }
191
+
192
+ /** The default stage for a new enquiry: the first open one, or the first if none are open. */
193
+ async function defaultEnquiryStage(workspaceId: string): Promise<PipelineStageRecord> {
194
+ const rows = await pipelineRepository.listStagesOfKind(
195
+ dependencies.db,
196
+ workspaceId,
197
+ 'enquiry',
198
+ )
199
+ const first = rows.find((row) => row.open) ?? rows[0]
200
+
201
+ if (first === undefined) {
202
+ // Unreachable through the API: workspaces seed stages and the last stage
203
+ // of a pipeline cannot be removed.
204
+ throw AppError.conflict('This workspace has no enquiry stages')
205
+ }
206
+
207
+ return first
208
+ }
209
+
210
+ async function requireOwner(workspaceId: string, ownerId: string): Promise<void> {
211
+ if (!(await repository.memberExists(dependencies.db, workspaceId, ownerId))) {
212
+ throw AppError.notFound('Team member not found')
213
+ }
214
+ }
215
+
216
+ /** @returns Each person's name, for the link activities. Any id missing here is a 404. */
217
+ async function requirePeople(
218
+ workspaceId: string,
219
+ personIds: readonly string[],
220
+ ): Promise<ReadonlyMap<string, string>> {
221
+ const named = await personLinks.findPeopleNamed(dependencies.db, workspaceId, personIds)
222
+ const missing = personIds.filter((id) => !named.has(id))
223
+
224
+ if (missing.length > 0) {
225
+ throw new AppError(
226
+ 'not_found',
227
+ 'Person not found',
228
+ missing.map((id) => ({ field: 'person_ids', message: `No person ${id} here` })),
229
+ )
230
+ }
231
+
232
+ return named
233
+ }
234
+
235
+ async function toViews(
236
+ workspaceId: string,
237
+ records: readonly EnquiryRecord[],
238
+ ): Promise<EnquiryView[]> {
239
+ const peopleByEnquiry = await personLinks.listPersonIdsFor(
240
+ dependencies.db,
241
+ workspaceId,
242
+ 'enquiry',
243
+ records.map((record) => record.id),
244
+ )
245
+
246
+ return records.map((record) => toView(record, peopleByEnquiry.get(record.id) ?? []))
247
+ }
248
+
249
+ return {
250
+ async list(actor, filters, query) {
251
+ const workspaceId = requireWorkspaceId(actor)
252
+ const window = readListWindow(query, ENQUIRY_SORTS, DEFAULT_ENQUIRY_SORT)
253
+ const rows = await repository.listEnquiries(dependencies.db, workspaceId, filters, window)
254
+ const page = toPage(rows, window, (enquiry) => enquiry.id)
255
+
256
+ return { items: await toViews(workspaceId, page.items), nextCursor: page.nextCursor }
257
+ },
258
+
259
+ async get(actor, id) {
260
+ const workspaceId = requireWorkspaceId(actor)
261
+ const enquiry = await require(workspaceId, id)
262
+
263
+ return toView(
264
+ enquiry,
265
+ await personLinks.listPersonIds(dependencies.db, workspaceId, {
266
+ targetType: 'enquiry',
267
+ targetId: id,
268
+ }),
269
+ )
270
+ },
271
+
272
+ async create(actor, input) {
273
+ const workspaceId = requireWorkspaceId(actor)
274
+
275
+ if (input.companyId !== null) {
276
+ await requireCompany(workspaceId, input.companyId)
277
+ }
278
+
279
+ const stage =
280
+ input.stageId === undefined
281
+ ? await defaultEnquiryStage(workspaceId)
282
+ : await requireEnquiryStage(workspaceId, input.stageId)
283
+ const ownerId = input.ownerId === undefined ? actorMemberId(actor) : input.ownerId
284
+
285
+ if (ownerId !== null) {
286
+ await requireOwner(workspaceId, ownerId)
287
+ }
288
+
289
+ const personIds = [...new Set(input.personIds)]
290
+ const named = await requirePeople(workspaceId, personIds)
291
+ const id = dependencies.createId('enquiry')
292
+
293
+ return dependencies.transaction(async ({ tx, events }) => {
294
+ const customFields = await dependencies.customFields.forCreate(
295
+ tx,
296
+ workspaceId,
297
+ 'enquiry',
298
+ input.customFields,
299
+ )
300
+ const created = await repository.insertEnquiry(tx, {
301
+ id,
302
+ workspaceId,
303
+ name: input.name,
304
+ source: input.source,
305
+ stageId: stage.id,
306
+ companyId: input.companyId,
307
+ ownerId,
308
+ convertedDealId: null,
309
+ summary: input.summary,
310
+ tags: [...input.tags],
311
+ customFields,
312
+ })
313
+
314
+ await personLinks.linkPeople(
315
+ tx,
316
+ dependencies.createId,
317
+ workspaceId,
318
+ { targetType: 'enquiry', targetId: id },
319
+ personIds,
320
+ )
321
+
322
+ await dependencies.recordActivity(tx, workspaceId, actor, {
323
+ targetType: 'enquiry',
324
+ targetId: id,
325
+ kind: 'created',
326
+ ...describeCreation('Enquiry'),
327
+ })
328
+
329
+ for (const personId of personIds) {
330
+ await dependencies.recordActivity(tx, workspaceId, actor, {
331
+ targetType: 'enquiry',
332
+ targetId: id,
333
+ kind: 'linked',
334
+ ...describeLink('person', named.get(personId) ?? personId),
335
+ })
336
+ }
337
+
338
+ events.emit('enquiries.enquiry.created', { type: 'enquiry', id }, {})
339
+
340
+ return toView(created, personIds)
341
+ }, { workspaceId, actor: toEventActor(actor) })
342
+ },
343
+
344
+ async update(actor, id, changes) {
345
+ const workspaceId = requireWorkspaceId(actor)
346
+ const existing = await require(workspaceId, id)
347
+
348
+ if (typeof changes.companyId === 'string' && changes.companyId !== existing.companyId) {
349
+ await requireCompany(workspaceId, changes.companyId)
350
+ }
351
+
352
+ const stageMove =
353
+ changes.stageId === undefined || changes.stageId === existing.stageId
354
+ ? undefined
355
+ : {
356
+ from: await requireEnquiryStage(workspaceId, existing.stageId),
357
+ to: await requireEnquiryStage(workspaceId, changes.stageId),
358
+ }
359
+
360
+ if (typeof changes.ownerId === 'string' && changes.ownerId !== existing.ownerId) {
361
+ await requireOwner(workspaceId, changes.ownerId)
362
+ }
363
+
364
+ const currentPeople = await personLinks.listPersonIds(dependencies.db, workspaceId, {
365
+ targetType: 'enquiry',
366
+ targetId: id,
367
+ })
368
+ const nextPeople =
369
+ changes.personIds === undefined ? undefined : [...new Set(changes.personIds)]
370
+ const added =
371
+ nextPeople === undefined
372
+ ? []
373
+ : nextPeople.filter((personId) => !currentPeople.includes(personId))
374
+ const removed =
375
+ nextPeople === undefined
376
+ ? []
377
+ : currentPeople.filter((personId) => !nextPeople.includes(personId))
378
+ const named = await requirePeople(workspaceId, [...added, ...removed])
379
+
380
+ const columns = toStoredColumns(changes)
381
+ const scalarChanged = changedKeys(existing, columns)
382
+ const linksChanged = added.length > 0 || removed.length > 0
383
+
384
+ return dependencies.transaction(async ({ tx, events }) => {
385
+ const cf = await dependencies.customFields.forUpdate(
386
+ tx,
387
+ workspaceId,
388
+ 'enquiry',
389
+ existing.customFields,
390
+ changes.customFields,
391
+ )
392
+ const customFieldsChanged = cf !== undefined && cf.changedPaths.length > 0
393
+
394
+ if (scalarChanged.length === 0 && !linksChanged && !customFieldsChanged) {
395
+ return toView(existing, currentPeople)
396
+ }
397
+
398
+ const updated = await repository.updateEnquiry(tx, workspaceId, id, {
399
+ ...columns,
400
+ ...(customFieldsChanged ? { customFields: cf.merged } : {}),
401
+ updatedAt: dependencies.now(),
402
+ })
403
+
404
+ if (updated === undefined) {
405
+ throw AppError.notFound('Enquiry not found')
406
+ }
407
+
408
+ await personLinks.linkPeople(
409
+ tx,
410
+ dependencies.createId,
411
+ workspaceId,
412
+ { targetType: 'enquiry', targetId: id },
413
+ added,
414
+ )
415
+ await personLinks.unlinkPeople(
416
+ tx,
417
+ workspaceId,
418
+ { targetType: 'enquiry', targetId: id },
419
+ removed,
420
+ )
421
+
422
+ if (stageMove !== undefined) {
423
+ await dependencies.recordActivity(tx, workspaceId, actor, {
424
+ targetType: 'enquiry',
425
+ targetId: id,
426
+ kind: 'stage_changed',
427
+ ...describeStageChange(stageMove.from.label, stageMove.to.label),
428
+ })
429
+ }
430
+
431
+ const otherChanged = scalarChanged.filter((field) => field !== 'stageId')
432
+ const customFieldPaths = cf?.changedPaths ?? []
433
+ const activityChanged = [...otherChanged, ...customFieldPaths]
434
+
435
+ if (activityChanged.length > 0) {
436
+ const labels: Record<string, string> = { ...ENQUIRY_FIELD_LABELS, ...cf?.labels }
437
+ const before: Record<string, unknown> = { ...existing, ...cf?.flatBefore }
438
+ const after: Record<string, unknown> = { ...columns, ...cf?.flatAfter }
439
+ await dependencies.recordActivity(tx, workspaceId, actor, {
440
+ targetType: 'enquiry',
441
+ targetId: id,
442
+ kind: 'updated',
443
+ ...describeUpdate(activityChanged, labels, before, after),
444
+ })
445
+ }
446
+
447
+ for (const personId of added) {
448
+ await dependencies.recordActivity(tx, workspaceId, actor, {
449
+ targetType: 'enquiry',
450
+ targetId: id,
451
+ kind: 'linked',
452
+ ...describeLink('person', named.get(personId) ?? personId),
453
+ })
454
+ }
455
+
456
+ for (const personId of removed) {
457
+ await dependencies.recordActivity(tx, workspaceId, actor, {
458
+ targetType: 'enquiry',
459
+ targetId: id,
460
+ kind: 'unlinked',
461
+ ...describeUnlink('person', named.get(personId) ?? personId),
462
+ })
463
+ }
464
+
465
+ events.emit(
466
+ 'enquiries.enquiry.updated',
467
+ { type: 'enquiry', id },
468
+ {
469
+ changed: [
470
+ ...scalarChanged,
471
+ ...(linksChanged ? ['personIds'] : []),
472
+ ...customFieldPaths,
473
+ ],
474
+ },
475
+ )
476
+
477
+ if (stageMove !== undefined) {
478
+ events.emit(
479
+ 'enquiries.enquiry.stage_changed',
480
+ { type: 'enquiry', id },
481
+ { fromStageId: stageMove.from.id, toStageId: stageMove.to.id },
482
+ )
483
+ }
484
+
485
+ return toView(updated, nextPeople ?? currentPeople)
486
+ }, { workspaceId, actor: toEventActor(actor) })
487
+ },
488
+
489
+ async remove(actor, id) {
490
+ const workspaceId = requireWorkspaceId(actor)
491
+
492
+ await dependencies.transaction(async ({ tx, events }) => {
493
+ await require(workspaceId, id)
494
+
495
+ // Notes, activities, decisions, plan items, person_links, list
496
+ // memberships and form_attach_targets rows are removed here in the
497
+ // same transaction. `form_submissions.enquiry_id` is a set-null FK, so
498
+ // the DB clears it on its own.
499
+ await deleteRecordsAttachedTo(tx, workspaceId, 'enquiry', id)
500
+ await repository.deleteEnquiry(tx, workspaceId, id)
501
+
502
+ events.emit('enquiries.enquiry.deleted', { type: 'enquiry', id }, {})
503
+ }, { workspaceId, actor: toEventActor(actor) })
504
+ },
505
+
506
+ async convertToDeal(actor, id) {
507
+ const workspaceId = requireWorkspaceId(actor)
508
+ const existing = await require(workspaceId, id)
509
+
510
+ if (existing.convertedDealId !== null) {
511
+ throw new AppError(
512
+ 'conflict',
513
+ 'This enquiry has already been converted to a deal',
514
+ [{ field: 'converted_deal_id', message: `Deal ${existing.convertedDealId}` }],
515
+ )
516
+ }
517
+
518
+ if (existing.companyId === null) {
519
+ throw AppError.validationFailed('An enquiry needs a company before it can become a deal', [
520
+ { field: 'company_id', message: 'Link a company to the enquiry first' },
521
+ ])
522
+ }
523
+
524
+ const dealStages = await pipelineRepository.listStagesOfKind(
525
+ dependencies.db,
526
+ workspaceId,
527
+ 'deal',
528
+ )
529
+ const openDealStage = dealStages.find((row) => row.open) ?? dealStages[0]
530
+
531
+ if (openDealStage === undefined) {
532
+ // Unreachable through the API: workspaces seed stages and the last
533
+ // deal stage cannot be removed.
534
+ throw AppError.conflict('This workspace has no deal stages')
535
+ }
536
+
537
+ const enquiryStages = await pipelineRepository.listStagesOfKind(
538
+ dependencies.db,
539
+ workspaceId,
540
+ 'enquiry',
541
+ )
542
+ // A closed enquiry stage is where a converted enquiry lands. If the
543
+ // workspace has deleted every closed stage we leave the enquiry where it
544
+ // is rather than refuse the conversion over board cosmetics.
545
+ const closedEnquiryStage = enquiryStages.find((row) => !row.open)
546
+
547
+ const personIds = await personLinks.listPersonIds(dependencies.db, workspaceId, {
548
+ targetType: 'enquiry',
549
+ targetId: id,
550
+ })
551
+ const dealId = dependencies.createId('deal')
552
+ const now = dependencies.now()
553
+
554
+ return dependencies.transaction(async ({ tx, events }) => {
555
+ const deal = await dealRepository.insertDeal(tx, {
556
+ id: dealId,
557
+ workspaceId,
558
+ name: existing.name,
559
+ companyId: existing.companyId as string,
560
+ stageId: openDealStage.id,
561
+ valueCents: null,
562
+ currency: null,
563
+ ownerId: existing.ownerId,
564
+ expectedClose: null,
565
+ competitors: [],
566
+ risks: '',
567
+ whyWin: '',
568
+ summary: existing.summary,
569
+ tags: [...existing.tags],
570
+ externalId: null,
571
+ customFields: {},
572
+ })
573
+
574
+ await personLinks.linkPeople(
575
+ tx,
576
+ dependencies.createId,
577
+ workspaceId,
578
+ { targetType: 'deal', targetId: dealId },
579
+ personIds,
580
+ )
581
+
582
+ const stageChanged =
583
+ closedEnquiryStage !== undefined && closedEnquiryStage.id !== existing.stageId
584
+ const currentEnquiryStage = enquiryStages.find((row) => row.id === existing.stageId)
585
+
586
+ const updatedEnquiry = await repository.updateEnquiry(tx, workspaceId, id, {
587
+ convertedDealId: dealId,
588
+ ...(stageChanged ? { stageId: closedEnquiryStage.id } : {}),
589
+ updatedAt: now,
590
+ })
591
+
592
+ if (updatedEnquiry === undefined) {
593
+ throw AppError.notFound('Enquiry not found')
594
+ }
595
+
596
+ await dependencies.recordActivity(tx, workspaceId, actor, {
597
+ targetType: 'deal',
598
+ targetId: dealId,
599
+ kind: 'created',
600
+ ...describeCreationFrom('Deal', 'Enquiry', existing.name),
601
+ })
602
+
603
+ await dependencies.recordActivity(tx, workspaceId, actor, {
604
+ targetType: 'enquiry',
605
+ targetId: id,
606
+ kind: 'updated',
607
+ ...describeConversion('Deal', deal.name),
608
+ })
609
+
610
+ if (stageChanged && currentEnquiryStage !== undefined) {
611
+ await dependencies.recordActivity(tx, workspaceId, actor, {
612
+ targetType: 'enquiry',
613
+ targetId: id,
614
+ kind: 'stage_changed',
615
+ ...describeStageChange(currentEnquiryStage.label, closedEnquiryStage.label),
616
+ })
617
+ }
618
+
619
+ events.emit('deals.deal.created', { type: 'deal', id: dealId }, {})
620
+ events.emit(
621
+ 'enquiries.enquiry.updated',
622
+ { type: 'enquiry', id },
623
+ {
624
+ changed: stageChanged
625
+ ? ['convertedDealId', 'stageId']
626
+ : ['convertedDealId'],
627
+ },
628
+ )
629
+
630
+ if (stageChanged && currentEnquiryStage !== undefined) {
631
+ events.emit(
632
+ 'enquiries.enquiry.stage_changed',
633
+ { type: 'enquiry', id },
634
+ { fromStageId: currentEnquiryStage.id, toStageId: closedEnquiryStage.id },
635
+ )
636
+ }
637
+
638
+ events.emit('enquiries.enquiry.converted', { type: 'enquiry', id }, { dealId })
639
+
640
+ return { deal, personIds }
641
+ }, { workspaceId, actor: toEventActor(actor) })
642
+ },
643
+ }
644
+ }