@kelpie/server 0.10.0 → 0.12.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 (485) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +2 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/actor.d.ts +3 -1
  9. package/dist/lib/actor.d.ts.map +1 -1
  10. package/dist/lib/actor.js.map +1 -1
  11. package/dist/lib/apiKeyScopes.d.ts +8 -0
  12. package/dist/lib/apiKeyScopes.d.ts.map +1 -0
  13. package/dist/lib/apiKeyScopes.js +166 -0
  14. package/dist/lib/apiKeyScopes.js.map +1 -0
  15. package/dist/lib/errors.d.ts +18 -0
  16. package/dist/lib/errors.d.ts.map +1 -1
  17. package/dist/lib/errors.js +17 -0
  18. package/dist/lib/errors.js.map +1 -1
  19. package/dist/modules/activities/repository.d.ts +2 -0
  20. package/dist/modules/activities/repository.d.ts.map +1 -1
  21. package/dist/modules/activities/repository.js +9 -0
  22. package/dist/modules/activities/repository.js.map +1 -1
  23. package/dist/modules/agent-tasks/repository.d.ts +2 -0
  24. package/dist/modules/agent-tasks/repository.d.ts.map +1 -1
  25. package/dist/modules/agent-tasks/repository.js +9 -0
  26. package/dist/modules/agent-tasks/repository.js.map +1 -1
  27. package/dist/modules/api-keys/routes.d.ts.map +1 -1
  28. package/dist/modules/api-keys/routes.js +4 -1
  29. package/dist/modules/api-keys/routes.js.map +1 -1
  30. package/dist/modules/api-keys/schema.d.ts +43 -0
  31. package/dist/modules/api-keys/schema.d.ts.map +1 -1
  32. package/dist/modules/api-keys/schema.js +2 -0
  33. package/dist/modules/api-keys/schema.js.map +1 -1
  34. package/dist/modules/api-keys/scopeMiddleware.d.ts +8 -0
  35. package/dist/modules/api-keys/scopeMiddleware.d.ts.map +1 -0
  36. package/dist/modules/api-keys/scopeMiddleware.js +21 -0
  37. package/dist/modules/api-keys/scopeMiddleware.js.map +1 -0
  38. package/dist/modules/api-keys/service.d.ts +3 -1
  39. package/dist/modules/api-keys/service.d.ts.map +1 -1
  40. package/dist/modules/api-keys/service.js +26 -1
  41. package/dist/modules/api-keys/service.js.map +1 -1
  42. package/dist/modules/auth/credentials.d.ts.map +1 -1
  43. package/dist/modules/auth/credentials.js +2 -0
  44. package/dist/modules/auth/credentials.js.map +1 -1
  45. package/dist/modules/auth/index.d.ts.map +1 -1
  46. package/dist/modules/auth/index.js +21 -4
  47. package/dist/modules/auth/index.js.map +1 -1
  48. package/dist/modules/auth/repository.d.ts +2 -1
  49. package/dist/modules/auth/repository.d.ts.map +1 -1
  50. package/dist/modules/auth/repository.js +1 -0
  51. package/dist/modules/auth/repository.js.map +1 -1
  52. package/dist/modules/auth/routes.d.ts.map +1 -1
  53. package/dist/modules/auth/routes.js +2 -6
  54. package/dist/modules/auth/routes.js.map +1 -1
  55. package/dist/modules/auth/schema.d.ts +18 -1
  56. package/dist/modules/auth/schema.d.ts.map +1 -1
  57. package/dist/modules/auth/schema.js +12 -1
  58. package/dist/modules/auth/schema.js.map +1 -1
  59. package/dist/modules/auth/service.d.ts +18 -0
  60. package/dist/modules/auth/service.d.ts.map +1 -1
  61. package/dist/modules/auth/service.js +95 -6
  62. package/dist/modules/auth/service.js.map +1 -1
  63. package/dist/modules/auth/session.d.ts +12 -0
  64. package/dist/modules/auth/session.d.ts.map +1 -1
  65. package/dist/modules/auth/session.js +12 -0
  66. package/dist/modules/auth/session.js.map +1 -1
  67. package/dist/modules/consent-purposes/index.d.ts +1 -1
  68. package/dist/modules/consent-purposes/index.js +1 -1
  69. package/dist/modules/consent-purposes/schema.d.ts +3 -3
  70. package/dist/modules/consent-purposes/schema.js +3 -3
  71. package/dist/modules/consent-purposes/service.d.ts +1 -1
  72. package/dist/modules/consent-purposes/service.d.ts.map +1 -1
  73. package/dist/modules/consent-purposes/service.js +7 -16
  74. package/dist/modules/consent-purposes/service.js.map +1 -1
  75. package/dist/modules/consent-purposes/starters.d.ts +1 -1
  76. package/dist/modules/consent-purposes/tools.js +1 -1
  77. package/dist/modules/consent-purposes/tools.js.map +1 -1
  78. package/dist/modules/conversions/clearPointers.d.ts +10 -0
  79. package/dist/modules/conversions/clearPointers.d.ts.map +1 -0
  80. package/dist/modules/conversions/clearPointers.js +40 -0
  81. package/dist/modules/conversions/clearPointers.js.map +1 -0
  82. package/dist/modules/conversions/factory.d.ts +5 -0
  83. package/dist/modules/conversions/factory.d.ts.map +1 -0
  84. package/dist/modules/conversions/factory.js +18 -0
  85. package/dist/modules/conversions/factory.js.map +1 -0
  86. package/dist/modules/conversions/fieldMap.d.ts +55 -0
  87. package/dist/modules/conversions/fieldMap.d.ts.map +1 -0
  88. package/dist/modules/conversions/fieldMap.js +398 -0
  89. package/dist/modules/conversions/fieldMap.js.map +1 -0
  90. package/dist/modules/conversions/index.d.ts +7 -0
  91. package/dist/modules/conversions/index.d.ts.map +1 -0
  92. package/dist/modules/conversions/index.js +6 -0
  93. package/dist/modules/conversions/index.js.map +1 -0
  94. package/dist/modules/conversions/mcp.d.ts +7 -0
  95. package/dist/modules/conversions/mcp.d.ts.map +1 -0
  96. package/dist/modules/conversions/mcp.js +47 -0
  97. package/dist/modules/conversions/mcp.js.map +1 -0
  98. package/dist/modules/conversions/repoint.d.ts +19 -0
  99. package/dist/modules/conversions/repoint.d.ts.map +1 -0
  100. package/dist/modules/conversions/repoint.js +51 -0
  101. package/dist/modules/conversions/repoint.js.map +1 -0
  102. package/dist/modules/conversions/routes.d.ts +26 -0
  103. package/dist/modules/conversions/routes.d.ts.map +1 -0
  104. package/dist/modules/conversions/routes.js +23 -0
  105. package/dist/modules/conversions/routes.js.map +1 -0
  106. package/dist/modules/conversions/service.d.ts +28 -0
  107. package/dist/modules/conversions/service.d.ts.map +1 -0
  108. package/dist/modules/conversions/service.js +170 -0
  109. package/dist/modules/conversions/service.js.map +1 -0
  110. package/dist/modules/conversions/wire.d.ts +4 -0
  111. package/dist/modules/conversions/wire.d.ts.map +1 -0
  112. package/dist/modules/conversions/wire.js +28 -0
  113. package/dist/modules/conversions/wire.js.map +1 -0
  114. package/dist/modules/deals/events.d.ts +9 -0
  115. package/dist/modules/deals/events.d.ts.map +1 -1
  116. package/dist/modules/deals/events.js +4 -0
  117. package/dist/modules/deals/events.js.map +1 -1
  118. package/dist/modules/deals/index.d.ts.map +1 -1
  119. package/dist/modules/deals/index.js +4 -2
  120. package/dist/modules/deals/index.js.map +1 -1
  121. package/dist/modules/deals/routes.d.ts +2 -0
  122. package/dist/modules/deals/routes.d.ts.map +1 -1
  123. package/dist/modules/deals/routes.js +8 -1
  124. package/dist/modules/deals/routes.js.map +1 -1
  125. package/dist/modules/deals/schema.d.ts +34 -0
  126. package/dist/modules/deals/schema.d.ts.map +1 -1
  127. package/dist/modules/deals/schema.js +7 -2
  128. package/dist/modules/deals/schema.js.map +1 -1
  129. package/dist/modules/deals/service.d.ts.map +1 -1
  130. package/dist/modules/deals/service.js +2 -0
  131. package/dist/modules/deals/service.js.map +1 -1
  132. package/dist/modules/deals/tools.d.ts +2 -1
  133. package/dist/modules/deals/tools.d.ts.map +1 -1
  134. package/dist/modules/deals/tools.js +3 -1
  135. package/dist/modules/deals/tools.js.map +1 -1
  136. package/dist/modules/decisions/repository.d.ts +2 -1
  137. package/dist/modules/decisions/repository.d.ts.map +1 -1
  138. package/dist/modules/decisions/repository.js +9 -1
  139. package/dist/modules/decisions/repository.js.map +1 -1
  140. package/dist/modules/enquiries/events.d.ts +6 -2
  141. package/dist/modules/enquiries/events.d.ts.map +1 -1
  142. package/dist/modules/enquiries/events.js +5 -1
  143. package/dist/modules/enquiries/events.js.map +1 -1
  144. package/dist/modules/enquiries/index.d.ts.map +1 -1
  145. package/dist/modules/enquiries/index.js +4 -2
  146. package/dist/modules/enquiries/index.js.map +1 -1
  147. package/dist/modules/enquiries/routes.d.ts +2 -0
  148. package/dist/modules/enquiries/routes.d.ts.map +1 -1
  149. package/dist/modules/enquiries/routes.js +9 -9
  150. package/dist/modules/enquiries/routes.js.map +1 -1
  151. package/dist/modules/enquiries/schema.d.ts +36 -1
  152. package/dist/modules/enquiries/schema.d.ts.map +1 -1
  153. package/dist/modules/enquiries/schema.js +9 -3
  154. package/dist/modules/enquiries/schema.js.map +1 -1
  155. package/dist/modules/enquiries/service.d.ts +0 -8
  156. package/dist/modules/enquiries/service.d.ts.map +1 -1
  157. package/dist/modules/enquiries/service.js +3 -95
  158. package/dist/modules/enquiries/service.js.map +1 -1
  159. package/dist/modules/enquiries/tools.d.ts +2 -1
  160. package/dist/modules/enquiries/tools.d.ts.map +1 -1
  161. package/dist/modules/enquiries/tools.js +4 -16
  162. package/dist/modules/enquiries/tools.js.map +1 -1
  163. package/dist/modules/forms/applyMappedFields.d.ts +20 -0
  164. package/dist/modules/forms/applyMappedFields.d.ts.map +1 -0
  165. package/dist/modules/forms/applyMappedFields.js +169 -0
  166. package/dist/modules/forms/applyMappedFields.js.map +1 -0
  167. package/dist/modules/forms/applySubmissionFields.d.ts +18 -0
  168. package/dist/modules/forms/applySubmissionFields.d.ts.map +1 -0
  169. package/dist/modules/forms/applySubmissionFields.js +230 -0
  170. package/dist/modules/forms/applySubmissionFields.js.map +1 -0
  171. package/dist/modules/forms/fields.d.ts +7 -2
  172. package/dist/modules/forms/fields.d.ts.map +1 -1
  173. package/dist/modules/forms/fields.js +17 -6
  174. package/dist/modules/forms/fields.js.map +1 -1
  175. package/dist/modules/forms/mapping.d.ts +8 -2
  176. package/dist/modules/forms/mapping.d.ts.map +1 -1
  177. package/dist/modules/forms/mapping.js +11 -0
  178. package/dist/modules/forms/mapping.js.map +1 -1
  179. package/dist/modules/forms/repository.d.ts +0 -5
  180. package/dist/modules/forms/repository.d.ts.map +1 -1
  181. package/dist/modules/forms/repository.js +0 -2
  182. package/dist/modules/forms/repository.js.map +1 -1
  183. package/dist/modules/forms/routes.d.ts +2 -30
  184. package/dist/modules/forms/routes.d.ts.map +1 -1
  185. package/dist/modules/forms/routes.js +2 -2
  186. package/dist/modules/forms/routes.js.map +1 -1
  187. package/dist/modules/forms/schema.d.ts.map +1 -1
  188. package/dist/modules/forms/schema.js +1 -2
  189. package/dist/modules/forms/schema.js.map +1 -1
  190. package/dist/modules/forms/service.d.ts.map +1 -1
  191. package/dist/modules/forms/service.js +18 -3
  192. package/dist/modules/forms/service.js.map +1 -1
  193. package/dist/modules/forms/starters.d.ts +31 -0
  194. package/dist/modules/forms/starters.d.ts.map +1 -0
  195. package/dist/modules/forms/starters.js +94 -0
  196. package/dist/modules/forms/starters.js.map +1 -0
  197. package/dist/modules/forms/submission.d.ts +1 -0
  198. package/dist/modules/forms/submission.d.ts.map +1 -1
  199. package/dist/modules/forms/submission.js +58 -37
  200. package/dist/modules/forms/submission.js.map +1 -1
  201. package/dist/modules/import-export/customFieldCsv.d.ts +9 -0
  202. package/dist/modules/import-export/customFieldCsv.d.ts.map +1 -0
  203. package/dist/modules/import-export/customFieldCsv.js +39 -0
  204. package/dist/modules/import-export/customFieldCsv.js.map +1 -0
  205. package/dist/modules/import-export/customFieldImport.d.ts +19 -0
  206. package/dist/modules/import-export/customFieldImport.d.ts.map +1 -0
  207. package/dist/modules/import-export/customFieldImport.js +76 -0
  208. package/dist/modules/import-export/customFieldImport.js.map +1 -0
  209. package/dist/modules/import-export/drafts.d.ts +57 -3
  210. package/dist/modules/import-export/drafts.d.ts.map +1 -1
  211. package/dist/modules/import-export/drafts.js +65 -3
  212. package/dist/modules/import-export/drafts.js.map +1 -1
  213. package/dist/modules/import-export/exportRows.d.ts +15 -13
  214. package/dist/modules/import-export/exportRows.d.ts.map +1 -1
  215. package/dist/modules/import-export/exportRows.js +99 -26
  216. package/dist/modules/import-export/exportRows.js.map +1 -1
  217. package/dist/modules/import-export/plan.d.ts +42 -11
  218. package/dist/modules/import-export/plan.d.ts.map +1 -1
  219. package/dist/modules/import-export/plan.js +198 -56
  220. package/dist/modules/import-export/plan.js.map +1 -1
  221. package/dist/modules/import-export/repository.d.ts +58 -2
  222. package/dist/modules/import-export/repository.d.ts.map +1 -1
  223. package/dist/modules/import-export/repository.js +201 -12
  224. package/dist/modules/import-export/repository.js.map +1 -1
  225. package/dist/modules/import-export/routes.d.ts.map +1 -1
  226. package/dist/modules/import-export/routes.js +5 -5
  227. package/dist/modules/import-export/routes.js.map +1 -1
  228. package/dist/modules/import-export/service.d.ts +8 -3
  229. package/dist/modules/import-export/service.d.ts.map +1 -1
  230. package/dist/modules/import-export/service.js +133 -40
  231. package/dist/modules/import-export/service.js.map +1 -1
  232. package/dist/modules/import-export/streams.d.ts +2 -2
  233. package/dist/modules/import-export/streams.d.ts.map +1 -1
  234. package/dist/modules/import-export/streams.js +50 -9
  235. package/dist/modules/import-export/streams.js.map +1 -1
  236. package/dist/modules/import-export/tools.d.ts.map +1 -1
  237. package/dist/modules/import-export/tools.js +13 -7
  238. package/dist/modules/import-export/tools.js.map +1 -1
  239. package/dist/modules/import-export/validation.d.ts +5 -1
  240. package/dist/modules/import-export/validation.d.ts.map +1 -1
  241. package/dist/modules/import-export/validation.js +89 -2
  242. package/dist/modules/import-export/validation.js.map +1 -1
  243. package/dist/modules/import-export/writes.d.ts +2 -1
  244. package/dist/modules/import-export/writes.d.ts.map +1 -1
  245. package/dist/modules/import-export/writes.js +358 -25
  246. package/dist/modules/import-export/writes.js.map +1 -1
  247. package/dist/modules/lists/repository.d.ts +0 -1
  248. package/dist/modules/lists/repository.d.ts.map +1 -1
  249. package/dist/modules/lists/repository.js +0 -1
  250. package/dist/modules/lists/repository.js.map +1 -1
  251. package/dist/modules/lists/routes.d.ts +0 -2
  252. package/dist/modules/lists/routes.d.ts.map +1 -1
  253. package/dist/modules/lists/routes.js +0 -8
  254. package/dist/modules/lists/routes.js.map +1 -1
  255. package/dist/modules/lists/schema.d.ts +0 -17
  256. package/dist/modules/lists/schema.d.ts.map +1 -1
  257. package/dist/modules/lists/schema.js +0 -10
  258. package/dist/modules/lists/schema.js.map +1 -1
  259. package/dist/modules/lists/service.d.ts +2 -14
  260. package/dist/modules/lists/service.d.ts.map +1 -1
  261. package/dist/modules/lists/service.js +7 -53
  262. package/dist/modules/lists/service.js.map +1 -1
  263. package/dist/modules/lists/starters.d.ts +12 -0
  264. package/dist/modules/lists/starters.d.ts.map +1 -0
  265. package/dist/modules/lists/starters.js +4 -0
  266. package/dist/modules/lists/starters.js.map +1 -0
  267. package/dist/modules/mcp/protocol.d.ts.map +1 -1
  268. package/dist/modules/mcp/protocol.js +13 -0
  269. package/dist/modules/mcp/protocol.js.map +1 -1
  270. package/dist/modules/notes/repository.d.ts +2 -0
  271. package/dist/modules/notes/repository.d.ts.map +1 -1
  272. package/dist/modules/notes/repository.js +9 -0
  273. package/dist/modules/notes/repository.js.map +1 -1
  274. package/dist/modules/opportunities/events.d.ts +9 -0
  275. package/dist/modules/opportunities/events.d.ts.map +1 -1
  276. package/dist/modules/opportunities/events.js +4 -0
  277. package/dist/modules/opportunities/events.js.map +1 -1
  278. package/dist/modules/opportunities/index.d.ts.map +1 -1
  279. package/dist/modules/opportunities/index.js +4 -2
  280. package/dist/modules/opportunities/index.js.map +1 -1
  281. package/dist/modules/opportunities/routes.d.ts +2 -0
  282. package/dist/modules/opportunities/routes.d.ts.map +1 -1
  283. package/dist/modules/opportunities/routes.js +8 -1
  284. package/dist/modules/opportunities/routes.js.map +1 -1
  285. package/dist/modules/opportunities/schema.d.ts +34 -0
  286. package/dist/modules/opportunities/schema.d.ts.map +1 -1
  287. package/dist/modules/opportunities/schema.js +7 -2
  288. package/dist/modules/opportunities/schema.js.map +1 -1
  289. package/dist/modules/opportunities/service.d.ts.map +1 -1
  290. package/dist/modules/opportunities/service.js +2 -0
  291. package/dist/modules/opportunities/service.js.map +1 -1
  292. package/dist/modules/opportunities/tools.d.ts +2 -1
  293. package/dist/modules/opportunities/tools.d.ts.map +1 -1
  294. package/dist/modules/opportunities/tools.js +3 -1
  295. package/dist/modules/opportunities/tools.js.map +1 -1
  296. package/dist/modules/partnerships/events.d.ts +9 -0
  297. package/dist/modules/partnerships/events.d.ts.map +1 -1
  298. package/dist/modules/partnerships/events.js +4 -0
  299. package/dist/modules/partnerships/events.js.map +1 -1
  300. package/dist/modules/partnerships/index.d.ts.map +1 -1
  301. package/dist/modules/partnerships/index.js +4 -2
  302. package/dist/modules/partnerships/index.js.map +1 -1
  303. package/dist/modules/partnerships/routes.d.ts +2 -0
  304. package/dist/modules/partnerships/routes.d.ts.map +1 -1
  305. package/dist/modules/partnerships/routes.js +8 -1
  306. package/dist/modules/partnerships/routes.js.map +1 -1
  307. package/dist/modules/partnerships/schema.d.ts +34 -0
  308. package/dist/modules/partnerships/schema.d.ts.map +1 -1
  309. package/dist/modules/partnerships/schema.js +7 -2
  310. package/dist/modules/partnerships/schema.js.map +1 -1
  311. package/dist/modules/partnerships/service.d.ts.map +1 -1
  312. package/dist/modules/partnerships/service.js +2 -0
  313. package/dist/modules/partnerships/service.js.map +1 -1
  314. package/dist/modules/partnerships/tools.d.ts +2 -1
  315. package/dist/modules/partnerships/tools.d.ts.map +1 -1
  316. package/dist/modules/partnerships/tools.js +3 -1
  317. package/dist/modules/partnerships/tools.js.map +1 -1
  318. package/dist/modules/people/personConsentWrites.d.ts +1 -1
  319. package/dist/modules/people/schema.js +1 -1
  320. package/dist/modules/people/schema.js.map +1 -1
  321. package/dist/modules/plans/repository.d.ts +2 -0
  322. package/dist/modules/plans/repository.d.ts.map +1 -1
  323. package/dist/modules/plans/repository.js +9 -0
  324. package/dist/modules/plans/repository.js.map +1 -1
  325. package/dist/modules/raises/events.d.ts +9 -0
  326. package/dist/modules/raises/events.d.ts.map +1 -1
  327. package/dist/modules/raises/events.js +4 -0
  328. package/dist/modules/raises/events.js.map +1 -1
  329. package/dist/modules/raises/index.d.ts.map +1 -1
  330. package/dist/modules/raises/index.js +4 -2
  331. package/dist/modules/raises/index.js.map +1 -1
  332. package/dist/modules/raises/routes.d.ts +2 -0
  333. package/dist/modules/raises/routes.d.ts.map +1 -1
  334. package/dist/modules/raises/routes.js +8 -1
  335. package/dist/modules/raises/routes.js.map +1 -1
  336. package/dist/modules/raises/schema.d.ts +34 -0
  337. package/dist/modules/raises/schema.d.ts.map +1 -1
  338. package/dist/modules/raises/schema.js +7 -2
  339. package/dist/modules/raises/schema.js.map +1 -1
  340. package/dist/modules/raises/service.d.ts.map +1 -1
  341. package/dist/modules/raises/service.js +2 -0
  342. package/dist/modules/raises/service.js.map +1 -1
  343. package/dist/modules/raises/tools.d.ts +2 -1
  344. package/dist/modules/raises/tools.d.ts.map +1 -1
  345. package/dist/modules/raises/tools.js +3 -1
  346. package/dist/modules/raises/tools.js.map +1 -1
  347. package/dist/modules/workspace/routes.d.ts +0 -2
  348. package/dist/modules/workspace/routes.d.ts.map +1 -1
  349. package/dist/modules/workspace/routes.js +0 -6
  350. package/dist/modules/workspace/routes.js.map +1 -1
  351. package/dist/modules/workspace/schema.d.ts +0 -34
  352. package/dist/modules/workspace/schema.d.ts.map +1 -1
  353. package/dist/modules/workspace/schema.js +0 -2
  354. package/dist/modules/workspace/schema.js.map +1 -1
  355. package/dist/modules/workspace/seedStarterForms.d.ts +17 -0
  356. package/dist/modules/workspace/seedStarterForms.d.ts.map +1 -0
  357. package/dist/modules/workspace/seedStarterForms.js +71 -0
  358. package/dist/modules/workspace/seedStarterForms.js.map +1 -0
  359. package/dist/modules/workspace/service.d.ts +0 -4
  360. package/dist/modules/workspace/service.d.ts.map +1 -1
  361. package/dist/modules/workspace/service.js +20 -10
  362. package/dist/modules/workspace/service.js.map +1 -1
  363. package/dist/modules/workspace/tools.js +1 -1
  364. package/dist/modules/workspace/tools.js.map +1 -1
  365. package/dist/runtime/module.d.ts +63 -1
  366. package/dist/runtime/module.d.ts.map +1 -1
  367. package/dist/runtime/registry.d.ts.map +1 -1
  368. package/dist/runtime/registry.js +40 -2
  369. package/dist/runtime/registry.js.map +1 -1
  370. package/dist/testing/fixtures.d.ts.map +1 -1
  371. package/dist/testing/fixtures.js +1 -0
  372. package/dist/testing/fixtures.js.map +1 -1
  373. package/migrations/0037_drop_lists_consent_purpose_id.sql +2 -0
  374. package/migrations/0038_smart_white_queen.sql +2 -0
  375. package/migrations/0039_form_map_to_open.sql +1 -0
  376. package/migrations/0040_pipeline_converted_to.sql +20 -0
  377. package/migrations/0041_api_key_scopes.sql +1 -0
  378. package/migrations/0042_drop_workspace_identity.sql +2 -0
  379. package/migrations/0043_external_sign_in.sql +2 -0
  380. package/migrations/meta/0038_snapshot.json +6554 -0
  381. package/migrations/meta/_journal.json +49 -0
  382. package/package.json +2 -2
  383. package/src/app.ts +3 -0
  384. package/src/index.ts +13 -1
  385. package/src/lib/actor.ts +3 -1
  386. package/src/lib/apiKeyScopes.ts +213 -0
  387. package/src/lib/errors.ts +30 -0
  388. package/src/modules/activities/repository.ts +24 -0
  389. package/src/modules/agent-tasks/repository.ts +24 -0
  390. package/src/modules/api-keys/routes.ts +5 -0
  391. package/src/modules/api-keys/schema.ts +2 -0
  392. package/src/modules/api-keys/scopeMiddleware.ts +30 -0
  393. package/src/modules/api-keys/service.ts +36 -2
  394. package/src/modules/auth/credentials.ts +4 -0
  395. package/src/modules/auth/index.ts +25 -4
  396. package/src/modules/auth/repository.ts +2 -1
  397. package/src/modules/auth/routes.ts +2 -8
  398. package/src/modules/auth/schema.ts +12 -1
  399. package/src/modules/auth/service.ts +143 -6
  400. package/src/modules/auth/session.ts +14 -0
  401. package/src/modules/consent-purposes/index.ts +1 -1
  402. package/src/modules/consent-purposes/schema.ts +3 -3
  403. package/src/modules/consent-purposes/service.ts +7 -16
  404. package/src/modules/consent-purposes/starters.ts +1 -1
  405. package/src/modules/consent-purposes/tools.ts +1 -1
  406. package/src/modules/conversions/clearPointers.ts +81 -0
  407. package/src/modules/conversions/factory.ts +20 -0
  408. package/src/modules/conversions/fieldMap.ts +548 -0
  409. package/src/modules/conversions/index.ts +6 -0
  410. package/src/modules/conversions/mcp.ts +71 -0
  411. package/src/modules/conversions/repoint.ts +146 -0
  412. package/src/modules/conversions/routes.ts +68 -0
  413. package/src/modules/conversions/service.ts +310 -0
  414. package/src/modules/conversions/wire.ts +42 -0
  415. package/src/modules/deals/events.ts +9 -0
  416. package/src/modules/deals/index.ts +4 -2
  417. package/src/modules/deals/routes.ts +11 -1
  418. package/src/modules/deals/schema.ts +10 -2
  419. package/src/modules/deals/service.ts +3 -0
  420. package/src/modules/deals/tools.ts +9 -1
  421. package/src/modules/decisions/repository.ts +23 -1
  422. package/src/modules/enquiries/events.ts +8 -2
  423. package/src/modules/enquiries/index.ts +4 -2
  424. package/src/modules/enquiries/routes.ts +11 -13
  425. package/src/modules/enquiries/schema.ts +12 -3
  426. package/src/modules/enquiries/service.ts +3 -150
  427. package/src/modules/enquiries/tools.ts +9 -18
  428. package/src/modules/forms/applyMappedFields.ts +248 -0
  429. package/src/modules/forms/applySubmissionFields.ts +435 -0
  430. package/src/modules/forms/fields.ts +31 -7
  431. package/src/modules/forms/mapping.ts +20 -3
  432. package/src/modules/forms/repository.ts +0 -7
  433. package/src/modules/forms/routes.ts +1 -2
  434. package/src/modules/forms/schema.ts +0 -2
  435. package/src/modules/forms/service.ts +31 -4
  436. package/src/modules/forms/starters.ts +129 -0
  437. package/src/modules/forms/submission.ts +135 -69
  438. package/src/modules/import-export/customFieldCsv.ts +55 -0
  439. package/src/modules/import-export/customFieldImport.ts +111 -0
  440. package/src/modules/import-export/drafts.ts +151 -3
  441. package/src/modules/import-export/exportRows.ts +222 -68
  442. package/src/modules/import-export/plan.ts +321 -67
  443. package/src/modules/import-export/repository.ts +356 -14
  444. package/src/modules/import-export/routes.ts +8 -8
  445. package/src/modules/import-export/service.ts +208 -45
  446. package/src/modules/import-export/streams.ts +95 -13
  447. package/src/modules/import-export/tools.ts +14 -6
  448. package/src/modules/import-export/validation.ts +128 -0
  449. package/src/modules/import-export/writes.ts +559 -27
  450. package/src/modules/lists/repository.ts +0 -2
  451. package/src/modules/lists/routes.ts +0 -8
  452. package/src/modules/lists/schema.ts +0 -10
  453. package/src/modules/lists/service.ts +9 -107
  454. package/src/modules/lists/starters.ts +16 -0
  455. package/src/modules/mcp/protocol.ts +18 -0
  456. package/src/modules/notes/repository.ts +24 -0
  457. package/src/modules/opportunities/events.ts +9 -0
  458. package/src/modules/opportunities/index.ts +4 -2
  459. package/src/modules/opportunities/routes.ts +11 -1
  460. package/src/modules/opportunities/schema.ts +10 -2
  461. package/src/modules/opportunities/service.ts +3 -0
  462. package/src/modules/opportunities/tools.ts +9 -1
  463. package/src/modules/partnerships/events.ts +9 -0
  464. package/src/modules/partnerships/index.ts +4 -2
  465. package/src/modules/partnerships/routes.ts +11 -1
  466. package/src/modules/partnerships/schema.ts +10 -2
  467. package/src/modules/partnerships/service.ts +3 -0
  468. package/src/modules/partnerships/tools.ts +9 -1
  469. package/src/modules/people/personConsentWrites.ts +1 -1
  470. package/src/modules/people/schema.ts +1 -1
  471. package/src/modules/plans/repository.ts +24 -0
  472. package/src/modules/raises/events.ts +9 -0
  473. package/src/modules/raises/index.ts +4 -2
  474. package/src/modules/raises/routes.ts +11 -1
  475. package/src/modules/raises/schema.ts +10 -2
  476. package/src/modules/raises/service.ts +3 -0
  477. package/src/modules/raises/tools.ts +9 -1
  478. package/src/modules/workspace/routes.ts +0 -6
  479. package/src/modules/workspace/schema.ts +0 -2
  480. package/src/modules/workspace/seedStarterForms.ts +98 -0
  481. package/src/modules/workspace/service.ts +23 -15
  482. package/src/modules/workspace/tools.ts +1 -1
  483. package/src/runtime/module.ts +70 -1
  484. package/src/runtime/registry.ts +54 -0
  485. package/src/testing/fixtures.ts +1 -0
