@kelpie/server 0.8.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 (584) hide show
  1. package/dist/lib/ids.d.ts +11 -0
  2. package/dist/lib/ids.d.ts.map +1 -1
  3. package/dist/lib/ids.js +11 -0
  4. package/dist/lib/ids.js.map +1 -1
  5. package/dist/modules/activities/repository.d.ts.map +1 -1
  6. package/dist/modules/activities/repository.js +19 -20
  7. package/dist/modules/activities/repository.js.map +1 -1
  8. package/dist/modules/activities/wording.d.ts +12 -0
  9. package/dist/modules/activities/wording.d.ts.map +1 -1
  10. package/dist/modules/activities/wording.js +16 -0
  11. package/dist/modules/activities/wording.js.map +1 -1
  12. package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
  13. package/dist/modules/agent-tasks/catalog.js +62 -0
  14. package/dist/modules/agent-tasks/catalog.js.map +1 -1
  15. package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
  16. package/dist/modules/agent-tasks/resolve.js +42 -9
  17. package/dist/modules/agent-tasks/resolve.js.map +1 -1
  18. package/dist/modules/agent-tasks/routes.d.ts +2 -0
  19. package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
  20. package/dist/modules/attachedRecords.d.ts +6 -1
  21. package/dist/modules/attachedRecords.d.ts.map +1 -1
  22. package/dist/modules/attachedRecords.js +15 -1
  23. package/dist/modules/attachedRecords.js.map +1 -1
  24. package/dist/modules/companies/index.d.ts.map +1 -1
  25. package/dist/modules/companies/index.js +3 -1
  26. package/dist/modules/companies/index.js.map +1 -1
  27. package/dist/modules/companies/routes.d.ts +14 -0
  28. package/dist/modules/companies/routes.d.ts.map +1 -1
  29. package/dist/modules/companies/routes.js +7 -0
  30. package/dist/modules/companies/routes.js.map +1 -1
  31. package/dist/modules/companies/schema.d.ts +20 -0
  32. package/dist/modules/companies/schema.d.ts.map +1 -1
  33. package/dist/modules/companies/schema.js +6 -1
  34. package/dist/modules/companies/schema.js.map +1 -1
  35. package/dist/modules/companies/service.d.ts +5 -0
  36. package/dist/modules/companies/service.d.ts.map +1 -1
  37. package/dist/modules/companies/service.js +24 -12
  38. package/dist/modules/companies/service.js.map +1 -1
  39. package/dist/modules/consent-purposes/capabilities.d.ts +7 -0
  40. package/dist/modules/consent-purposes/capabilities.d.ts.map +1 -0
  41. package/dist/modules/consent-purposes/capabilities.js +10 -0
  42. package/dist/modules/consent-purposes/capabilities.js.map +1 -0
  43. package/dist/modules/consent-purposes/events.d.ts +38 -0
  44. package/dist/modules/consent-purposes/events.d.ts.map +1 -0
  45. package/dist/modules/consent-purposes/events.js +17 -0
  46. package/dist/modules/consent-purposes/events.js.map +1 -0
  47. package/dist/modules/consent-purposes/index.d.ts +13 -0
  48. package/dist/modules/consent-purposes/index.d.ts.map +1 -0
  49. package/dist/modules/consent-purposes/index.js +41 -0
  50. package/dist/modules/consent-purposes/index.js.map +1 -0
  51. package/dist/modules/consent-purposes/repository.d.ts +21 -0
  52. package/dist/modules/consent-purposes/repository.d.ts.map +1 -0
  53. package/dist/modules/consent-purposes/repository.js +98 -0
  54. package/dist/modules/consent-purposes/repository.js.map +1 -0
  55. package/dist/modules/consent-purposes/routes.d.ts +39 -0
  56. package/dist/modules/consent-purposes/routes.d.ts.map +1 -0
  57. package/dist/modules/consent-purposes/routes.js +79 -0
  58. package/dist/modules/consent-purposes/routes.js.map +1 -0
  59. package/dist/modules/consent-purposes/schema.d.ts +175 -0
  60. package/dist/modules/consent-purposes/schema.d.ts.map +1 -0
  61. package/dist/modules/consent-purposes/schema.js +35 -0
  62. package/dist/modules/consent-purposes/schema.js.map +1 -0
  63. package/dist/modules/consent-purposes/service.d.ts +50 -0
  64. package/dist/modules/consent-purposes/service.d.ts.map +1 -0
  65. package/dist/modules/consent-purposes/service.js +263 -0
  66. package/dist/modules/consent-purposes/service.js.map +1 -0
  67. package/dist/modules/consent-purposes/starters.d.ts +17 -0
  68. package/dist/modules/consent-purposes/starters.d.ts.map +1 -0
  69. package/dist/modules/consent-purposes/starters.js +15 -0
  70. package/dist/modules/consent-purposes/starters.js.map +1 -0
  71. package/dist/modules/consent-purposes/tools.d.ts +4 -0
  72. package/dist/modules/consent-purposes/tools.d.ts.map +1 -0
  73. package/dist/modules/consent-purposes/tools.js +29 -0
  74. package/dist/modules/consent-purposes/tools.js.map +1 -0
  75. package/dist/modules/core.d.ts.map +1 -1
  76. package/dist/modules/core.js +10 -0
  77. package/dist/modules/core.js.map +1 -1
  78. package/dist/modules/custom-fields/capabilities.d.ts +12 -0
  79. package/dist/modules/custom-fields/capabilities.d.ts.map +1 -0
  80. package/dist/modules/custom-fields/capabilities.js +15 -0
  81. package/dist/modules/custom-fields/capabilities.js.map +1 -0
  82. package/dist/modules/custom-fields/events.d.ts +49 -0
  83. package/dist/modules/custom-fields/events.d.ts.map +1 -0
  84. package/dist/modules/custom-fields/events.js +25 -0
  85. package/dist/modules/custom-fields/events.js.map +1 -0
  86. package/dist/modules/custom-fields/index.d.ts +19 -0
  87. package/dist/modules/custom-fields/index.d.ts.map +1 -0
  88. package/dist/modules/custom-fields/index.js +46 -0
  89. package/dist/modules/custom-fields/index.js.map +1 -0
  90. package/dist/modules/custom-fields/repository.d.ts +37 -0
  91. package/dist/modules/custom-fields/repository.d.ts.map +1 -0
  92. package/dist/modules/custom-fields/repository.js +144 -0
  93. package/dist/modules/custom-fields/repository.js.map +1 -0
  94. package/dist/modules/custom-fields/routes.d.ts +44 -0
  95. package/dist/modules/custom-fields/routes.d.ts.map +1 -0
  96. package/dist/modules/custom-fields/routes.js +103 -0
  97. package/dist/modules/custom-fields/routes.js.map +1 -0
  98. package/dist/modules/custom-fields/schema.d.ts +215 -0
  99. package/dist/modules/custom-fields/schema.d.ts.map +1 -0
  100. package/dist/modules/custom-fields/schema.js +43 -0
  101. package/dist/modules/custom-fields/schema.js.map +1 -0
  102. package/dist/modules/custom-fields/service.d.ts +57 -0
  103. package/dist/modules/custom-fields/service.d.ts.map +1 -0
  104. package/dist/modules/custom-fields/service.js +273 -0
  105. package/dist/modules/custom-fields/service.js.map +1 -0
  106. package/dist/modules/custom-fields/tools.d.ts +4 -0
  107. package/dist/modules/custom-fields/tools.d.ts.map +1 -0
  108. package/dist/modules/custom-fields/tools.js +38 -0
  109. package/dist/modules/custom-fields/tools.js.map +1 -0
  110. package/dist/modules/custom-fields/values.d.ts +49 -0
  111. package/dist/modules/custom-fields/values.d.ts.map +1 -0
  112. package/dist/modules/custom-fields/values.js +249 -0
  113. package/dist/modules/custom-fields/values.js.map +1 -0
  114. package/dist/modules/custom-fields/wire.d.ts +12 -0
  115. package/dist/modules/custom-fields/wire.d.ts.map +1 -0
  116. package/dist/modules/custom-fields/wire.js +30 -0
  117. package/dist/modules/custom-fields/wire.js.map +1 -0
  118. package/dist/modules/dashboard/repository.d.ts.map +1 -1
  119. package/dist/modules/dashboard/repository.js +4 -3
  120. package/dist/modules/dashboard/repository.js.map +1 -1
  121. package/dist/modules/deals/index.d.ts +2 -1
  122. package/dist/modules/deals/index.d.ts.map +1 -1
  123. package/dist/modules/deals/index.js +5 -2
  124. package/dist/modules/deals/index.js.map +1 -1
  125. package/dist/modules/deals/repository.d.ts +0 -16
  126. package/dist/modules/deals/repository.d.ts.map +1 -1
  127. package/dist/modules/deals/repository.js +6 -76
  128. package/dist/modules/deals/repository.js.map +1 -1
  129. package/dist/modules/deals/routes.d.ts +14 -0
  130. package/dist/modules/deals/routes.d.ts.map +1 -1
  131. package/dist/modules/deals/routes.js +7 -0
  132. package/dist/modules/deals/routes.js.map +1 -1
  133. package/dist/modules/deals/schema.d.ts +20 -42
  134. package/dist/modules/deals/schema.d.ts.map +1 -1
  135. package/dist/modules/deals/schema.js +6 -11
  136. package/dist/modules/deals/schema.js.map +1 -1
  137. package/dist/modules/deals/service.d.ts +13 -2
  138. package/dist/modules/deals/service.d.ts.map +1 -1
  139. package/dist/modules/deals/service.js +43 -20
  140. package/dist/modules/deals/service.js.map +1 -1
  141. package/dist/modules/decisions/repository.d.ts.map +1 -1
  142. package/dist/modules/decisions/repository.js +2 -0
  143. package/dist/modules/decisions/repository.js.map +1 -1
  144. package/dist/modules/decisions/routes.d.ts +1 -0
  145. package/dist/modules/decisions/routes.d.ts.map +1 -1
  146. package/dist/modules/enquiries/events.d.ts +44 -0
  147. package/dist/modules/enquiries/events.d.ts.map +1 -0
  148. package/dist/modules/enquiries/events.js +19 -0
  149. package/dist/modules/enquiries/events.js.map +1 -0
  150. package/dist/modules/enquiries/index.d.ts +13 -0
  151. package/dist/modules/enquiries/index.d.ts.map +1 -0
  152. package/dist/modules/enquiries/index.js +44 -0
  153. package/dist/modules/enquiries/index.js.map +1 -0
  154. package/dist/modules/enquiries/repository.d.ts +30 -0
  155. package/dist/modules/enquiries/repository.d.ts.map +1 -0
  156. package/dist/modules/enquiries/repository.js +94 -0
  157. package/dist/modules/enquiries/repository.js.map +1 -0
  158. package/dist/modules/enquiries/routes.d.ts +52 -0
  159. package/dist/modules/enquiries/routes.d.ts.map +1 -0
  160. package/dist/modules/enquiries/routes.js +127 -0
  161. package/dist/modules/enquiries/routes.js.map +1 -0
  162. package/dist/modules/enquiries/schema.d.ts +290 -0
  163. package/dist/modules/enquiries/schema.d.ts.map +1 -0
  164. package/dist/modules/enquiries/schema.js +52 -0
  165. package/dist/modules/enquiries/schema.js.map +1 -0
  166. package/dist/modules/enquiries/service.d.ts +85 -0
  167. package/dist/modules/enquiries/service.d.ts.map +1 -0
  168. package/dist/modules/enquiries/service.js +370 -0
  169. package/dist/modules/enquiries/service.js.map +1 -0
  170. package/dist/modules/enquiries/tools.d.ts +4 -0
  171. package/dist/modules/enquiries/tools.d.ts.map +1 -0
  172. package/dist/modules/enquiries/tools.js +50 -0
  173. package/dist/modules/enquiries/tools.js.map +1 -0
  174. package/dist/modules/eventCatalogs.d.ts +3 -0
  175. package/dist/modules/eventCatalogs.d.ts.map +1 -1
  176. package/dist/modules/eventCatalogs.js +3 -0
  177. package/dist/modules/eventCatalogs.js.map +1 -1
  178. package/dist/modules/forms/embed.d.ts +20 -6
  179. package/dist/modules/forms/embed.d.ts.map +1 -1
  180. package/dist/modules/forms/embed.js +359 -43
  181. package/dist/modules/forms/embed.js.map +1 -1
  182. package/dist/modules/forms/events.d.ts +20 -7
  183. package/dist/modules/forms/events.d.ts.map +1 -1
  184. package/dist/modules/forms/events.js +20 -2
  185. package/dist/modules/forms/events.js.map +1 -1
  186. package/dist/modules/forms/fields.d.ts +14 -1
  187. package/dist/modules/forms/fields.d.ts.map +1 -1
  188. package/dist/modules/forms/fields.js +87 -3
  189. package/dist/modules/forms/fields.js.map +1 -1
  190. package/dist/modules/forms/index.d.ts.map +1 -1
  191. package/dist/modules/forms/index.js +12 -1
  192. package/dist/modules/forms/index.js.map +1 -1
  193. package/dist/modules/forms/mapping.d.ts +62 -5
  194. package/dist/modules/forms/mapping.d.ts.map +1 -1
  195. package/dist/modules/forms/mapping.js +139 -5
  196. package/dist/modules/forms/mapping.js.map +1 -1
  197. package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
  198. package/dist/modules/forms/publicRoutes.js +29 -1
  199. package/dist/modules/forms/publicRoutes.js.map +1 -1
  200. package/dist/modules/forms/repository.d.ts +31 -0
  201. package/dist/modules/forms/repository.d.ts.map +1 -1
  202. package/dist/modules/forms/repository.js +90 -1
  203. package/dist/modules/forms/repository.js.map +1 -1
  204. package/dist/modules/forms/routes.d.ts +83 -1
  205. package/dist/modules/forms/routes.d.ts.map +1 -1
  206. package/dist/modules/forms/routes.js +185 -2
  207. package/dist/modules/forms/routes.js.map +1 -1
  208. package/dist/modules/forms/schema.d.ts +672 -1
  209. package/dist/modules/forms/schema.d.ts.map +1 -1
  210. package/dist/modules/forms/schema.js +146 -3
  211. package/dist/modules/forms/schema.js.map +1 -1
  212. package/dist/modules/forms/service.d.ts +54 -1
  213. package/dist/modules/forms/service.d.ts.map +1 -1
  214. package/dist/modules/forms/service.js +338 -28
  215. package/dist/modules/forms/service.js.map +1 -1
  216. package/dist/modules/forms/submission.d.ts +15 -0
  217. package/dist/modules/forms/submission.d.ts.map +1 -1
  218. package/dist/modules/forms/submission.js +418 -40
  219. package/dist/modules/forms/submission.js.map +1 -1
  220. package/dist/modules/import-export/drafts.d.ts +10 -0
  221. package/dist/modules/import-export/drafts.d.ts.map +1 -1
  222. package/dist/modules/import-export/drafts.js +16 -2
  223. package/dist/modules/import-export/drafts.js.map +1 -1
  224. package/dist/modules/import-export/exportRows.d.ts +7 -4
  225. package/dist/modules/import-export/exportRows.d.ts.map +1 -1
  226. package/dist/modules/import-export/exportRows.js +20 -5
  227. package/dist/modules/import-export/exportRows.js.map +1 -1
  228. package/dist/modules/import-export/plan.d.ts +12 -1
  229. package/dist/modules/import-export/plan.d.ts.map +1 -1
  230. package/dist/modules/import-export/plan.js +29 -2
  231. package/dist/modules/import-export/plan.js.map +1 -1
  232. package/dist/modules/import-export/presets.d.ts.map +1 -1
  233. package/dist/modules/import-export/presets.js +10 -0
  234. package/dist/modules/import-export/presets.js.map +1 -1
  235. package/dist/modules/import-export/repository.d.ts +11 -1
  236. package/dist/modules/import-export/repository.d.ts.map +1 -1
  237. package/dist/modules/import-export/repository.js +42 -9
  238. package/dist/modules/import-export/repository.js.map +1 -1
  239. package/dist/modules/import-export/routes.d.ts.map +1 -1
  240. package/dist/modules/import-export/routes.js +4 -0
  241. package/dist/modules/import-export/routes.js.map +1 -1
  242. package/dist/modules/import-export/schema.d.ts +17 -0
  243. package/dist/modules/import-export/schema.d.ts.map +1 -1
  244. package/dist/modules/import-export/schema.js +11 -0
  245. package/dist/modules/import-export/schema.js.map +1 -1
  246. package/dist/modules/import-export/service.d.ts +6 -0
  247. package/dist/modules/import-export/service.d.ts.map +1 -1
  248. package/dist/modules/import-export/service.js +14 -2
  249. package/dist/modules/import-export/service.js.map +1 -1
  250. package/dist/modules/import-export/streams.d.ts.map +1 -1
  251. package/dist/modules/import-export/streams.js +3 -3
  252. package/dist/modules/import-export/streams.js.map +1 -1
  253. package/dist/modules/import-export/tools.d.ts.map +1 -1
  254. package/dist/modules/import-export/tools.js +8 -0
  255. package/dist/modules/import-export/tools.js.map +1 -1
  256. package/dist/modules/import-export/validation.d.ts.map +1 -1
  257. package/dist/modules/import-export/validation.js +22 -1
  258. package/dist/modules/import-export/validation.js.map +1 -1
  259. package/dist/modules/import-export/writes.d.ts.map +1 -1
  260. package/dist/modules/import-export/writes.js +37 -4
  261. package/dist/modules/import-export/writes.js.map +1 -1
  262. package/dist/modules/lists/repository.d.ts +11 -0
  263. package/dist/modules/lists/repository.d.ts.map +1 -1
  264. package/dist/modules/lists/repository.js +13 -0
  265. package/dist/modules/lists/repository.js.map +1 -1
  266. package/dist/modules/lists/routes.d.ts +4 -0
  267. package/dist/modules/lists/routes.d.ts.map +1 -1
  268. package/dist/modules/lists/routes.js +8 -0
  269. package/dist/modules/lists/routes.js.map +1 -1
  270. package/dist/modules/lists/schema.d.ts +17 -0
  271. package/dist/modules/lists/schema.d.ts.map +1 -1
  272. package/dist/modules/lists/schema.js +10 -0
  273. package/dist/modules/lists/schema.js.map +1 -1
  274. package/dist/modules/lists/service.d.ts +14 -2
  275. package/dist/modules/lists/service.d.ts.map +1 -1
  276. package/dist/modules/lists/service.js +55 -7
  277. package/dist/modules/lists/service.js.map +1 -1
  278. package/dist/modules/mcp/index.d.ts.map +1 -1
  279. package/dist/modules/mcp/index.js +5 -0
  280. package/dist/modules/mcp/index.js.map +1 -1
  281. package/dist/modules/notes/routes.d.ts +1 -0
  282. package/dist/modules/notes/routes.d.ts.map +1 -1
  283. package/dist/modules/opportunities/index.d.ts.map +1 -1
  284. package/dist/modules/opportunities/index.js +3 -1
  285. package/dist/modules/opportunities/index.js.map +1 -1
  286. package/dist/modules/opportunities/repository.d.ts +2 -0
  287. package/dist/modules/opportunities/repository.d.ts.map +1 -1
  288. package/dist/modules/opportunities/repository.js +4 -0
  289. package/dist/modules/opportunities/repository.js.map +1 -1
  290. package/dist/modules/opportunities/routes.d.ts +16 -0
  291. package/dist/modules/opportunities/routes.d.ts.map +1 -1
  292. package/dist/modules/opportunities/routes.js +13 -0
  293. package/dist/modules/opportunities/routes.js.map +1 -1
  294. package/dist/modules/opportunities/schema.d.ts +20 -0
  295. package/dist/modules/opportunities/schema.d.ts.map +1 -1
  296. package/dist/modules/opportunities/schema.js +6 -1
  297. package/dist/modules/opportunities/schema.js.map +1 -1
  298. package/dist/modules/opportunities/service.d.ts +20 -3
  299. package/dist/modules/opportunities/service.d.ts.map +1 -1
  300. package/dist/modules/opportunities/service.js +99 -18
  301. package/dist/modules/opportunities/service.js.map +1 -1
  302. package/dist/modules/opportunities/tools.d.ts.map +1 -1
  303. package/dist/modules/opportunities/tools.js +2 -0
  304. package/dist/modules/opportunities/tools.js.map +1 -1
  305. package/dist/modules/partnerships/index.d.ts.map +1 -1
  306. package/dist/modules/partnerships/index.js +3 -1
  307. package/dist/modules/partnerships/index.js.map +1 -1
  308. package/dist/modules/partnerships/repository.d.ts +0 -17
  309. package/dist/modules/partnerships/repository.d.ts.map +1 -1
  310. package/dist/modules/partnerships/repository.js +6 -82
  311. package/dist/modules/partnerships/repository.js.map +1 -1
  312. package/dist/modules/partnerships/routes.d.ts +14 -0
  313. package/dist/modules/partnerships/routes.d.ts.map +1 -1
  314. package/dist/modules/partnerships/routes.js +7 -0
  315. package/dist/modules/partnerships/routes.js.map +1 -1
  316. package/dist/modules/partnerships/schema.d.ts +20 -41
  317. package/dist/modules/partnerships/schema.d.ts.map +1 -1
  318. package/dist/modules/partnerships/schema.js +6 -10
  319. package/dist/modules/partnerships/schema.js.map +1 -1
  320. package/dist/modules/partnerships/service.d.ts +11 -1
  321. package/dist/modules/partnerships/service.d.ts.map +1 -1
  322. package/dist/modules/partnerships/service.js +43 -20
  323. package/dist/modules/partnerships/service.js.map +1 -1
  324. package/dist/modules/people/consentHydration.d.ts +26 -0
  325. package/dist/modules/people/consentHydration.d.ts.map +1 -0
  326. package/dist/modules/people/consentHydration.js +100 -0
  327. package/dist/modules/people/consentHydration.js.map +1 -0
  328. package/dist/modules/people/index.d.ts.map +1 -1
  329. package/dist/modules/people/index.js +3 -1
  330. package/dist/modules/people/index.js.map +1 -1
  331. package/dist/modules/people/personConsentWrites.d.ts +40 -0
  332. package/dist/modules/people/personConsentWrites.d.ts.map +1 -0
  333. package/dist/modules/people/personConsentWrites.js +98 -0
  334. package/dist/modules/people/personConsentWrites.js.map +1 -0
  335. package/dist/modules/people/repository.d.ts.map +1 -1
  336. package/dist/modules/people/repository.js +5 -1
  337. package/dist/modules/people/repository.js.map +1 -1
  338. package/dist/modules/people/routes.d.ts +57 -4
  339. package/dist/modules/people/routes.d.ts.map +1 -1
  340. package/dist/modules/people/routes.js +104 -5
  341. package/dist/modules/people/routes.js.map +1 -1
  342. package/dist/modules/people/schema.d.ts +366 -1
  343. package/dist/modules/people/schema.d.ts.map +1 -1
  344. package/dist/modules/people/schema.js +92 -2
  345. package/dist/modules/people/schema.js.map +1 -1
  346. package/dist/modules/people/service.d.ts +30 -1
  347. package/dist/modules/people/service.d.ts.map +1 -1
  348. package/dist/modules/people/service.js +115 -38
  349. package/dist/modules/people/service.js.map +1 -1
  350. package/dist/modules/people/tools.d.ts.map +1 -1
  351. package/dist/modules/people/tools.js +4 -1
  352. package/dist/modules/people/tools.js.map +1 -1
  353. package/dist/modules/personLinks.d.ts +79 -0
  354. package/dist/modules/personLinks.d.ts.map +1 -0
  355. package/dist/modules/personLinks.js +155 -0
  356. package/dist/modules/personLinks.js.map +1 -0
  357. package/dist/modules/pipelines/routes.d.ts +1 -0
  358. package/dist/modules/pipelines/routes.d.ts.map +1 -1
  359. package/dist/modules/plans/routes.d.ts +1 -0
  360. package/dist/modules/plans/routes.d.ts.map +1 -1
  361. package/dist/modules/raises/index.d.ts.map +1 -1
  362. package/dist/modules/raises/index.js +3 -1
  363. package/dist/modules/raises/index.js.map +1 -1
  364. package/dist/modules/raises/repository.d.ts +0 -17
  365. package/dist/modules/raises/repository.d.ts.map +1 -1
  366. package/dist/modules/raises/repository.js +6 -77
  367. package/dist/modules/raises/repository.js.map +1 -1
  368. package/dist/modules/raises/routes.d.ts +14 -0
  369. package/dist/modules/raises/routes.d.ts.map +1 -1
  370. package/dist/modules/raises/routes.js +7 -0
  371. package/dist/modules/raises/routes.js.map +1 -1
  372. package/dist/modules/raises/schema.d.ts +20 -41
  373. package/dist/modules/raises/schema.d.ts.map +1 -1
  374. package/dist/modules/raises/schema.js +6 -10
  375. package/dist/modules/raises/schema.js.map +1 -1
  376. package/dist/modules/raises/service.d.ts +11 -1
  377. package/dist/modules/raises/service.d.ts.map +1 -1
  378. package/dist/modules/raises/service.js +41 -18
  379. package/dist/modules/raises/service.js.map +1 -1
  380. package/dist/modules/recordTargets.d.ts.map +1 -1
  381. package/dist/modules/recordTargets.js +2 -0
  382. package/dist/modules/recordTargets.js.map +1 -1
  383. package/dist/modules/references.d.ts +10 -0
  384. package/dist/modules/references.d.ts.map +1 -1
  385. package/dist/modules/references.js +27 -4
  386. package/dist/modules/references.js.map +1 -1
  387. package/dist/modules/sample-data/fixture.d.ts +21 -0
  388. package/dist/modules/sample-data/fixture.d.ts.map +1 -1
  389. package/dist/modules/sample-data/fixture.js +40 -0
  390. package/dist/modules/sample-data/fixture.js.map +1 -1
  391. package/dist/modules/sample-data/index.d.ts.map +1 -1
  392. package/dist/modules/sample-data/index.js +1 -0
  393. package/dist/modules/sample-data/index.js.map +1 -1
  394. package/dist/modules/sample-data/routes.d.ts.map +1 -1
  395. package/dist/modules/sample-data/routes.js +1 -0
  396. package/dist/modules/sample-data/routes.js.map +1 -1
  397. package/dist/modules/sample-data/service.d.ts +1 -0
  398. package/dist/modules/sample-data/service.d.ts.map +1 -1
  399. package/dist/modules/sample-data/service.js +77 -8
  400. package/dist/modules/sample-data/service.js.map +1 -1
  401. package/dist/modules/search/index.d.ts +1 -1
  402. package/dist/modules/search/index.d.ts.map +1 -1
  403. package/dist/modules/search/index.js +2 -1
  404. package/dist/modules/search/index.js.map +1 -1
  405. package/dist/modules/search/repository.d.ts +1 -0
  406. package/dist/modules/search/repository.d.ts.map +1 -1
  407. package/dist/modules/search/repository.js +23 -0
  408. package/dist/modules/search/repository.js.map +1 -1
  409. package/dist/modules/search/service.d.ts +3 -3
  410. package/dist/modules/search/service.d.ts.map +1 -1
  411. package/dist/modules/search/service.js +5 -4
  412. package/dist/modules/search/service.js.map +1 -1
  413. package/dist/modules/stagedRecords.d.ts +3 -3
  414. package/dist/modules/stagedRecords.d.ts.map +1 -1
  415. package/dist/modules/stagedRecords.js +9 -0
  416. package/dist/modules/stagedRecords.js.map +1 -1
  417. package/dist/modules/webhooks/payloads.d.ts.map +1 -1
  418. package/dist/modules/webhooks/payloads.js +15 -2
  419. package/dist/modules/webhooks/payloads.js.map +1 -1
  420. package/dist/modules/workspace/repository.d.ts +2 -0
  421. package/dist/modules/workspace/repository.d.ts.map +1 -1
  422. package/dist/modules/workspace/repository.js +7 -0
  423. package/dist/modules/workspace/repository.js.map +1 -1
  424. package/dist/modules/workspace/service.d.ts.map +1 -1
  425. package/dist/modules/workspace/service.js +10 -0
  426. package/dist/modules/workspace/service.js.map +1 -1
  427. package/dist/modules/workspace/starters.d.ts.map +1 -1
  428. package/dist/modules/workspace/starters.js +5 -0
  429. package/dist/modules/workspace/starters.js.map +1 -1
  430. package/dist/runtime/events.d.ts +1 -1
  431. package/dist/runtime/events.d.ts.map +1 -1
  432. package/dist/runtime/events.js +1 -0
  433. package/dist/runtime/events.js.map +1 -1
  434. package/dist/schema/index.d.ts +3 -0
  435. package/dist/schema/index.d.ts.map +1 -1
  436. package/dist/schema/index.js +3 -0
  437. package/dist/schema/index.js.map +1 -1
  438. package/dist/testing/database.d.ts +5 -1
  439. package/dist/testing/database.d.ts.map +1 -1
  440. package/dist/testing/database.js +81 -10
  441. package/dist/testing/database.js.map +1 -1
  442. package/migrations/0024_third_king_cobra.sql +46 -0
  443. package/migrations/0025_worthless_chimera.sql +3 -0
  444. package/migrations/0026_late_aqueduct.sql +46 -0
  445. package/migrations/0027_brainy_silver_sable.sql +3 -0
  446. package/migrations/0028_freezing_scrambler.sql +19 -0
  447. package/migrations/0029_custom_fields.sql +26 -0
  448. package/migrations/0030_enquiries.sql +79 -0
  449. package/migrations/0031_consent.sql +45 -0
  450. package/migrations/0032_form_field_statement.sql +1 -0
  451. package/migrations/0033_form_field_consent_purpose_ids.sql +5 -0
  452. package/migrations/0034_drop_form_field_consent_purpose_id.sql +1 -0
  453. package/migrations/0035_form_field_consent_purpose_labels.sql +1 -0
  454. package/migrations/0036_form_field_notice_type.sql +2 -0
  455. package/migrations/meta/0024_snapshot.json +5516 -0
  456. package/migrations/meta/0025_snapshot.json +5336 -0
  457. package/migrations/meta/0026_snapshot.json +5710 -0
  458. package/migrations/meta/0027_snapshot.json +5716 -0
  459. package/migrations/meta/0028_snapshot.json +5740 -0
  460. package/migrations/meta/0029_snapshot.json +5935 -0
  461. package/migrations/meta/0030_snapshot.json +6245 -0
  462. package/migrations/meta/0031_snapshot.json +6572 -0
  463. package/migrations/meta/0032_snapshot.json +6578 -0
  464. package/migrations/meta/0033_snapshot.json +6572 -0
  465. package/migrations/meta/0034_snapshot.json +6566 -0
  466. package/migrations/meta/0035_snapshot.json +6573 -0
  467. package/migrations/meta/0036_snapshot.json +6573 -0
  468. package/migrations/meta/_journal.json +91 -0
  469. package/package.json +2 -2
  470. package/src/lib/ids.ts +11 -0
  471. package/src/modules/activities/repository.ts +22 -23
  472. package/src/modules/activities/wording.ts +18 -0
  473. package/src/modules/agent-tasks/catalog.ts +63 -0
  474. package/src/modules/agent-tasks/resolve.ts +64 -24
  475. package/src/modules/attachedRecords.ts +29 -2
  476. package/src/modules/companies/index.ts +3 -1
  477. package/src/modules/companies/routes.ts +7 -0
  478. package/src/modules/companies/schema.ts +7 -1
  479. package/src/modules/companies/service.ts +48 -13
  480. package/src/modules/consent-purposes/capabilities.ts +12 -0
  481. package/src/modules/consent-purposes/events.ts +38 -0
  482. package/src/modules/consent-purposes/index.ts +48 -0
  483. package/src/modules/consent-purposes/repository.ts +163 -0
  484. package/src/modules/consent-purposes/routes.ts +122 -0
  485. package/src/modules/consent-purposes/schema.ts +46 -0
  486. package/src/modules/consent-purposes/service.ts +423 -0
  487. package/src/modules/consent-purposes/starters.ts +32 -0
  488. package/src/modules/consent-purposes/tools.ts +44 -0
  489. package/src/modules/core.ts +10 -0
  490. package/src/modules/custom-fields/capabilities.ts +17 -0
  491. package/src/modules/custom-fields/events.ts +51 -0
  492. package/src/modules/custom-fields/index.ts +61 -0
  493. package/src/modules/custom-fields/repository.ts +225 -0
  494. package/src/modules/custom-fields/routes.ts +155 -0
  495. package/src/modules/custom-fields/schema.ts +61 -0
  496. package/src/modules/custom-fields/service.ts +439 -0
  497. package/src/modules/custom-fields/tools.ts +53 -0
  498. package/src/modules/custom-fields/values.ts +352 -0
  499. package/src/modules/custom-fields/wire.ts +32 -0
  500. package/src/modules/dashboard/repository.ts +4 -3
  501. package/src/modules/deals/index.ts +5 -2
  502. package/src/modules/deals/repository.ts +6 -106
  503. package/src/modules/deals/routes.ts +7 -0
  504. package/src/modules/deals/schema.ts +7 -15
  505. package/src/modules/deals/service.ts +92 -23
  506. package/src/modules/decisions/repository.ts +2 -0
  507. package/src/modules/enquiries/events.ts +45 -0
  508. package/src/modules/enquiries/index.ts +50 -0
  509. package/src/modules/enquiries/repository.ts +164 -0
  510. package/src/modules/enquiries/routes.ts +172 -0
  511. package/src/modules/enquiries/schema.ts +59 -0
  512. package/src/modules/enquiries/service.ts +644 -0
  513. package/src/modules/enquiries/tools.ts +66 -0
  514. package/src/modules/eventCatalogs.ts +3 -0
  515. package/src/modules/forms/embed.ts +391 -44
  516. package/src/modules/forms/events.ts +30 -2
  517. package/src/modules/forms/fields.ts +102 -2
  518. package/src/modules/forms/index.ts +12 -1
  519. package/src/modules/forms/mapping.ts +183 -6
  520. package/src/modules/forms/publicRoutes.ts +43 -1
  521. package/src/modules/forms/repository.ts +162 -1
  522. package/src/modules/forms/routes.ts +212 -2
  523. package/src/modules/forms/schema.ts +166 -4
  524. package/src/modules/forms/service.ts +565 -41
  525. package/src/modules/forms/submission.ts +718 -44
  526. package/src/modules/import-export/drafts.ts +20 -1
  527. package/src/modules/import-export/exportRows.ts +21 -5
  528. package/src/modules/import-export/plan.ts +47 -2
  529. package/src/modules/import-export/presets.ts +10 -0
  530. package/src/modules/import-export/repository.ts +73 -8
  531. package/src/modules/import-export/routes.ts +4 -0
  532. package/src/modules/import-export/schema.ts +11 -0
  533. package/src/modules/import-export/service.ts +28 -2
  534. package/src/modules/import-export/streams.ts +3 -1
  535. package/src/modules/import-export/tools.ts +10 -0
  536. package/src/modules/import-export/validation.ts +28 -0
  537. package/src/modules/import-export/writes.ts +70 -5
  538. package/src/modules/lists/repository.ts +30 -0
  539. package/src/modules/lists/routes.ts +8 -0
  540. package/src/modules/lists/schema.ts +10 -0
  541. package/src/modules/lists/service.ts +110 -9
  542. package/src/modules/mcp/index.ts +5 -0
  543. package/src/modules/opportunities/index.ts +3 -1
  544. package/src/modules/opportunities/repository.ts +11 -0
  545. package/src/modules/opportunities/routes.ts +13 -0
  546. package/src/modules/opportunities/schema.ts +7 -1
  547. package/src/modules/opportunities/service.ts +188 -22
  548. package/src/modules/opportunities/tools.ts +2 -0
  549. package/src/modules/partnerships/index.ts +3 -1
  550. package/src/modules/partnerships/repository.ts +6 -117
  551. package/src/modules/partnerships/routes.ts +7 -0
  552. package/src/modules/partnerships/schema.ts +7 -14
  553. package/src/modules/partnerships/service.ts +93 -22
  554. package/src/modules/people/consentHydration.ts +167 -0
  555. package/src/modules/people/index.ts +3 -1
  556. package/src/modules/people/personConsentWrites.ts +177 -0
  557. package/src/modules/people/repository.ts +5 -0
  558. package/src/modules/people/routes.ts +127 -18
  559. package/src/modules/people/schema.ts +109 -3
  560. package/src/modules/people/service.ts +186 -40
  561. package/src/modules/people/tools.ts +5 -1
  562. package/src/modules/personLinks.ts +278 -0
  563. package/src/modules/raises/index.ts +3 -1
  564. package/src/modules/raises/repository.ts +6 -107
  565. package/src/modules/raises/routes.ts +7 -0
  566. package/src/modules/raises/schema.ts +7 -14
  567. package/src/modules/raises/service.ts +91 -20
  568. package/src/modules/recordTargets.ts +2 -0
  569. package/src/modules/references.ts +43 -4
  570. package/src/modules/sample-data/fixture.ts +63 -0
  571. package/src/modules/sample-data/index.ts +1 -0
  572. package/src/modules/sample-data/routes.ts +1 -0
  573. package/src/modules/sample-data/service.ts +97 -8
  574. package/src/modules/search/index.ts +2 -1
  575. package/src/modules/search/repository.ts +33 -1
  576. package/src/modules/search/service.ts +7 -5
  577. package/src/modules/stagedRecords.ts +18 -3
  578. package/src/modules/webhooks/payloads.ts +20 -2
  579. package/src/modules/workspace/repository.ts +12 -0
  580. package/src/modules/workspace/service.ts +14 -0
  581. package/src/modules/workspace/starters.ts +5 -0
  582. package/src/runtime/events.ts +1 -0
  583. package/src/schema/index.ts +3 -0
  584. package/src/testing/database.ts +97 -11