@@ -1,7 +1,9 @@
1
+ import { sql } from 'drizzle-orm'
2
+ import { check, date, index, jsonb, pgTable, text } from 'drizzle-orm/pg-core'
3
+ import { PIPELINE_KINDS } from '@kelpie/schemas'
1
4
  import type { CustomFieldValue } from '@kelpie/schemas'
2
- import { date, index, jsonb, pgTable, text } from 'drizzle-orm/pg-core'
3
5
 
4
- import { createdAt, primaryId, searchVector, updatedAt } from '../../lib/columns.ts'
6
+ import { createdAt, oneOf, primaryId, searchVector, updatedAt } from '../../lib/columns.ts'
5
7
  import type { SearchVectorPart } from '../../lib/columns.ts'
6
8
  import { companies } from '../companies/schema.ts'
7
9
  import { pipelineStages } from '../pipelines/schema.ts'
@@ -32,6 +34,8 @@ export const partnerships = pgTable(
32
34
  successLooksLike: text('success_looks_like').notNull().default(''),
33
35
  summary: text('summary').notNull().default(''),
34
36
  tags: text('tags').array().notNull().default([]),
37
+ convertedTargetType: text('converted_target_type'),
38
+ convertedTargetId: text('converted_target_id'),
35
39
  // Workspace-defined fields, keyed by definition key. See people/schema.ts.
36
40
  customFields: jsonb('custom_fields')
37
41
  .$type<Readonly<Record<string, CustomFieldValue>>>()
@@ -53,6 +57,10 @@ export const partnerships = pgTable(
53
57
  index('partnerships_company_idx').on(table.companyId),
54
58
  index('partnerships_stage_idx').on(table.stageId),
55
59
  index('partnerships_search_idx').using('gin', table.searchVector),
60
+ check(
61
+ 'partnerships_converted_target_type_check',
62
+ sql`${table.convertedTargetType} is null or ${oneOf('partnerships_converted_target_type_check', table.convertedTargetType, PIPELINE_KINDS)}`,
63
+ ),
56
64
  ],
57
65
  )