@@ -1,3 +1,5 @@
1
+ import type { CustomFieldWireValue } from '@kelpie/schemas'
2
+
1
3
  import { changedKeys } from '../../lib/changes.ts'
2
4
  import { UNIQUE_VIOLATION, isReferenceViolation, postgresErrorCode } from '../../lib/database.ts'
3
5
  import type { Database } from '../../lib/database.ts'
@@ -16,6 +18,7 @@ import type { Actor } from '../auth/actor.ts'
16
18
  import { requireWorkspaceId } from '../auth/actor.ts'
17
19
  import './events.ts'
18
20
  import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
21
+ import type { CustomFieldValuesValidator } from '../custom-fields/values.ts'
19
22
  import { referencedElsewhere } from '../references.ts'
20
23
  import * as repository from './repository.ts'
21
24
  import { COMPANY_SORTS, DEFAULT_COMPANY_SORT } from './repository.ts'
@@ -35,6 +38,7 @@ export interface CompaniesDependencies {
35
38
  readonly createId: IdFactory
36
39
  readonly now: () => Date
37
40
  readonly recordActivity: ActivityRecorder
41
+ readonly customFields: CustomFieldValuesValidator
38
42
  }
39
43
 
40
44
  /** What a changed column is called on a timeline. `icpFit` is why these are written out. */
@@ -73,6 +77,8 @@ export interface CreateCompanyInput {
73
77
  readonly summary: string
74
78
  readonly tags: readonly string[]
75
79
  readonly isOwn: boolean
80
+ /** Wire shape merge patch (undefined for a create without any). */
81
+ readonly customFields: Readonly<Record<string, CustomFieldWireValue | null>> | undefined
76
82
  }
77
83
 
78
84
  /** PATCH semantics: an absent field is left alone, and null clears a nullable one. */
@@ -156,6 +162,12 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
156
162
  const id = dependencies.createId('company')
157
163
 
158
164
  return dependencies.transaction(async ({ tx, events }) => {
165
+ const customFields = await dependencies.customFields.forCreate(
166
+ tx,
167
+ workspaceId,
168
+ 'company',
169
+ input.customFields,
170
+ )
159
171
  let created: CompanyRecord
160
172
 
161
173
  try {
@@ -176,6 +188,7 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
176
188
  summary: input.summary,
177
189
  tags: [...input.tags],
178
190
  isOwn: input.isOwn,
191
+ customFields,
179
192
  })
180
193
  } catch (error: unknown) {
181
194
  if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
@@ -211,18 +224,28 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
211
224
  const workspaceId = requireWorkspaceId(actor)
212
225
  const existing = await require(workspaceId, id)
213
226
  const columns = toStoredColumns(changes)
214
- const changed = changedKeys(existing, columns)
215
-
216
- if (changed.length === 0) {
217
- return toView(existing)
218
- }
227
+ const scalarChanged = changedKeys(existing, columns)
219
228
 
220
229
  return dependencies.transaction(async ({ tx, events }) => {
230
+ const cf = await dependencies.customFields.forUpdate(
231
+ tx,
232
+ workspaceId,
233
+ 'company',
234
+ existing.customFields,
235
+ changes.customFields,
236
+ )
237
+ const customFieldsChanged = cf !== undefined && cf.changedPaths.length > 0
238
+
239
+ if (scalarChanged.length === 0 && !customFieldsChanged) {
240
+ return toView(existing)
241
+ }
242
+
221
243
  let updated: CompanyRecord | undefined
222
244
 
223
245
  try {
224
246
  updated = await repository.updateCompany(tx, workspaceId, id, {
225
247
  ...columns,
248
+ ...(customFieldsChanged ? { customFields: cf.merged } : {}),
226
249
  updatedAt: dependencies.now(),
227
250
  })
228
251
  } catch (error: unknown) {
@@ -237,19 +260,31 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
237
260
  throw AppError.notFound('Company not found')
238
261
  }
239
262
 
240
- await dependencies.recordActivity(tx, workspaceId, actor, {
241
- targetType: 'company',
242
- targetId: id,
243
- kind: 'updated',
244
- ...describeUpdate(changed, COMPANY_FIELD_LABELS, existing, columns),
245
- })
263
+ const customFieldPaths = cf?.changedPaths ?? []
264
+ const activityChanged = [...scalarChanged, ...customFieldPaths]
265
+
266
+ if (activityChanged.length > 0) {
267
+ const labels: Record<string, string> = { ...COMPANY_FIELD_LABELS, ...cf?.labels }
268
+ const before: Record<string, unknown> = { ...existing, ...cf?.flatBefore }
269
+ const after: Record<string, unknown> = { ...columns, ...cf?.flatAfter }
270
+ await dependencies.recordActivity(tx, workspaceId, actor, {
271
+ targetType: 'company',
272
+ targetId: id,
273
+ kind: 'updated',
274
+ ...describeUpdate(activityChanged, labels, before, after),
275
+ })
276
+ }
246
277
 
247
- events.emit('companies.company.updated', { type: 'company', id }, { changed })
278
+ events.emit(
279
+ 'companies.company.updated',
280
+ { type: 'company', id },
281
+ { changed: [...scalarChanged, ...customFieldPaths] },
282
+ )
248
283
 
249
284
  // Sync sweep when the domain moved. A newly-set domain gains matches;
250
285
  // a changed domain gains new matches without touching the old links
251
286
  // (never-remove — a person may still work at the previous domain).
252
- if (changed.includes('domain')) {
287
+ if (scalarChanged.includes('domain')) {
253
288
  await autoLinkCompanyByDomain(tx, events, workspaceId, updated, {
254
289
  createId: dependencies.createId,
255
290
  now: dependencies.now,
@@ -0,0 +1,12 @@
1
+ import type { LimitCapability } from '../../runtime/entitlements.ts'
2
+
3
+ /**
4
+ * How many consent purposes one workspace may define. Open source answers
5
+ * unlimited; the cloud can gate it later without a core change.
6
+ */
7
+ export const CONSENT_PURPOSES_LIMIT: LimitCapability = {
8
+ name: 'consent_purposes.limit',
9
+ kind: 'limit',
10
+ description:
11
+ 'How many consent purposes one workspace may define. Unlimited in open source.',
12
+ }
@@ -0,0 +1,38 @@
1
+ import { z } from 'zod'
2
+
3
+ import type { ModuleEventCatalog } from '../../runtime/module.ts'
4
+
5
+ /**
6
+ * Domain events for the consent-purposes catalog.
7
+ *
8
+ * `target` is the purpose definition. Per-person consent writes ride each
9
+ * person's own `.updated` event, with per-purpose entries in `changed` shaped
10
+ * as `consents.<slug>`.
11
+ */
12
+ export const consentPurposesEvents = {
13
+ 'consent_purposes.purpose.created': z.object({ slug: z.string() }),
14
+ 'consent_purposes.purpose.updated': z.object({
15
+ slug: z.string(),
16
+ changed: z.array(z.string()).readonly(),
17
+ }),
18
+ 'consent_purposes.purpose.deleted': z.object({ slug: z.string() }),
19
+ } satisfies ModuleEventCatalog
20
+
21
+ export interface ConsentPurposeCreatedData {
22
+ readonly slug: string
23
+ }
24
+ export interface ConsentPurposeUpdatedData {
25
+ readonly slug: string
26
+ readonly changed: readonly string[]
27
+ }
28
+ export interface ConsentPurposeDeletedData {
29
+ readonly slug: string
30
+ }
31
+
32
+ declare module '../../runtime/events.ts' {
33
+ interface KelpieEventMap {
34
+ 'consent_purposes.purpose.created': ConsentPurposeCreatedData
35
+ 'consent_purposes.purpose.updated': ConsentPurposeUpdatedData
36
+ 'consent_purposes.purpose.deleted': ConsentPurposeDeletedData
37
+ }
38
+ }
@@ -0,0 +1,48 @@
1
+ import type { KelpieModule } from '../../runtime/module.ts'
2
+ import { CONSENT_PURPOSES_LIMIT } from './capabilities.ts'
3
+ import { consentPurposesEvents } from './events.ts'
4
+ import { mountConsentPurposesRoutes } from './routes.ts'
5
+ import * as schema from './schema.ts'
6
+ import { createConsentPurposesService } from './service.ts'
7
+ import { registerConsentPurposesTools } from './tools.ts'
8
+
9
+ /**
10
+ * Consent purposes: the workspace catalog every capture site names.
11
+ *
12
+ * Structural because Person consent rows carry `purpose_id`, and forms /
13
+ * lists / imports each reference one; a disabled module would leave those
14
+ * references without a definition to resolve.
15
+ *
16
+ * Registers before people, forms, lists, and import-export so their `_fk`
17
+ * targets are in the schema barrel when their own migrations reference them.
18
+ */
19
+ export function createConsentPurposesModule(migrationsDirectory: string): KelpieModule {
20
+ return {
21
+ id: 'consent-purposes',
22
+ requires: ['workspace'],
23
+ structural: true,
24
+ events: consentPurposesEvents,
25
+
26
+ register(context) {
27
+ context.entitlements.declare(CONSENT_PURPOSES_LIMIT)
28
+
29
+ const service = createConsentPurposesService({
30
+ db: context.db,
31
+ transaction: context.transaction,
32
+ createId: context.createId,
33
+ now: context.now,
34
+ entitlements: context.entitlements,
35
+ })
36
+
37
+ context.schema(schema, migrationsDirectory)
38
+
39
+ context.routes((router) => {
40
+ mountConsentPurposesRoutes(router, { db: context.db, now: context.now, service })
41
+ })
42
+
43
+ registerConsentPurposesTools(context.mcp, service)
44
+
45
+ return Promise.resolve()
46
+ },
47
+ }
48
+ }
@@ -0,0 +1,163 @@
1
+ import { and, asc, eq, ilike, inArray, sql } from 'drizzle-orm'
2
+ import type { SQL } from 'drizzle-orm'
3
+
4
+ import { keysetCondition, orderByWindow, textSort, timestampSort } from '../../lib/pagination.ts'
5
+ import type { ListWindow, SortableFields } from '../../lib/pagination.ts'
6
+ import { containsPattern } from '../../lib/search.ts'
7
+ import type { Queryable } from '../../runtime/transaction.ts'
8
+ import { consentPurposes } from './schema.ts'
9
+
10
+ export type ConsentPurposeRecord = typeof consentPurposes.$inferSelect
11
+ export type ConsentPurposeColumns = typeof consentPurposes.$inferInsert
12
+
13
+ export const CONSENT_PURPOSE_SORTS: SortableFields<ConsentPurposeRecord> = {
14
+ sort_order: {
15
+ column: consentPurposes.sortOrder,
16
+ valueOf: (row) => String(row.sortOrder),
17
+ parse: (value) => {
18
+ const parsed = Number(value)
19
+ if (!Number.isInteger(parsed)) {
20
+ throw new Error('sort_order cursor is not a whole number')
21
+ }
22
+ return parsed
23
+ },
24
+ },
25
+ label: textSort(consentPurposes.label, (row) => row.label),
26
+ slug: textSort(consentPurposes.slug, (row) => row.slug),
27
+ created_at: timestampSort(consentPurposes.createdAt, (row) => row.createdAt),
28
+ updated_at: timestampSort(consentPurposes.updatedAt, (row) => row.updatedAt),
29
+ }
30
+
31
+ export const DEFAULT_CONSENT_PURPOSE_SORT = 'sort_order'
32
+
33
+ export interface ConsentPurposeFilters {
34
+ readonly term?: string | undefined
35
+ }
36
+
37
+ function conditionsFor(workspaceId: string, filters: ConsentPurposeFilters): (SQL | undefined)[] {
38
+ return [
39
+ eq(consentPurposes.workspaceId, workspaceId),
40
+ filters.term === undefined ? undefined : ilike(consentPurposes.label, containsPattern(filters.term)),
41
+ ]
42
+ }
43
+
44
+ export function listPurposes(
45
+ db: Queryable,
46
+ workspaceId: string,
47
+ filters: ConsentPurposeFilters,
48
+ window: ListWindow<ConsentPurposeRecord>,
49
+ ): Promise<ConsentPurposeRecord[]> {
50
+ return db
51
+ .select()
52
+ .from(consentPurposes)
53
+ .where(and(...conditionsFor(workspaceId, filters), keysetCondition(window, consentPurposes.id)))
54
+ .orderBy(...orderByWindow(window, consentPurposes.id))
55
+ .limit(window.fetchLimit)
56
+ }
57
+
58
+ export async function findPurpose(
59
+ db: Queryable,
60
+ workspaceId: string,
61
+ id: string,
62
+ ): Promise<ConsentPurposeRecord | undefined> {
63
+ const [found] = await db
64
+ .select()
65
+ .from(consentPurposes)
66
+ .where(and(eq(consentPurposes.workspaceId, workspaceId), eq(consentPurposes.id, id)))
67
+ .limit(1)
68
+
69
+ return found
70
+ }
71
+
72
+ export async function findPurposeBySlug(
73
+ db: Queryable,
74
+ workspaceId: string,
75
+ slug: string,
76
+ ): Promise<ConsentPurposeRecord | undefined> {
77
+ const [found] = await db
78
+ .select()
79
+ .from(consentPurposes)
80
+ .where(and(eq(consentPurposes.workspaceId, workspaceId), eq(consentPurposes.slug, slug)))
81
+ .limit(1)
82
+
83
+ return found
84
+ }
85
+
86
+ export function purposesForWorkspace(
87
+ db: Queryable,
88
+ workspaceId: string,
89
+ ): Promise<ConsentPurposeRecord[]> {
90
+ return db
91
+ .select()
92
+ .from(consentPurposes)
93
+ .where(eq(consentPurposes.workspaceId, workspaceId))
94
+ .orderBy(asc(consentPurposes.sortOrder), asc(consentPurposes.id))
95
+ }
96
+
97
+ /** The purposes with any of these ids, in this workspace. Used by cross-module checks. */
98
+ export function listPurposesByIds(
99
+ db: Queryable,
100
+ workspaceId: string,
101
+ ids: readonly string[],
102
+ ): Promise<ConsentPurposeRecord[]> {
103
+ if (ids.length === 0) return Promise.resolve([])
104
+ return db
105
+ .select()
106
+ .from(consentPurposes)
107
+ .where(
108
+ and(
109
+ eq(consentPurposes.workspaceId, workspaceId),
110
+ inArray(consentPurposes.id, [...ids]),
111
+ ),
112
+ )
113
+ }
114
+
115
+ export async function countPurposes(db: Queryable, workspaceId: string): Promise<number> {
116
+ const [row] = await db
117
+ .select({ count: sql<number>`count(*)::int` })
118
+ .from(consentPurposes)
119
+ .where(eq(consentPurposes.workspaceId, workspaceId))
120
+
121
+ return Number(row?.count ?? 0)
122
+ }
123
+
124
+ export async function insertPurpose(
125
+ db: Queryable,
126
+ values: ConsentPurposeColumns,
127
+ ): Promise<ConsentPurposeRecord> {
128
+ const [created] = await db.insert(consentPurposes).values(values).returning()
129
+
130
+ if (created === undefined) {
131
+ throw new Error(`Inserting consent_purpose ${values.id} returned no row`)
132
+ }
133
+
134
+ return created
135
+ }
136
+
137
+ export async function updatePurpose(
138
+ db: Queryable,
139
+ workspaceId: string,
140
+ id: string,
141
+ changes: Partial<ConsentPurposeColumns>,
142
+ ): Promise<ConsentPurposeRecord | undefined> {
143
+ const [updated] = await db
144
+ .update(consentPurposes)
145
+ .set(changes)
146
+ .where(and(eq(consentPurposes.workspaceId, workspaceId), eq(consentPurposes.id, id)))
147
+ .returning()
148
+
149
+ return updated
150
+ }
151
+
152
+ export async function deletePurpose(
153
+ db: Queryable,
154
+ workspaceId: string,
155
+ id: string,
156
+ ): Promise<number> {
157
+ const deleted = await db
158
+ .delete(consentPurposes)
159
+ .where(and(eq(consentPurposes.workspaceId, workspaceId), eq(consentPurposes.id, id)))
160
+ .returning({ id: consentPurposes.id })
161
+
162
+ return deleted.length
163
+ }
@@ -0,0 +1,122 @@
1
+ import { CONSENT_PURPOSE_STATUSES } from '@kelpie/schemas'
2
+ import type { Context, Hono } from 'hono'
3
+ import { z } from 'zod'
4
+
5
+ import { pageBody, readJsonBody, readListParameters } from '../../lib/http.ts'
6
+ import type { Actor } from '../auth/actor.ts'
7
+ import { resolveActorFrom } from '../auth/credentials.ts'
8
+ import type { CredentialDependencies } from '../auth/credentials.ts'
9
+ import type {
10
+ ConsentPurposeView,
11
+ ConsentPurposesService,
12
+ CreateConsentPurposeInput,
13
+ UpdateConsentPurposeInput,
14
+ } from './service.ts'
15
+
16
+ /**
17
+ * Wire shapes for `/v1/consent_purposes`.
18
+ *
19
+ * `slug` is only on the create body: the update body omits it and the strict
20
+ * PATCH answers `422` if it is sent. The description defaults to empty so a
21
+ * write that only sets label + slug is accepted.
22
+ */
23
+
24
+ export const createBody = z.strictObject({
25
+ slug: z.string().min(1).max(64),
26
+ label: z.string().min(1).max(120),
27
+ description: z.string().max(2000).default(''),
28
+ default_status: z.enum(CONSENT_PURPOSE_STATUSES).default('unknown'),
29
+ })
30
+
31
+ export const updateBody = z
32
+ .strictObject({
33
+ label: z.string().min(1).max(120),
34
+ description: z.string().max(2000),
35
+ default_status: z.enum(CONSENT_PURPOSE_STATUSES),
36
+ sort_order: z.number().int().min(0),
37
+ })
38
+ .partial()
39
+
40
+ export interface ConsentPurposesRoutesDependencies extends CredentialDependencies {
41
+ readonly service: ConsentPurposesService
42
+ }
43
+
44
+ export function toCreateInput(body: z.infer<typeof createBody>): CreateConsentPurposeInput {
45
+ return {
46
+ slug: body.slug,
47
+ label: body.label,
48
+ description: body.description,
49
+ defaultStatus: body.default_status,
50
+ }
51
+ }
52
+
53
+ export function toUpdateInput(body: z.infer<typeof updateBody>): UpdateConsentPurposeInput {
54
+ return {
55
+ ...(body.label === undefined ? {} : { label: body.label }),
56
+ ...(body.description === undefined ? {} : { description: body.description }),
57
+ ...(body.default_status === undefined ? {} : { defaultStatus: body.default_status }),
58
+ ...(body.sort_order === undefined ? {} : { sortOrder: body.sort_order }),
59
+ }
60
+ }
61
+
62
+ export function consentPurposeResponse(purpose: ConsentPurposeView): Record<string, unknown> {
63
+ return {
64
+ id: purpose.id,
65
+ slug: purpose.slug,
66
+ label: purpose.label,
67
+ description: purpose.description,
68
+ default_status: purpose.defaultStatus,
69
+ sort_order: purpose.sortOrder,
70
+ created_at: purpose.createdAt.toISOString(),
71
+ updated_at: purpose.updatedAt.toISOString(),
72
+ }
73
+ }
74
+
75
+ export function mountConsentPurposesRoutes(
76
+ router: Hono,
77
+ dependencies: ConsentPurposesRoutesDependencies,
78
+ ): void {
79
+ const requireActor = (context: Context): Promise<Actor> =>
80
+ resolveActorFrom(dependencies, context)
81
+
82
+ router.get('/consent_purposes', async (context) => {
83
+ const page = await dependencies.service.list(
84
+ await requireActor(context),
85
+ { term: context.req.query('q') },
86
+ readListParameters(context),
87
+ )
88
+ return context.json(pageBody(page, consentPurposeResponse))
89
+ })
90
+
91
+ router.post('/consent_purposes', async (context) => {
92
+ const body = await readJsonBody(context, createBody)
93
+ const purpose = await dependencies.service.create(
94
+ await requireActor(context),
95
+ toCreateInput(body),
96
+ )
97
+ return context.json(consentPurposeResponse(purpose), 201)
98
+ })
99
+
100
+ router.get('/consent_purposes/:id', async (context) => {
101
+ const purpose = await dependencies.service.get(
102
+ await requireActor(context),
103
+ context.req.param('id'),
104
+ )
105
+ return context.json(consentPurposeResponse(purpose))
106
+ })
107
+
108
+ router.patch('/consent_purposes/:id', async (context) => {
109
+ const body = await readJsonBody(context, updateBody)
110
+ const purpose = await dependencies.service.update(
111
+ await requireActor(context),
112
+ context.req.param('id'),
113
+ toUpdateInput(body),
114
+ )
115
+ return context.json(consentPurposeResponse(purpose))
116
+ })
117
+
118
+ router.delete('/consent_purposes/:id', async (context) => {
119
+ await dependencies.service.remove(await requireActor(context), context.req.param('id'))
120
+ return context.body(null, 204)
121
+ })
122
+ }
@@ -0,0 +1,46 @@
1
+ import { CONSENT_PURPOSE_STATUSES } from '@kelpie/schemas'
2
+ import { index, integer, pgTable, text, unique } from 'drizzle-orm/pg-core'
3
+
4
+ import { checkOneOf, createdAt, primaryId, updatedAt } from '../../lib/columns.ts'
5
+ import { workspaces } from '../workspace/schema.ts'
6
+
7
+ /**
8
+ * Workspace-defined consent purposes.
9
+ *
10
+ * Every capture site — a form's consent field, a list, an import job, the
11
+ * manual override on a Person — names one of these. `slug` is set at create
12
+ * and immutable after: a rename would strand every form/list/import that
13
+ * names it and every `person_consents` row that carries it (identified by
14
+ * the purpose id). The strict PATCH body naturally refuses either as a `422`.
15
+ *
16
+ * `default_status` is the workspace default: a person without an explicit
17
+ * `person_consents` row for this purpose inherits it.
18
+ */
19
+ export { CONSENT_PURPOSE_STATUSES } from '@kelpie/schemas'
20
+ export type { ConsentPurposeStatus } from '@kelpie/schemas'
21
+
22
+ export const consentPurposes = pgTable(
23
+ 'consent_purposes',
24
+ {
25
+ id: primaryId(),
26
+ workspaceId: text('workspace_id')
27
+ .notNull()
28
+ .references(() => workspaces.id, { onDelete: 'cascade' }),
29
+ slug: text('slug').notNull(),
30
+ label: text('label').notNull(),
31
+ description: text('description').notNull().default(''),
32
+ defaultStatus: text('default_status').notNull().default('unknown'),
33
+ sortOrder: integer('sort_order').notNull(),
34
+ createdAt: createdAt(),
35
+ updatedAt: updatedAt(),
36
+ },
37
+ (table) => [
38
+ index('consent_purposes_workspace_idx').on(table.workspaceId),
39
+ unique('consent_purposes_workspace_slug_key').on(table.workspaceId, table.slug),
40
+ checkOneOf(
41
+ 'consent_purposes_default_status_check',
42
+ table.defaultStatus,
43
+ CONSENT_PURPOSE_STATUSES,
44
+ ),
45
+ ],
46
+ )