58
66
 
@@ -21,6 +21,7 @@ import type { Actor } from '../auth/actor.ts'
21
21
  import { actorMemberId, requireWorkspaceId } from '../auth/actor.ts'
22
22
  import './events.ts'
23
23
  import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
24
+ import { clearConversionPointersToTarget } from '../conversions/clearPointers.ts'
24
25
  import * as companyRepository from '../companies/repository.ts'
25
26
  import type { CustomFieldValuesValidator } from '../custom-fields/values.ts'
26
27
  import * as personLinks from '../personLinks.ts'
@@ -499,6 +500,8 @@ export function createPartnershipsService(
499
500
  await dependencies.transaction(async ({ tx, events }) => {
500
501
  await require(workspaceId, id)
501
502
 
503
+ await clearConversionPointersToTarget(tx, workspaceId, 'partnership', id)
504
+
502
505
  // Notes, activities, decisions, plan items, and person_links have no
503
506
  // key back to the partnership, so they are removed here, in the same
504
507
  // transaction.
@@ -2,6 +2,8 @@ import { z } from 'zod'
2
2
 
3
3
  import type { McpToolRegistry } from '../../runtime/module.ts'
4
4
  import { idArg, idSetArg, listWindowShape, registerCrudTools, termArg, toSet } from '../crudTools.ts'
5
+ import type { ConversionsService } from '../conversions/index.ts'
6
+ import { registerPipelineConvertTool } from '../conversions/mcp.ts'
5
7
  import { createBody, partnershipResponse, toCreateInput, toUpdateInput, updateBody } from './routes.ts'
6
8
  import type { PartnershipsService } from './service.ts'
7
9
 
@@ -16,7 +18,11 @@ const listArgs = z.strictObject({
16
18
  person_id: idSetArg.optional().describe('Only partnerships one of these people is a contact on.'),
17
19
  })
18
20
 
19
- export function registerPartnershipsTools(mcp: McpToolRegistry, service: PartnershipsService): void {
21
+ export function registerPartnershipsTools(
22
+ mcp: McpToolRegistry,
23
+ service: PartnershipsService,
24
+ conversions: ConversionsService,
25
+ ): void {
20
26
  registerCrudTools(mcp, {
21
27
  resource: 'partnerships',
22
28
  subject: 'partnership',
@@ -38,4 +44,6 @@ export function registerPartnershipsTools(mcp: McpToolRegistry, service: Partner
38
44
  updateArgs: updateBody.extend({ id: idArg }),
39
45
  toUpdateInput,
40
46
  })
47
+
48
+ registerPipelineConvertTool(mcp, conversions, 'partnership')
41
49
  }
@@ -8,7 +8,7 @@ import { personConsents } from './schema.ts'
8
8
 
9
9
  /**
10
10
  * Writes to `person_consents`, shared by the manual PATCH override and every
11
- * capture site (forms, lists, imports). Every write is idempotent — a second
11
+ * capture site (forms, imports). Every write is idempotent — a second
12
12
  * grant for the same (person, purpose) with the same source is a no-op.
13
13
  *
14
14
  * `source` follows the shape in `docs/privacy.md`:
@@ -84,7 +84,7 @@ export const people = pgTable(
84
84
  lastContactedAt: moment('last_contacted_at'),
85
85
  // The Article 21 objection. A global do-not-contact signal, independent
86
86
  // of consent purposes: agents check this before outreach regardless of
87
- // per-purpose consent state. Never touched by forms, lists, or imports —
87
+ // per-purpose consent state. Never touched by forms or imports —
88
88
  // the workspace member owns this flag.
89
89
  doNotContact: boolean('do_not_contact').notNull().default(false),
90
90
  // Workspace-defined fields, keyed by definition key. The custom-fields
@@ -158,6 +158,30 @@ export async function deleteForTarget(
158
158
  return deleted.length
159
159
  }
160
160
 
161
+ /** Moves every plan item from one target to another inside a conversion transaction. */
162
+ export async function repointForTarget(
163
+ db: Queryable,
164
+ workspaceId: string,
165
+ fromType: string,
166
+ fromId: string,
167
+ toType: string,
168
+ toId: string,
169
+ ): Promise<number> {
170
+ const updated = await db
171
+ .update(planItems)
172
+ .set({ targetType: toType, targetId: toId })
173
+ .where(
174
+ and(
175
+ eq(planItems.workspaceId, workspaceId),
176
+ eq(planItems.targetType, fromType),
177
+ eq(planItems.targetId, fromId),
178
+ ),
179
+ )
180
+ .returning({ id: planItems.id })
181
+
182
+ return updated.length
183
+ }
184
+
161
185
  /** Whether a member belongs to this workspace, for validating `owner_id`. */
162
186
  export async function memberExists(
163
187
  db: Queryable,
@@ -12,6 +12,10 @@ export const raisesEvents = {
12
12
  fromStageId: z.string().nullable(),
13
13
  toStageId: z.string(),
14
14
  }),
15
+ 'raises.raise.converted': z.object({
16
+ targetType: z.string(),
17
+ targetId: z.string(),
18
+ }),
15
19
  } satisfies ModuleEventCatalog
16
20
 
17
21
  export type RaiseCreatedData = Record<string, never>
@@ -23,6 +27,10 @@ export interface RaiseStageChangedData {
23
27
  readonly fromStageId: string | null
24
28
  readonly toStageId: string
25
29
  }
30
+ export interface RaiseConvertedData {
31
+ readonly targetType: string
32
+ readonly targetId: string
33
+ }
26
34
 
27
35
  declare module '../../runtime/events.ts' {
28
36
  interface KelpieEventMap {
@@ -30,5 +38,6 @@ declare module '../../runtime/events.ts' {
30
38
  'raises.raise.updated': RaiseUpdatedData
31
39
  'raises.raise.deleted': RaiseDeletedData
32
40
  'raises.raise.stage_changed': RaiseStageChangedData
41
+ 'raises.raise.converted': RaiseConvertedData
33
42
  }
34
43
  }
@@ -1,5 +1,6 @@
1
1
  import type { KelpieModule } from '../../runtime/module.ts'
2
2
  import { createActivityRecorder } from '../activities/index.ts'
3
+ import { createConversionsFromContext } from '../conversions/index.ts'
3
4
  import { createCustomFieldValues } from '../custom-fields/index.ts'
4
5
  import { raisesEvents } from './events.ts'
5
6
  import { mountRaisesRoutes } from './routes.ts'
@@ -22,6 +23,7 @@ export function createRaisesModule(migrationsDirectory: string): KelpieModule {
22
23
  events: raisesEvents,
23
24
 
24
25
  register(context) {
26
+ const conversions = createConversionsFromContext(context)
25
27
  const service = createRaisesService({
26
28
  db: context.db,
27
29
  transaction: context.transaction,
@@ -37,10 +39,10 @@ export function createRaisesModule(migrationsDirectory: string): KelpieModule {
37
39
  context.schema(schema, migrationsDirectory)
38
40
 
39
41
  context.routes((router) => {
40
- mountRaisesRoutes(router, { db: context.db, now: context.now, service })
42
+ mountRaisesRoutes(router, { db: context.db, now: context.now, service, conversions })
41
43
  })
42
44
 
43
- registerRaisesTools(context.mcp, service)
45
+ registerRaisesTools(context.mcp, service, conversions)
44
46
 
45
47
  return Promise.resolve()
46
48
  },
@@ -1,4 +1,4 @@
1
- import { customFieldsPatchShape } from '@kelpie/schemas'
1
+ import { convertPipelineRecordBody, convertedToResponse, customFieldsPatchShape } from '@kelpie/schemas'
2
2
  import type { Context, Hono } from 'hono'
3
3
  import { z } from 'zod'
4
4
 
@@ -8,6 +8,8 @@ import type { Actor } from '../auth/actor.ts'
8
8
  import { resolveActorFrom } from '../auth/credentials.ts'
9
9
  import type { CredentialDependencies } from '../auth/credentials.ts'
10
10
  import { renderCustomFieldsForWire } from '../custom-fields/wire.ts'
11
+ import { mountPipelineConvertRoute } from '../conversions/routes.ts'
12
+ import type { ConversionsService } from '../conversions/index.ts'
11
13
  import type { CreateRaiseInput, RaiseView, RaisesService, UpdateRaiseInput } from './service.ts'
12
14
 
13
15
  /** Wire shapes for `/v1/raises`. Bodies are strict; an unknown field is a 422, per `api.md`. */
@@ -58,6 +60,7 @@ export const updateBody = z.strictObject(raiseShape).partial()
58
60
 
59
61
  export interface RaisesRoutesDependencies extends CredentialDependencies {
60
62
  readonly service: RaisesService
63
+ readonly conversions: ConversionsService
61
64
  }
62
65
 
63
66
  export function toCreateInput(body: z.infer<typeof createBody>): CreateRaiseInput {
@@ -111,6 +114,7 @@ export function raiseResponse(raise: RaiseView): Record<string, unknown> {
111
114
  person_ids: raise.personIds,
112
115
  summary: raise.summary,
113
116
  tags: raise.tags,
117
+ converted_to: convertedToResponse(raise.convertedTargetType, raise.convertedTargetId),
114
118
  custom_fields: renderCustomFieldsForWire(raise.customFields),
115
119
  created_at: raise.createdAt.toISOString(),
116
120
  updated_at: raise.updatedAt.toISOString(),
@@ -164,4 +168,10 @@ export function mountRaisesRoutes(router: Hono, dependencies: RaisesRoutesDepend
164
168
 
165
169
  return context.body(null, 204)
166
170
  })
171
+
172
+ mountPipelineConvertRoute(router, '/raises/:id/convert', {
173
+ ...dependencies,
174
+ sourceKind: 'raise',
175
+ bodySchema: convertPipelineRecordBody,
176
+ })
167
177
  }
@@ -1,7 +1,9 @@
1
+ import { sql } from 'drizzle-orm'
2
+ import { check, bigint, date, index, jsonb, pgTable, text } from 'drizzle-orm/pg-core'
3
+ import { PIPELINE_KINDS } from '@kelpie/schemas'
1
4
  import type { CustomFieldValue } from '@kelpie/schemas'
2
- import { bigint, date, index, jsonb, pgTable, text } from 'drizzle-orm/pg-core'
3
5
 
4
- import { createdAt, primaryId, searchVector, updatedAt } from '../../lib/columns.ts'
6
+ import { createdAt, oneOf, primaryId, searchVector, updatedAt } from '../../lib/columns.ts'
5
7
  import type { SearchVectorPart } from '../../lib/columns.ts'
6
8
  import { companies } from '../companies/schema.ts'
7
9
  import { pipelineStages } from '../pipelines/schema.ts'
@@ -34,6 +36,8 @@ export const raises = pgTable(
34
36
  expectedClose: date('expected_close'),
35
37
  summary: text('summary').notNull().default(''),
36
38
  tags: text('tags').array().notNull().default([]),
39
+ convertedTargetType: text('converted_target_type'),
40
+ convertedTargetId: text('converted_target_id'),
37
41
  // Workspace-defined fields, keyed by definition key. See people/schema.ts.
38
42
  customFields: jsonb('custom_fields')
39
43
  .$type<Readonly<Record<string, CustomFieldValue>>>()
@@ -54,6 +58,10 @@ export const raises = pgTable(
54
58
  index('raises_company_idx').on(table.companyId),
55
59
  index('raises_stage_idx').on(table.stageId),
56
60
  index('raises_search_idx').using('gin', table.searchVector),
61
+ check(
62
+ 'raises_converted_target_type_check',
63
+ sql`${table.convertedTargetType} is null or ${oneOf('raises_converted_target_type_check', table.convertedTargetType, PIPELINE_KINDS)}`,
64
+ ),
57
65
  ],
58
66
  )
59
67
 
@@ -21,6 +21,7 @@ import type { Actor } from '../auth/actor.ts'
21
21
  import { actorMemberId, requireWorkspaceId } from '../auth/actor.ts'
22
22
  import './events.ts'
23
23
  import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
24
+ import { clearConversionPointersToTarget } from '../conversions/clearPointers.ts'
24
25
  import * as companyRepository from '../companies/repository.ts'
25
26
  import type { CustomFieldValuesValidator } from '../custom-fields/values.ts'
26
27
  import * as personLinks from '../personLinks.ts'
@@ -499,6 +500,8 @@ export function createRaisesService(dependencies: RaisesDependencies): RaisesSer
499
500
  await dependencies.transaction(async ({ tx, events }) => {
500
501
  await require(workspaceId, id)
501
502
 
503
+ await clearConversionPointersToTarget(tx, workspaceId, 'raise', id)
504
+
502
505
  // Notes, activities, decisions, plan items, and person_links have no key back to the raise;
503
506
  // activities, decisions and plan items have no key, so they are removed
504
507
  // here, in the same transaction.
@@ -2,6 +2,8 @@ import { z } from 'zod'
2
2
 
3
3
  import type { McpToolRegistry } from '../../runtime/module.ts'
4
4
  import { idArg, idSetArg, listWindowShape, registerCrudTools, termArg, toSet } from '../crudTools.ts'
5
+ import type { ConversionsService } from '../conversions/index.ts'
6
+ import { registerPipelineConvertTool } from '../conversions/mcp.ts'
5
7
  import { createBody, raiseResponse, toCreateInput, toUpdateInput, updateBody } from './routes.ts'
6
8
  import type { RaisesService } from './service.ts'
7
9
 
@@ -15,7 +17,11 @@ const listArgs = z.strictObject({
15
17
  person_id: idSetArg.optional().describe('Only raises one of these people is key on.'),
16
18
  })
17
19
 
18
- export function registerRaisesTools(mcp: McpToolRegistry, service: RaisesService): void {
20
+ export function registerRaisesTools(
21
+ mcp: McpToolRegistry,
22
+ service: RaisesService,
23
+ conversions: ConversionsService,
24
+ ): void {
19
25
  registerCrudTools(mcp, {
20
26
  resource: 'raises',
21
27
  subject: 'raise',
@@ -36,4 +42,6 @@ export function registerRaisesTools(mcp: McpToolRegistry, service: RaisesService
36
42
  updateArgs: updateBody.extend({ id: idArg }),
37
43
  toUpdateInput,
38
44
  })
45
+
46
+ registerPipelineConvertTool(mcp, conversions, 'raise')
39
47
  }
@@ -26,8 +26,6 @@ export const updateBody = z
26
26
  name: z.string().min(1),
27
27
  slug: z.string().min(1).max(63).regex(slugPattern, 'Use lowercase letters, digits, and hyphens'),
28
28
  timezone: timezoneSchema,
29
- tagline: z.string().nullable(),
30
- one_liner: z.string().nullable(),
31
29
  })
32
30
  .partial()
33
31
 
@@ -65,8 +63,6 @@ export function workspaceResponse(workspace: WorkspaceView): Record<string, unkn
65
63
  name: workspace.name,
66
64
  slug: workspace.slug,
67
65
  timezone: workspace.timezone,
68
- tagline: workspace.tagline,
69
- one_liner: workspace.oneLiner,
70
66
  }
71
67
  }
72
68
 
@@ -122,8 +118,6 @@ export function mountWorkspaceRoutes(router: Hono, dependencies: WorkspaceRoutes
122
118
  ...(body.name === undefined ? {} : { name: body.name }),
123
119
  ...(body.slug === undefined ? {} : { slug: body.slug }),
124
120
  ...(body.timezone === undefined ? {} : { timezone: body.timezone }),
125
- ...(body.tagline === undefined ? {} : { tagline: body.tagline }),
126
- ...(body.one_liner === undefined ? {} : { oneLiner: body.one_liner }),
127
121
  })
128
122
 
129
123
  return context.json(workspaceResponse(workspace))
@@ -14,8 +14,6 @@ export const workspaces = pgTable('workspaces', {
14
14
  name: text('name').notNull(),
15
15
  slug: text('slug').notNull().unique(),
16
16
  timezone: text('timezone').notNull(),
17
- tagline: text('tagline'),
18
- oneLiner: text('one_liner'),
19
17
  createdAt: createdAt(),
20
18
  updatedAt: updatedAt(),
21
19
  })
@@ -0,0 +1,98 @@
1
+ import type { IdFactory } from '../../lib/ids.ts'
2
+ import type { Transaction } from '../../runtime/transaction.ts'
3
+ import { STARTER_FORMS } from '../forms/starters.ts'
4
+ import type { StarterConsentPurposeSlug, StarterListSlug } from '../forms/starters.ts'
5
+ import * as formsRepository from '../forms/repository.ts'
6
+ import { STARTER_LISTS } from '../lists/starters.ts'
7
+ import * as listsRepository from '../lists/repository.ts'
8
+
9
+ export interface SeedStarterFormsInput {
10
+ readonly workspaceId: string
11
+ readonly createId: IdFactory
12
+ readonly generatePublicKey: () => string
13
+ readonly consentPurposeIdsBySlug: Readonly<Partial<Record<StarterConsentPurposeSlug, string>>>
14
+ }
15
+
16
+ /**
17
+ * Inserts the starter lists and forms for a new workspace.
18
+ *
19
+ * Called from `WorkspaceService.create()` in the same transaction as handbook
20
+ * pages and consent purposes, so a reader never lands in an empty forms list.
21
+ */
22
+ export async function seedStarterForms(
23
+ tx: Transaction,
24
+ input: SeedStarterFormsInput,
25
+ ): Promise<void> {
26
+ const listIdsBySlug = new Map<StarterListSlug, string>()
27
+
28
+ for (const list of STARTER_LISTS) {
29
+ const id = input.createId('list')
30
+ await listsRepository.insertList(tx, {
31
+ id,
32
+ workspaceId: input.workspaceId,
33
+ name: list.name,
34
+ description: null,
35
+ targetType: list.targetType,
36
+ })
37
+ listIdsBySlug.set(list.slug as StarterListSlug, id)
38
+ }
39
+
40
+ for (const form of STARTER_FORMS) {
41
+ const formId = input.createId('form')
42
+ await formsRepository.insertForm(tx, {
43
+ id: formId,
44
+ workspaceId: input.workspaceId,
45
+ name: form.name,
46
+ title: form.title,
47
+ description: form.description,
48
+ status: 'active',
49
+ thankYouMessage: form.thankYouMessage,
50
+ publicKey: input.generatePublicKey(),
51
+ })
52
+
53
+ await formsRepository.insertFields(
54
+ tx,
55
+ form.fields.map((field, index) => {
56
+ const consentPurposeIds =
57
+ field.consentPurposeSlug === undefined
58
+ ? []
59
+ : (() => {
60
+ const purposeId = input.consentPurposeIdsBySlug[field.consentPurposeSlug]
61
+ if (purposeId === undefined) {
62
+ throw new Error(
63
+ `Starter form ${form.slug} names unknown consent purpose ${field.consentPurposeSlug}`,
64
+ )
65
+ }
66
+ return [purposeId]
67
+ })()
68
+
69
+ return {
70
+ id: input.createId('formField'),
71
+ workspaceId: input.workspaceId,
72
+ formId,
73
+ label: field.label,
74
+ type: field.type,
75
+ required: field.required,
76
+ mapTo: field.mapTo,
77
+ options: [],
78
+ placeholder: field.placeholder ?? null,
79
+ statement: field.statement ?? null,
80
+ consentPurposeIds,
81
+ consentPurposeLabels: {},
82
+ sortOrder: index,
83
+ }
84
+ }),
85
+ )
86
+
87
+ const linkedListId =
88
+ form.linkedListSlug === undefined ? undefined : listIdsBySlug.get(form.linkedListSlug)
89
+
90
+ if (form.linkedListSlug !== undefined && linkedListId === undefined) {
91
+ throw new Error(`Starter form ${form.slug} names unknown list ${form.linkedListSlug}`)
92
+ }
93
+
94
+ if (linkedListId !== undefined) {
95
+ await formsRepository.replaceFormLists(tx, input.workspaceId, formId, [linkedListId])
96
+ }
97
+ }
98
+ }
@@ -17,6 +17,7 @@ import * as authRepository from '../auth/repository.ts'
17
17
  import { SEATS_LIMIT } from './capabilities.ts'
18
18
  import { STARTER_CONSENT_PURPOSES } from '../consent-purposes/starters.ts'
19
19
  import * as repository from './repository.ts'
20
+ import { seedStarterForms } from './seedStarterForms.ts'
20
21
  import { parseInvitableRole, parseMemberRole, roleAllows } from './roles.ts'
21
22
  import type { InvitableRole, InviteStatus, MemberRole } from './roles.ts'
22
23
  import {
@@ -55,8 +56,6 @@ export interface WorkspaceView {
55
56
  readonly name: string
56
57
  readonly slug: string
57
58
  readonly timezone: string
58
- readonly tagline: string | null
59
- readonly oneLiner: string | null
60
59
  }
61
60
 
62
61
  export interface MemberView {
@@ -104,8 +103,6 @@ export interface UpdateWorkspaceInput {
104
103
  readonly name?: string | undefined
105
104
  readonly slug?: string | undefined
106
105
  readonly timezone?: string | undefined
107
- readonly tagline?: string | null | undefined
108
- readonly oneLiner?: string | null | undefined
109
106
  }
110
107
 
111
108
  export interface WorkspaceService {
@@ -145,8 +142,6 @@ function toWorkspaceView(record: repository.WorkspaceRecord): WorkspaceView {
145
142
  name: record.name,
146
143
  slug: record.slug,
147
144
  timezone: record.timezone,
148
- tagline: record.tagline,
149
- oneLiner: record.oneLiner,
150
145
  }
151
146
  }
152
147
 
@@ -472,19 +467,32 @@ export function createWorkspaceService(dependencies: WorkspaceDependencies): Wor
472
467
  ),
473
468
  )
474
469
 
470
+ const consentPurposeIdsBySlug: Partial<Record<string, string>> = {}
471
+
475
472
  await repository.insertConsentPurposes(
476
473
  tx,
477
- STARTER_CONSENT_PURPOSES.map((purpose, index) => ({
478
- id: dependencies.createId('consentPurpose'),
479
- workspaceId,
480
- slug: purpose.slug,
481
- label: purpose.label,
482
- description: purpose.description,
483
- defaultStatus: purpose.defaultStatus,
484
- sortOrder: index,
485
- })),
474
+ STARTER_CONSENT_PURPOSES.map((purpose, index) => {
475
+ const id = dependencies.createId('consentPurpose')
476
+ consentPurposeIdsBySlug[purpose.slug] = id
477
+ return {
478
+ id,
479
+ workspaceId,
480
+ slug: purpose.slug,
481
+ label: purpose.label,
482
+ description: purpose.description,
483
+ defaultStatus: purpose.defaultStatus,
484
+ sortOrder: index,
485
+ }
486
+ }),
486
487
  )
487
488
 
489
+ await seedStarterForms(tx, {
490
+ workspaceId,
491
+ createId: dependencies.createId,
492
+ generatePublicKey: generateToken,
493
+ consentPurposeIdsBySlug,
494
+ })
495
+
488
496
  // The session that created the workspace should land in it.
489
497
  await authRepository.setActiveWorkspace(tx, actor.sessionId, workspaceId)
490
498
 
@@ -27,7 +27,7 @@ export function registerWorkspaceTools(mcp: McpToolRegistry, service: WorkspaceS
27
27
  mcp.tool({
28
28
  name: 'workspace_get',
29
29
  description:
30
- 'This workspace\'s name, slug, timezone, tagline and one-liner. Mirrors GET /v1/workspaces/{id}.',
30
+ 'This workspace\'s name, slug, and timezone. Mirrors GET /v1/workspaces/{id}.',
31
31
  inputSchema: noArgs,
32
32
  invoke: async (_args, actor) =>
33
33
  workspaceResponse(await service.get(actor, requireWorkspaceId(actor))),
@@ -1,4 +1,4 @@
1
- import type { Handler, Hono, MiddlewareHandler } from 'hono'
1
+ import type { Context, Handler, Hono, MiddlewareHandler } from 'hono'
2
2
  import type { ZodType } from 'zod'
3
3
 
4
4
  import type { Actor } from '../lib/actor.ts'
@@ -58,6 +58,53 @@ export interface McpToolRegistry {
58
58
  tool<Input>(definition: McpToolDefinition<Input>): void
59
59
  }
60
60
 
61
+ /**
62
+ * An identity a module verified somewhere else, handed back for core to sign in.
63
+ *
64
+ * Core never learns what OIDC or SAML is. Verification is the module's job and
65
+ * core does not redo it; core's job is that everything downstream of the cookie
66
+ * is identical to a password sign-in.
67
+ */
68
+ export interface VerifiedIdentity {
69
+ readonly email: string
70
+ /** Core refuses the identity when false, rather than assuming the module checked. */
71
+ readonly emailVerified: boolean
72
+ /** The provider's display name, when it has one. The local part of the address is used otherwise. */
73
+ readonly name: string | null
74
+ /** Who verified it, recorded on the session: the module id, optionally suffixed (`sign-in:google`). */
75
+ readonly verifiedBy: string
76
+ /**
77
+ * What to do with an address core has never seen. The policy is the module's,
78
+ * because only it knows whether its provider vouches for strangers; executing
79
+ * it is core's.
80
+ */
81
+ readonly provision: 'create' | 'refuse'
82
+ }
83
+
84
+ /** The account a completed sign-in belongs to. */
85
+ export interface CompletedSignInAccount {
86
+ readonly id: string
87
+ readonly email: string
88
+ readonly name: string
89
+ readonly emailVerified: boolean
90
+ }
91
+
92
+ export interface CompletedSignIn {
93
+ readonly account: CompletedSignInAccount
94
+ /** True when this sign-in provisioned the account rather than finding it. */
95
+ readonly created: boolean
96
+ readonly activeWorkspaceId: string | null
97
+ }
98
+
99
+ /**
100
+ * Completes a sign-in. Takes the Hono context because writing the session
101
+ * cookie on it is the point.
102
+ */
103
+ export type ExternalSignInHandler = (
104
+ context: Context,
105
+ identity: VerifiedIdentity,
106
+ ) => Promise<CompletedSignIn>
107
+
61
108
  /**
62
109
  * What a module gets to build with, beyond its own contributions.
63
110
  *
@@ -119,6 +166,28 @@ export interface ModuleContext extends ModuleServices {
119
166
  * delegates to the provider `email.provider` picked.
120
167
  */
121
168
  readonly email: EmailSender
169
+ /**
170
+ * Installs the one implementation of external sign-in. Core's `auth` module
171
+ * calls this; a second caller fails boot.
172
+ *
173
+ * The same shape as `provideEmailSender`: a capability only one module owns,
174
+ * reached by every module through a proxy, so registration order does not
175
+ * matter to a consumer.
176
+ */
177
+ provideExternalSignIn(handler: ExternalSignInHandler): void
178
+ /**
179
+ * Completes a sign-in for an identity this module already verified: finds or
180
+ * provisions the account, issues a session, and writes the session cookie on
181
+ * `context`.
182
+ *
183
+ * The alternative is a module writing core's `sessions` table itself, which
184
+ * ties it to core's token hashing, cookie flags and expiry with nothing
185
+ * keeping the two in step (`modules.md`).
186
+ *
187
+ * @throws ExternalSignInError when the identity is unverified, or unknown and
188
+ * the module asked for `provision: 'refuse'`.
189
+ */
190
+ completeExternalSignIn(context: Context, identity: VerifiedIdentity): Promise<CompletedSignIn>
122
191
  /**
123
192
  * Registers routes that mount under `/v1/public`, take no credentials, and
124
193
  * answer cross-origin requests from any site.