@kelpie/server 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ids.d.ts +11 -0
- package/dist/lib/ids.d.ts.map +1 -1
- package/dist/lib/ids.js +11 -0
- package/dist/lib/ids.js.map +1 -1
- package/dist/modules/activities/repository.d.ts.map +1 -1
- package/dist/modules/activities/repository.js +19 -20
- package/dist/modules/activities/repository.js.map +1 -1
- package/dist/modules/activities/wording.d.ts +12 -0
- package/dist/modules/activities/wording.d.ts.map +1 -1
- package/dist/modules/activities/wording.js +16 -0
- package/dist/modules/activities/wording.js.map +1 -1
- package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
- package/dist/modules/agent-tasks/catalog.js +62 -0
- package/dist/modules/agent-tasks/catalog.js.map +1 -1
- package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
- package/dist/modules/agent-tasks/resolve.js +42 -9
- package/dist/modules/agent-tasks/resolve.js.map +1 -1
- package/dist/modules/agent-tasks/routes.d.ts +2 -0
- package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
- package/dist/modules/attachedRecords.d.ts +6 -1
- package/dist/modules/attachedRecords.d.ts.map +1 -1
- package/dist/modules/attachedRecords.js +15 -1
- package/dist/modules/attachedRecords.js.map +1 -1
- package/dist/modules/companies/index.d.ts.map +1 -1
- package/dist/modules/companies/index.js +3 -1
- package/dist/modules/companies/index.js.map +1 -1
- package/dist/modules/companies/routes.d.ts +14 -0
- package/dist/modules/companies/routes.d.ts.map +1 -1
- package/dist/modules/companies/routes.js +7 -0
- package/dist/modules/companies/routes.js.map +1 -1
- package/dist/modules/companies/schema.d.ts +20 -0
- package/dist/modules/companies/schema.d.ts.map +1 -1
- package/dist/modules/companies/schema.js +6 -1
- package/dist/modules/companies/schema.js.map +1 -1
- package/dist/modules/companies/service.d.ts +5 -0
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +24 -12
- package/dist/modules/companies/service.js.map +1 -1
- package/dist/modules/consent-purposes/capabilities.d.ts +7 -0
- package/dist/modules/consent-purposes/capabilities.d.ts.map +1 -0
- package/dist/modules/consent-purposes/capabilities.js +10 -0
- package/dist/modules/consent-purposes/capabilities.js.map +1 -0
- package/dist/modules/consent-purposes/events.d.ts +38 -0
- package/dist/modules/consent-purposes/events.d.ts.map +1 -0
- package/dist/modules/consent-purposes/events.js +17 -0
- package/dist/modules/consent-purposes/events.js.map +1 -0
- package/dist/modules/consent-purposes/index.d.ts +13 -0
- package/dist/modules/consent-purposes/index.d.ts.map +1 -0
- package/dist/modules/consent-purposes/index.js +41 -0
- package/dist/modules/consent-purposes/index.js.map +1 -0
- package/dist/modules/consent-purposes/repository.d.ts +21 -0
- package/dist/modules/consent-purposes/repository.d.ts.map +1 -0
- package/dist/modules/consent-purposes/repository.js +98 -0
- package/dist/modules/consent-purposes/repository.js.map +1 -0
- package/dist/modules/consent-purposes/routes.d.ts +39 -0
- package/dist/modules/consent-purposes/routes.d.ts.map +1 -0
- package/dist/modules/consent-purposes/routes.js +79 -0
- package/dist/modules/consent-purposes/routes.js.map +1 -0
- package/dist/modules/consent-purposes/schema.d.ts +175 -0
- package/dist/modules/consent-purposes/schema.d.ts.map +1 -0
- package/dist/modules/consent-purposes/schema.js +35 -0
- package/dist/modules/consent-purposes/schema.js.map +1 -0
- package/dist/modules/consent-purposes/service.d.ts +50 -0
- package/dist/modules/consent-purposes/service.d.ts.map +1 -0
- package/dist/modules/consent-purposes/service.js +263 -0
- package/dist/modules/consent-purposes/service.js.map +1 -0
- package/dist/modules/consent-purposes/starters.d.ts +17 -0
- package/dist/modules/consent-purposes/starters.d.ts.map +1 -0
- package/dist/modules/consent-purposes/starters.js +15 -0
- package/dist/modules/consent-purposes/starters.js.map +1 -0
- package/dist/modules/consent-purposes/tools.d.ts +4 -0
- package/dist/modules/consent-purposes/tools.d.ts.map +1 -0
- package/dist/modules/consent-purposes/tools.js +29 -0
- package/dist/modules/consent-purposes/tools.js.map +1 -0
- package/dist/modules/core.d.ts.map +1 -1
- package/dist/modules/core.js +10 -0
- package/dist/modules/core.js.map +1 -1
- package/dist/modules/custom-fields/capabilities.d.ts +12 -0
- package/dist/modules/custom-fields/capabilities.d.ts.map +1 -0
- package/dist/modules/custom-fields/capabilities.js +15 -0
- package/dist/modules/custom-fields/capabilities.js.map +1 -0
- package/dist/modules/custom-fields/events.d.ts +49 -0
- package/dist/modules/custom-fields/events.d.ts.map +1 -0
- package/dist/modules/custom-fields/events.js +25 -0
- package/dist/modules/custom-fields/events.js.map +1 -0
- package/dist/modules/custom-fields/index.d.ts +19 -0
- package/dist/modules/custom-fields/index.d.ts.map +1 -0
- package/dist/modules/custom-fields/index.js +46 -0
- package/dist/modules/custom-fields/index.js.map +1 -0
- package/dist/modules/custom-fields/repository.d.ts +37 -0
- package/dist/modules/custom-fields/repository.d.ts.map +1 -0
- package/dist/modules/custom-fields/repository.js +144 -0
- package/dist/modules/custom-fields/repository.js.map +1 -0
- package/dist/modules/custom-fields/routes.d.ts +44 -0
- package/dist/modules/custom-fields/routes.d.ts.map +1 -0
- package/dist/modules/custom-fields/routes.js +103 -0
- package/dist/modules/custom-fields/routes.js.map +1 -0
- package/dist/modules/custom-fields/schema.d.ts +215 -0
- package/dist/modules/custom-fields/schema.d.ts.map +1 -0
- package/dist/modules/custom-fields/schema.js +43 -0
- package/dist/modules/custom-fields/schema.js.map +1 -0
- package/dist/modules/custom-fields/service.d.ts +57 -0
- package/dist/modules/custom-fields/service.d.ts.map +1 -0
- package/dist/modules/custom-fields/service.js +273 -0
- package/dist/modules/custom-fields/service.js.map +1 -0
- package/dist/modules/custom-fields/tools.d.ts +4 -0
- package/dist/modules/custom-fields/tools.d.ts.map +1 -0
- package/dist/modules/custom-fields/tools.js +38 -0
- package/dist/modules/custom-fields/tools.js.map +1 -0
- package/dist/modules/custom-fields/values.d.ts +49 -0
- package/dist/modules/custom-fields/values.d.ts.map +1 -0
- package/dist/modules/custom-fields/values.js +249 -0
- package/dist/modules/custom-fields/values.js.map +1 -0
- package/dist/modules/custom-fields/wire.d.ts +12 -0
- package/dist/modules/custom-fields/wire.d.ts.map +1 -0
- package/dist/modules/custom-fields/wire.js +30 -0
- package/dist/modules/custom-fields/wire.js.map +1 -0
- package/dist/modules/dashboard/repository.d.ts.map +1 -1
- package/dist/modules/dashboard/repository.js +4 -3
- package/dist/modules/dashboard/repository.js.map +1 -1
- package/dist/modules/deals/index.d.ts +2 -1
- package/dist/modules/deals/index.d.ts.map +1 -1
- package/dist/modules/deals/index.js +5 -2
- package/dist/modules/deals/index.js.map +1 -1
- package/dist/modules/deals/repository.d.ts +0 -16
- package/dist/modules/deals/repository.d.ts.map +1 -1
- package/dist/modules/deals/repository.js +6 -76
- package/dist/modules/deals/repository.js.map +1 -1
- package/dist/modules/deals/routes.d.ts +14 -0
- package/dist/modules/deals/routes.d.ts.map +1 -1
- package/dist/modules/deals/routes.js +7 -0
- package/dist/modules/deals/routes.js.map +1 -1
- package/dist/modules/deals/schema.d.ts +20 -42
- package/dist/modules/deals/schema.d.ts.map +1 -1
- package/dist/modules/deals/schema.js +6 -11
- package/dist/modules/deals/schema.js.map +1 -1
- package/dist/modules/deals/service.d.ts +13 -2
- package/dist/modules/deals/service.d.ts.map +1 -1
- package/dist/modules/deals/service.js +43 -20
- package/dist/modules/deals/service.js.map +1 -1
- package/dist/modules/decisions/repository.d.ts.map +1 -1
- package/dist/modules/decisions/repository.js +2 -0
- package/dist/modules/decisions/repository.js.map +1 -1
- package/dist/modules/decisions/routes.d.ts +1 -0
- package/dist/modules/decisions/routes.d.ts.map +1 -1
- package/dist/modules/enquiries/events.d.ts +44 -0
- package/dist/modules/enquiries/events.d.ts.map +1 -0
- package/dist/modules/enquiries/events.js +19 -0
- package/dist/modules/enquiries/events.js.map +1 -0
- package/dist/modules/enquiries/index.d.ts +13 -0
- package/dist/modules/enquiries/index.d.ts.map +1 -0
- package/dist/modules/enquiries/index.js +44 -0
- package/dist/modules/enquiries/index.js.map +1 -0
- package/dist/modules/enquiries/repository.d.ts +30 -0
- package/dist/modules/enquiries/repository.d.ts.map +1 -0
- package/dist/modules/enquiries/repository.js +94 -0
- package/dist/modules/enquiries/repository.js.map +1 -0
- package/dist/modules/enquiries/routes.d.ts +52 -0
- package/dist/modules/enquiries/routes.d.ts.map +1 -0
- package/dist/modules/enquiries/routes.js +127 -0
- package/dist/modules/enquiries/routes.js.map +1 -0
- package/dist/modules/enquiries/schema.d.ts +290 -0
- package/dist/modules/enquiries/schema.d.ts.map +1 -0
- package/dist/modules/enquiries/schema.js +52 -0
- package/dist/modules/enquiries/schema.js.map +1 -0
- package/dist/modules/enquiries/service.d.ts +85 -0
- package/dist/modules/enquiries/service.d.ts.map +1 -0
- package/dist/modules/enquiries/service.js +370 -0
- package/dist/modules/enquiries/service.js.map +1 -0
- package/dist/modules/enquiries/tools.d.ts +4 -0
- package/dist/modules/enquiries/tools.d.ts.map +1 -0
- package/dist/modules/enquiries/tools.js +50 -0
- package/dist/modules/enquiries/tools.js.map +1 -0
- package/dist/modules/eventCatalogs.d.ts +3 -0
- package/dist/modules/eventCatalogs.d.ts.map +1 -1
- package/dist/modules/eventCatalogs.js +3 -0
- package/dist/modules/eventCatalogs.js.map +1 -1
- package/dist/modules/forms/embed.d.ts +20 -6
- package/dist/modules/forms/embed.d.ts.map +1 -1
- package/dist/modules/forms/embed.js +359 -43
- package/dist/modules/forms/embed.js.map +1 -1
- package/dist/modules/forms/events.d.ts +20 -7
- package/dist/modules/forms/events.d.ts.map +1 -1
- package/dist/modules/forms/events.js +20 -2
- package/dist/modules/forms/events.js.map +1 -1
- package/dist/modules/forms/fields.d.ts +14 -1
- package/dist/modules/forms/fields.d.ts.map +1 -1
- package/dist/modules/forms/fields.js +87 -3
- package/dist/modules/forms/fields.js.map +1 -1
- package/dist/modules/forms/index.d.ts.map +1 -1
- package/dist/modules/forms/index.js +12 -1
- package/dist/modules/forms/index.js.map +1 -1
- package/dist/modules/forms/mapping.d.ts +62 -5
- package/dist/modules/forms/mapping.d.ts.map +1 -1
- package/dist/modules/forms/mapping.js +139 -5
- package/dist/modules/forms/mapping.js.map +1 -1
- package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
- package/dist/modules/forms/publicRoutes.js +29 -1
- package/dist/modules/forms/publicRoutes.js.map +1 -1
- package/dist/modules/forms/repository.d.ts +31 -0
- package/dist/modules/forms/repository.d.ts.map +1 -1
- package/dist/modules/forms/repository.js +90 -1
- package/dist/modules/forms/repository.js.map +1 -1
- package/dist/modules/forms/routes.d.ts +83 -1
- package/dist/modules/forms/routes.d.ts.map +1 -1
- package/dist/modules/forms/routes.js +185 -2
- package/dist/modules/forms/routes.js.map +1 -1
- package/dist/modules/forms/schema.d.ts +672 -1
- package/dist/modules/forms/schema.d.ts.map +1 -1
- package/dist/modules/forms/schema.js +146 -3
- package/dist/modules/forms/schema.js.map +1 -1
- package/dist/modules/forms/service.d.ts +54 -1
- package/dist/modules/forms/service.d.ts.map +1 -1
- package/dist/modules/forms/service.js +338 -28
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/submission.d.ts +15 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +418 -40
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/import-export/drafts.d.ts +10 -0
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +16 -2
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/exportRows.d.ts +7 -4
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +20 -5
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts +12 -1
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +29 -2
- package/dist/modules/import-export/plan.js.map +1 -1
- package/dist/modules/import-export/presets.d.ts.map +1 -1
- package/dist/modules/import-export/presets.js +10 -0
- package/dist/modules/import-export/presets.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +11 -1
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +42 -9
- package/dist/modules/import-export/repository.js.map +1 -1
- package/dist/modules/import-export/routes.d.ts.map +1 -1
- package/dist/modules/import-export/routes.js +4 -0
- package/dist/modules/import-export/routes.js.map +1 -1
- package/dist/modules/import-export/schema.d.ts +17 -0
- package/dist/modules/import-export/schema.d.ts.map +1 -1
- package/dist/modules/import-export/schema.js +11 -0
- package/dist/modules/import-export/schema.js.map +1 -1
- package/dist/modules/import-export/service.d.ts +6 -0
- package/dist/modules/import-export/service.d.ts.map +1 -1
- package/dist/modules/import-export/service.js +14 -2
- package/dist/modules/import-export/service.js.map +1 -1
- package/dist/modules/import-export/streams.d.ts.map +1 -1
- package/dist/modules/import-export/streams.js +3 -3
- package/dist/modules/import-export/streams.js.map +1 -1
- package/dist/modules/import-export/tools.d.ts.map +1 -1
- package/dist/modules/import-export/tools.js +8 -0
- package/dist/modules/import-export/tools.js.map +1 -1
- package/dist/modules/import-export/validation.d.ts.map +1 -1
- package/dist/modules/import-export/validation.js +22 -1
- package/dist/modules/import-export/validation.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +37 -4
- package/dist/modules/import-export/writes.js.map +1 -1
- package/dist/modules/lists/index.d.ts +38 -0
- package/dist/modules/lists/index.d.ts.map +1 -1
- package/dist/modules/lists/index.js +27 -0
- package/dist/modules/lists/index.js.map +1 -1
- package/dist/modules/lists/repository.d.ts +26 -0
- package/dist/modules/lists/repository.d.ts.map +1 -1
- package/dist/modules/lists/repository.js +32 -0
- package/dist/modules/lists/repository.js.map +1 -1
- package/dist/modules/lists/routes.d.ts +4 -0
- package/dist/modules/lists/routes.d.ts.map +1 -1
- package/dist/modules/lists/routes.js +8 -0
- package/dist/modules/lists/routes.js.map +1 -1
- package/dist/modules/lists/schema.d.ts +17 -0
- package/dist/modules/lists/schema.d.ts.map +1 -1
- package/dist/modules/lists/schema.js +10 -0
- package/dist/modules/lists/schema.js.map +1 -1
- package/dist/modules/lists/service.d.ts +14 -2
- package/dist/modules/lists/service.d.ts.map +1 -1
- package/dist/modules/lists/service.js +55 -7
- package/dist/modules/lists/service.js.map +1 -1
- package/dist/modules/mcp/index.d.ts.map +1 -1
- package/dist/modules/mcp/index.js +5 -0
- package/dist/modules/mcp/index.js.map +1 -1
- package/dist/modules/notes/routes.d.ts +1 -0
- package/dist/modules/notes/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/index.d.ts.map +1 -1
- package/dist/modules/opportunities/index.js +3 -1
- package/dist/modules/opportunities/index.js.map +1 -1
- package/dist/modules/opportunities/repository.d.ts +2 -0
- package/dist/modules/opportunities/repository.d.ts.map +1 -1
- package/dist/modules/opportunities/repository.js +4 -0
- package/dist/modules/opportunities/repository.js.map +1 -1
- package/dist/modules/opportunities/routes.d.ts +16 -0
- package/dist/modules/opportunities/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/routes.js +13 -0
- package/dist/modules/opportunities/routes.js.map +1 -1
- package/dist/modules/opportunities/schema.d.ts +20 -0
- package/dist/modules/opportunities/schema.d.ts.map +1 -1
- package/dist/modules/opportunities/schema.js +6 -1
- package/dist/modules/opportunities/schema.js.map +1 -1
- package/dist/modules/opportunities/service.d.ts +20 -3
- package/dist/modules/opportunities/service.d.ts.map +1 -1
- package/dist/modules/opportunities/service.js +99 -18
- package/dist/modules/opportunities/service.js.map +1 -1
- package/dist/modules/opportunities/tools.d.ts.map +1 -1
- package/dist/modules/opportunities/tools.js +2 -0
- package/dist/modules/opportunities/tools.js.map +1 -1
- package/dist/modules/partnerships/index.d.ts.map +1 -1
- package/dist/modules/partnerships/index.js +3 -1
- package/dist/modules/partnerships/index.js.map +1 -1
- package/dist/modules/partnerships/repository.d.ts +0 -17
- package/dist/modules/partnerships/repository.d.ts.map +1 -1
- package/dist/modules/partnerships/repository.js +6 -82
- package/dist/modules/partnerships/repository.js.map +1 -1
- package/dist/modules/partnerships/routes.d.ts +14 -0
- package/dist/modules/partnerships/routes.d.ts.map +1 -1
- package/dist/modules/partnerships/routes.js +7 -0
- package/dist/modules/partnerships/routes.js.map +1 -1
- package/dist/modules/partnerships/schema.d.ts +20 -41
- package/dist/modules/partnerships/schema.d.ts.map +1 -1
- package/dist/modules/partnerships/schema.js +6 -10
- package/dist/modules/partnerships/schema.js.map +1 -1
- package/dist/modules/partnerships/service.d.ts +11 -1
- package/dist/modules/partnerships/service.d.ts.map +1 -1
- package/dist/modules/partnerships/service.js +43 -20
- package/dist/modules/partnerships/service.js.map +1 -1
- package/dist/modules/people/consentHydration.d.ts +26 -0
- package/dist/modules/people/consentHydration.d.ts.map +1 -0
- package/dist/modules/people/consentHydration.js +100 -0
- package/dist/modules/people/consentHydration.js.map +1 -0
- package/dist/modules/people/index.d.ts.map +1 -1
- package/dist/modules/people/index.js +3 -1
- package/dist/modules/people/index.js.map +1 -1
- package/dist/modules/people/personConsentWrites.d.ts +40 -0
- package/dist/modules/people/personConsentWrites.d.ts.map +1 -0
- package/dist/modules/people/personConsentWrites.js +98 -0
- package/dist/modules/people/personConsentWrites.js.map +1 -0
- package/dist/modules/people/repository.d.ts.map +1 -1
- package/dist/modules/people/repository.js +5 -1
- package/dist/modules/people/repository.js.map +1 -1
- package/dist/modules/people/routes.d.ts +57 -4
- package/dist/modules/people/routes.d.ts.map +1 -1
- package/dist/modules/people/routes.js +104 -5
- package/dist/modules/people/routes.js.map +1 -1
- package/dist/modules/people/schema.d.ts +366 -1
- package/dist/modules/people/schema.d.ts.map +1 -1
- package/dist/modules/people/schema.js +92 -2
- package/dist/modules/people/schema.js.map +1 -1
- package/dist/modules/people/service.d.ts +30 -1
- package/dist/modules/people/service.d.ts.map +1 -1
- package/dist/modules/people/service.js +115 -38
- package/dist/modules/people/service.js.map +1 -1
- package/dist/modules/people/tools.d.ts.map +1 -1
- package/dist/modules/people/tools.js +4 -1
- package/dist/modules/people/tools.js.map +1 -1
- package/dist/modules/personLinks.d.ts +79 -0
- package/dist/modules/personLinks.d.ts.map +1 -0
- package/dist/modules/personLinks.js +155 -0
- package/dist/modules/personLinks.js.map +1 -0
- package/dist/modules/pipelines/routes.d.ts +1 -0
- package/dist/modules/pipelines/routes.d.ts.map +1 -1
- package/dist/modules/plans/routes.d.ts +1 -0
- package/dist/modules/plans/routes.d.ts.map +1 -1
- package/dist/modules/raises/index.d.ts.map +1 -1
- package/dist/modules/raises/index.js +3 -1
- package/dist/modules/raises/index.js.map +1 -1
- package/dist/modules/raises/repository.d.ts +0 -17
- package/dist/modules/raises/repository.d.ts.map +1 -1
- package/dist/modules/raises/repository.js +6 -77
- package/dist/modules/raises/repository.js.map +1 -1
- package/dist/modules/raises/routes.d.ts +14 -0
- package/dist/modules/raises/routes.d.ts.map +1 -1
- package/dist/modules/raises/routes.js +7 -0
- package/dist/modules/raises/routes.js.map +1 -1
- package/dist/modules/raises/schema.d.ts +20 -41
- package/dist/modules/raises/schema.d.ts.map +1 -1
- package/dist/modules/raises/schema.js +6 -10
- package/dist/modules/raises/schema.js.map +1 -1
- package/dist/modules/raises/service.d.ts +11 -1
- package/dist/modules/raises/service.d.ts.map +1 -1
- package/dist/modules/raises/service.js +41 -18
- package/dist/modules/raises/service.js.map +1 -1
- package/dist/modules/recordTargets.d.ts.map +1 -1
- package/dist/modules/recordTargets.js +2 -0
- package/dist/modules/recordTargets.js.map +1 -1
- package/dist/modules/references.d.ts +10 -0
- package/dist/modules/references.d.ts.map +1 -1
- package/dist/modules/references.js +27 -4
- package/dist/modules/references.js.map +1 -1
- package/dist/modules/sample-data/fixture.d.ts +21 -0
- package/dist/modules/sample-data/fixture.d.ts.map +1 -1
- package/dist/modules/sample-data/fixture.js +40 -0
- package/dist/modules/sample-data/fixture.js.map +1 -1
- package/dist/modules/sample-data/index.d.ts.map +1 -1
- package/dist/modules/sample-data/index.js +1 -0
- package/dist/modules/sample-data/index.js.map +1 -1
- package/dist/modules/sample-data/routes.d.ts.map +1 -1
- package/dist/modules/sample-data/routes.js +1 -0
- package/dist/modules/sample-data/routes.js.map +1 -1
- package/dist/modules/sample-data/service.d.ts +1 -0
- package/dist/modules/sample-data/service.d.ts.map +1 -1
- package/dist/modules/sample-data/service.js +77 -8
- package/dist/modules/sample-data/service.js.map +1 -1
- package/dist/modules/search/index.d.ts +1 -1
- package/dist/modules/search/index.d.ts.map +1 -1
- package/dist/modules/search/index.js +2 -1
- package/dist/modules/search/index.js.map +1 -1
- package/dist/modules/search/repository.d.ts +1 -0
- package/dist/modules/search/repository.d.ts.map +1 -1
- package/dist/modules/search/repository.js +23 -0
- package/dist/modules/search/repository.js.map +1 -1
- package/dist/modules/search/service.d.ts +3 -3
- package/dist/modules/search/service.d.ts.map +1 -1
- package/dist/modules/search/service.js +5 -4
- package/dist/modules/search/service.js.map +1 -1
- package/dist/modules/stagedRecords.d.ts +3 -3
- package/dist/modules/stagedRecords.d.ts.map +1 -1
- package/dist/modules/stagedRecords.js +9 -0
- package/dist/modules/stagedRecords.js.map +1 -1
- package/dist/modules/webhooks/payloads.d.ts.map +1 -1
- package/dist/modules/webhooks/payloads.js +15 -2
- package/dist/modules/webhooks/payloads.js.map +1 -1
- package/dist/modules/workspace/repository.d.ts +2 -0
- package/dist/modules/workspace/repository.d.ts.map +1 -1
- package/dist/modules/workspace/repository.js +7 -0
- package/dist/modules/workspace/repository.js.map +1 -1
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +10 -0
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/modules/workspace/starters.d.ts.map +1 -1
- package/dist/modules/workspace/starters.js +5 -0
- package/dist/modules/workspace/starters.js.map +1 -1
- package/dist/runtime/events.d.ts +1 -1
- package/dist/runtime/events.d.ts.map +1 -1
- package/dist/runtime/events.js +1 -0
- package/dist/runtime/events.js.map +1 -1
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/database.d.ts +5 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js +81 -10
- package/dist/testing/database.js.map +1 -1
- package/migrations/0024_third_king_cobra.sql +46 -0
- package/migrations/0025_worthless_chimera.sql +3 -0
- package/migrations/0026_late_aqueduct.sql +46 -0
- package/migrations/0027_brainy_silver_sable.sql +3 -0
- package/migrations/0028_freezing_scrambler.sql +19 -0
- package/migrations/0029_custom_fields.sql +26 -0
- package/migrations/0030_enquiries.sql +79 -0
- package/migrations/0031_consent.sql +45 -0
- package/migrations/0032_form_field_statement.sql +1 -0
- package/migrations/0033_form_field_consent_purpose_ids.sql +5 -0
- package/migrations/0034_drop_form_field_consent_purpose_id.sql +1 -0
- package/migrations/0035_form_field_consent_purpose_labels.sql +1 -0
- package/migrations/0036_form_field_notice_type.sql +2 -0
- package/migrations/meta/0024_snapshot.json +5516 -0
- package/migrations/meta/0025_snapshot.json +5336 -0
- package/migrations/meta/0026_snapshot.json +5710 -0
- package/migrations/meta/0027_snapshot.json +5716 -0
- package/migrations/meta/0028_snapshot.json +5740 -0
- package/migrations/meta/0029_snapshot.json +5935 -0
- package/migrations/meta/0030_snapshot.json +6245 -0
- package/migrations/meta/0031_snapshot.json +6572 -0
- package/migrations/meta/0032_snapshot.json +6578 -0
- package/migrations/meta/0033_snapshot.json +6572 -0
- package/migrations/meta/0034_snapshot.json +6566 -0
- package/migrations/meta/0035_snapshot.json +6573 -0
- package/migrations/meta/0036_snapshot.json +6573 -0
- package/migrations/meta/_journal.json +91 -0
- package/package.json +2 -2
- package/src/index.ts +6 -0
- package/src/lib/ids.ts +11 -0
- package/src/modules/activities/repository.ts +22 -23
- package/src/modules/activities/wording.ts +18 -0
- package/src/modules/agent-tasks/catalog.ts +63 -0
- package/src/modules/agent-tasks/resolve.ts +64 -24
- package/src/modules/attachedRecords.ts +29 -2
- package/src/modules/companies/index.ts +3 -1
- package/src/modules/companies/routes.ts +7 -0
- package/src/modules/companies/schema.ts +7 -1
- package/src/modules/companies/service.ts +48 -13
- package/src/modules/consent-purposes/capabilities.ts +12 -0
- package/src/modules/consent-purposes/events.ts +38 -0
- package/src/modules/consent-purposes/index.ts +48 -0
- package/src/modules/consent-purposes/repository.ts +163 -0
- package/src/modules/consent-purposes/routes.ts +122 -0
- package/src/modules/consent-purposes/schema.ts +46 -0
- package/src/modules/consent-purposes/service.ts +423 -0
- package/src/modules/consent-purposes/starters.ts +32 -0
- package/src/modules/consent-purposes/tools.ts +44 -0
- package/src/modules/core.ts +10 -0
- package/src/modules/custom-fields/capabilities.ts +17 -0
- package/src/modules/custom-fields/events.ts +51 -0
- package/src/modules/custom-fields/index.ts +61 -0
- package/src/modules/custom-fields/repository.ts +225 -0
- package/src/modules/custom-fields/routes.ts +155 -0
- package/src/modules/custom-fields/schema.ts +61 -0
- package/src/modules/custom-fields/service.ts +439 -0
- package/src/modules/custom-fields/tools.ts +53 -0
- package/src/modules/custom-fields/values.ts +352 -0
- package/src/modules/custom-fields/wire.ts +32 -0
- package/src/modules/dashboard/repository.ts +4 -3
- package/src/modules/deals/index.ts +5 -2
- package/src/modules/deals/repository.ts +6 -106
- package/src/modules/deals/routes.ts +7 -0
- package/src/modules/deals/schema.ts +7 -15
- package/src/modules/deals/service.ts +92 -23
- package/src/modules/decisions/repository.ts +2 -0
- package/src/modules/enquiries/events.ts +45 -0
- package/src/modules/enquiries/index.ts +50 -0
- package/src/modules/enquiries/repository.ts +164 -0
- package/src/modules/enquiries/routes.ts +172 -0
- package/src/modules/enquiries/schema.ts +59 -0
- package/src/modules/enquiries/service.ts +644 -0
- package/src/modules/enquiries/tools.ts +66 -0
- package/src/modules/eventCatalogs.ts +3 -0
- package/src/modules/forms/embed.ts +391 -44
- package/src/modules/forms/events.ts +30 -2
- package/src/modules/forms/fields.ts +102 -2
- package/src/modules/forms/index.ts +12 -1
- package/src/modules/forms/mapping.ts +183 -6
- package/src/modules/forms/publicRoutes.ts +43 -1
- package/src/modules/forms/repository.ts +162 -1
- package/src/modules/forms/routes.ts +212 -2
- package/src/modules/forms/schema.ts +166 -4
- package/src/modules/forms/service.ts +565 -41
- package/src/modules/forms/submission.ts +718 -44
- package/src/modules/import-export/drafts.ts +20 -1
- package/src/modules/import-export/exportRows.ts +21 -5
- package/src/modules/import-export/plan.ts +47 -2
- package/src/modules/import-export/presets.ts +10 -0
- package/src/modules/import-export/repository.ts +73 -8
- package/src/modules/import-export/routes.ts +4 -0
- package/src/modules/import-export/schema.ts +11 -0
- package/src/modules/import-export/service.ts +28 -2
- package/src/modules/import-export/streams.ts +3 -1
- package/src/modules/import-export/tools.ts +10 -0
- package/src/modules/import-export/validation.ts +28 -0
- package/src/modules/import-export/writes.ts +70 -5
- package/src/modules/lists/index.ts +71 -0
- package/src/modules/lists/repository.ts +64 -0
- package/src/modules/lists/routes.ts +8 -0
- package/src/modules/lists/schema.ts +10 -0
- package/src/modules/lists/service.ts +110 -9
- package/src/modules/mcp/index.ts +5 -0
- package/src/modules/opportunities/index.ts +3 -1
- package/src/modules/opportunities/repository.ts +11 -0
- package/src/modules/opportunities/routes.ts +13 -0
- package/src/modules/opportunities/schema.ts +7 -1
- package/src/modules/opportunities/service.ts +188 -22
- package/src/modules/opportunities/tools.ts +2 -0
- package/src/modules/partnerships/index.ts +3 -1
- package/src/modules/partnerships/repository.ts +6 -117
- package/src/modules/partnerships/routes.ts +7 -0
- package/src/modules/partnerships/schema.ts +7 -14
- package/src/modules/partnerships/service.ts +93 -22
- package/src/modules/people/consentHydration.ts +167 -0
- package/src/modules/people/index.ts +3 -1
- package/src/modules/people/personConsentWrites.ts +177 -0
- package/src/modules/people/repository.ts +5 -0
- package/src/modules/people/routes.ts +127 -18
- package/src/modules/people/schema.ts +109 -3
- package/src/modules/people/service.ts +186 -40
- package/src/modules/people/tools.ts +5 -1
- package/src/modules/personLinks.ts +278 -0
- package/src/modules/raises/index.ts +3 -1
- package/src/modules/raises/repository.ts +6 -107
- package/src/modules/raises/routes.ts +7 -0
- package/src/modules/raises/schema.ts +7 -14
- package/src/modules/raises/service.ts +91 -20
- package/src/modules/recordTargets.ts +2 -0
- package/src/modules/references.ts +43 -4
- package/src/modules/sample-data/fixture.ts +63 -0
- package/src/modules/sample-data/index.ts +1 -0
- package/src/modules/sample-data/routes.ts +1 -0
- package/src/modules/sample-data/service.ts +97 -8
- package/src/modules/search/index.ts +2 -1
- package/src/modules/search/repository.ts +33 -1
- package/src/modules/search/service.ts +7 -5
- package/src/modules/stagedRecords.ts +18 -3
- package/src/modules/webhooks/payloads.ts +20 -2
- package/src/modules/workspace/repository.ts +12 -0
- package/src/modules/workspace/service.ts +14 -0
- package/src/modules/workspace/starters.ts +5 -0
- package/src/runtime/events.ts +1 -0
- package/src/schema/index.ts +3 -0
- package/src/testing/database.ts +97 -11
|
@@ -7,11 +7,14 @@ import type { ActivityRecorder } from '../activities/recorder.ts'
|
|
|
7
7
|
import { describeCreationVia, describeLink, describeUpdateVia } from '../activities/wording.ts'
|
|
8
8
|
import type { Actor } from '../auth/actor.ts'
|
|
9
9
|
import * as companyRepository from '../companies/repository.ts'
|
|
10
|
+
import * as consentPurposesRepository from '../consent-purposes/repository.ts'
|
|
10
11
|
import * as dealRepository from '../deals/repository.ts'
|
|
11
12
|
import * as peopleRepository from '../people/repository.ts'
|
|
13
|
+
import { upsertPersonConsent } from '../people/personConsentWrites.ts'
|
|
14
|
+
import * as personLinks from '../personLinks.ts'
|
|
12
15
|
import * as positionRepository from '../positions/repository.ts'
|
|
13
16
|
import { IMPORT_DEAL_CURRENCY, NEW_COMPANY_DEFAULTS, NEW_PERSON_DEFAULTS } from './drafts.ts'
|
|
14
|
-
import type { ImportWrite, PlannedAffiliation, RowPlan } from './plan.ts'
|
|
17
|
+
import type { ImportConsentGrant, ImportWrite, PlannedAffiliation, RowPlan } from './plan.ts'
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Applying one planned row: the insert or update, and the timeline entry that
|
|
@@ -220,6 +223,9 @@ async function writePerson(
|
|
|
220
223
|
tags: write.draft.tags === undefined ? undefined : [...write.draft.tags],
|
|
221
224
|
id: dependencies.createId('person'),
|
|
222
225
|
workspaceId,
|
|
226
|
+
// `name` is not a required column any more; the People row check is what
|
|
227
|
+
// guarantees one, from the row's own `name` or composed from its first and
|
|
228
|
+
// last name cells. A row reaching here without one never passed validation.
|
|
223
229
|
name: write.draft.name ?? '',
|
|
224
230
|
})
|
|
225
231
|
|
|
@@ -228,6 +234,10 @@ async function writePerson(
|
|
|
228
234
|
? []
|
|
229
235
|
: await applyAffiliation(dependencies, created.id, write.affiliation)
|
|
230
236
|
|
|
237
|
+
if (write.consent !== undefined) {
|
|
238
|
+
await applyImportConsent(dependencies, created.id, write.consent)
|
|
239
|
+
}
|
|
240
|
+
|
|
231
241
|
return { recordId: created.id, objectType: 'person', changedFields: [], sideRecords }
|
|
232
242
|
}
|
|
233
243
|
|
|
@@ -257,9 +267,51 @@ async function writePerson(
|
|
|
257
267
|
? []
|
|
258
268
|
: await applyAffiliation(dependencies, id, write.affiliation)
|
|
259
269
|
|
|
270
|
+
if (write.consent !== undefined) {
|
|
271
|
+
await applyImportConsent(dependencies, id, write.consent)
|
|
272
|
+
}
|
|
273
|
+
|
|
260
274
|
return { recordId: id, objectType: 'person', changedFields, sideRecords }
|
|
261
275
|
}
|
|
262
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Applies the row's consent grant against the job's purpose. The purpose is
|
|
279
|
+
* looked up once per call rather than cached across rows — a commit runs one
|
|
280
|
+
* transaction and one row at a time — so the round trip is small and stays
|
|
281
|
+
* consistent with the current transaction's view.
|
|
282
|
+
*/
|
|
283
|
+
async function applyImportConsent(
|
|
284
|
+
dependencies: WriteDependencies,
|
|
285
|
+
personId: string,
|
|
286
|
+
consent: ImportConsentGrant,
|
|
287
|
+
): Promise<void> {
|
|
288
|
+
const [purpose] = await consentPurposesRepository.listPurposesByIds(
|
|
289
|
+
dependencies.tx,
|
|
290
|
+
dependencies.workspaceId,
|
|
291
|
+
[consent.purposeId],
|
|
292
|
+
)
|
|
293
|
+
if (purpose === undefined) return
|
|
294
|
+
const notedAt = consent.notedAt === null ? dependencies.now : new Date(`${consent.notedAt}T00:00:00Z`)
|
|
295
|
+
await upsertPersonConsent(
|
|
296
|
+
dependencies.tx,
|
|
297
|
+
dependencies.workspaceId,
|
|
298
|
+
personId,
|
|
299
|
+
consent.purposeId,
|
|
300
|
+
purpose.slug,
|
|
301
|
+
purpose.label,
|
|
302
|
+
consent.status,
|
|
303
|
+
'import',
|
|
304
|
+
notedAt,
|
|
305
|
+
)
|
|
306
|
+
await dependencies.recordActivity(dependencies.tx, dependencies.workspaceId, dependencies.actor, {
|
|
307
|
+
targetType: 'person',
|
|
308
|
+
targetId: personId,
|
|
309
|
+
kind: 'updated',
|
|
310
|
+
action: `${consent.status === 'granted' ? 'granted' : 'withdrew'} ${purpose.label} consent via ${dependencies.sourceName}`,
|
|
311
|
+
detail: null,
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
|
|
263
315
|
/**
|
|
264
316
|
* A Position's only writable field is its title, so an update is a rename.
|
|
265
317
|
*
|
|
@@ -318,12 +370,19 @@ async function reconcileDealPeople(
|
|
|
318
370
|
dealId: string,
|
|
319
371
|
personIds: readonly string[],
|
|
320
372
|
): Promise<boolean> {
|
|
321
|
-
const
|
|
373
|
+
const target = { targetType: 'deal' as const, targetId: dealId }
|
|
374
|
+
const current = await personLinks.listPersonIds(dependencies.tx, dependencies.workspaceId, target)
|
|
322
375
|
const added = personIds.filter((personId) => !current.includes(personId))
|
|
323
376
|
const removed = current.filter((personId) => !personIds.includes(personId))
|
|
324
377
|
|
|
325
|
-
await
|
|
326
|
-
|
|
378
|
+
await personLinks.linkPeople(
|
|
379
|
+
dependencies.tx,
|
|
380
|
+
dependencies.createId,
|
|
381
|
+
dependencies.workspaceId,
|
|
382
|
+
target,
|
|
383
|
+
added,
|
|
384
|
+
)
|
|
385
|
+
await personLinks.unlinkPeople(dependencies.tx, dependencies.workspaceId, target, removed)
|
|
327
386
|
|
|
328
387
|
return added.length > 0 || removed.length > 0
|
|
329
388
|
}
|
|
@@ -352,7 +411,13 @@ async function writeDeal(
|
|
|
352
411
|
// the same way, and no CSV column carries one.
|
|
353
412
|
currency: IMPORT_DEAL_CURRENCY,
|
|
354
413
|
})
|
|
355
|
-
await
|
|
414
|
+
await personLinks.linkPeople(
|
|
415
|
+
tx,
|
|
416
|
+
dependencies.createId,
|
|
417
|
+
workspaceId,
|
|
418
|
+
{ targetType: 'deal', targetId: id },
|
|
419
|
+
write.personIds,
|
|
420
|
+
)
|
|
356
421
|
|
|
357
422
|
return { recordId: id, objectType: 'deal', changedFields: [] }
|
|
358
423
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import type { EventActor } from '@kelpie/schemas'
|
|
2
|
+
|
|
3
|
+
import type { Database } from '../../lib/database.ts'
|
|
1
4
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
5
|
+
import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
6
|
+
import type { RecordTargetType } from '../recordTargets.ts'
|
|
2
7
|
import { listsEvents } from './events.ts'
|
|
8
|
+
import * as repository from './repository.ts'
|
|
3
9
|
import { mountListsRoutes } from './routes.ts'
|
|
4
10
|
import * as schema from './schema.ts'
|
|
5
11
|
import { createListsService } from './service.ts'
|
|
@@ -39,3 +45,68 @@ export function createListsModule(migrationsDirectory: string): KelpieModule {
|
|
|
39
45
|
},
|
|
40
46
|
}
|
|
41
47
|
}
|
|
48
|
+
|
|
49
|
+
/** Dependencies a caller outside the lists module already holds. */
|
|
50
|
+
export interface RemoveListMemberByTargetDependencies {
|
|
51
|
+
readonly db: Database
|
|
52
|
+
readonly transaction: TransactionScope
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface RemoveListMemberByTargetInput {
|
|
56
|
+
readonly workspaceId: string
|
|
57
|
+
readonly listId: string
|
|
58
|
+
readonly targetType: RecordTargetType
|
|
59
|
+
readonly targetId: string
|
|
60
|
+
/**
|
|
61
|
+
* The event actor to stamp on `lists.member.removed`. An integration webhook
|
|
62
|
+
* that has no signed-in user passes `{ kind: 'system' }`; a module acting on
|
|
63
|
+
* behalf of a user passes `{ kind: 'user', id: userId }`.
|
|
64
|
+
*/
|
|
65
|
+
readonly actor: EventActor
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Removes a person (or any record) from a list by target, from outside the lists module.
|
|
70
|
+
*
|
|
71
|
+
* The path an integration takes when a signal from an external system removes
|
|
72
|
+
* membership — a Resend unsubscribe removing the person from every mapped list,
|
|
73
|
+
* a compliance sweep evicting a record — and there is no signed-in user to
|
|
74
|
+
* hang a normal `removeMember(actor, listId, id)` call on. Every safeguard the
|
|
75
|
+
* REST route enforces (workspace membership, ownership of the list, presence
|
|
76
|
+
* of the member row) is skipped here on purpose: the caller has already
|
|
77
|
+
* decided, and the input is trusted because it comes from another module in
|
|
78
|
+
* the same assembly rather than a request body.
|
|
79
|
+
*
|
|
80
|
+
* @returns `true` if the row was on the list and is now gone (emits
|
|
81
|
+
* `lists.member.removed`), `false` if the target was not a member — a no-op
|
|
82
|
+
* so a delivery redelivered by an at-least-once webhook is safe.
|
|
83
|
+
*/
|
|
84
|
+
export async function removeListMemberByTarget(
|
|
85
|
+
dependencies: RemoveListMemberByTargetDependencies,
|
|
86
|
+
input: RemoveListMemberByTargetInput,
|
|
87
|
+
): Promise<boolean> {
|
|
88
|
+
return dependencies.transaction(
|
|
89
|
+
async ({ tx, events }) => {
|
|
90
|
+
const deleted = await repository.deleteListMemberByTarget(
|
|
91
|
+
tx,
|
|
92
|
+
input.workspaceId,
|
|
93
|
+
input.listId,
|
|
94
|
+
input.targetType,
|
|
95
|
+
input.targetId,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
if (deleted === undefined) {
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
events.emit(
|
|
103
|
+
'lists.member.removed',
|
|
104
|
+
{ type: input.targetType, id: input.targetId },
|
|
105
|
+
{ listId: input.listId },
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
return true
|
|
109
|
+
},
|
|
110
|
+
{ workspaceId: input.workspaceId, actor: input.actor },
|
|
111
|
+
)
|
|
112
|
+
}
|
|
@@ -103,6 +103,36 @@ export async function findList(
|
|
|
103
103
|
return { ...found, memberCount: await countMembers(db, id) }
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Bare list rows for a bulk existence + target-type check, without the
|
|
108
|
+
* member-count round trip `findList` pays for. Used by the forms service to
|
|
109
|
+
* validate `list_ids` at write time in one query rather than N.
|
|
110
|
+
*/
|
|
111
|
+
export interface ListIdRow {
|
|
112
|
+
readonly id: string
|
|
113
|
+
readonly targetType: string
|
|
114
|
+
readonly consentPurposeId: string | null
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function listListsById(
|
|
118
|
+
db: Queryable,
|
|
119
|
+
workspaceId: string,
|
|
120
|
+
ids: readonly string[],
|
|
121
|
+
): Promise<ListIdRow[]> {
|
|
122
|
+
if (ids.length === 0) {
|
|
123
|
+
return []
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return db
|
|
127
|
+
.select({
|
|
128
|
+
id: lists.id,
|
|
129
|
+
targetType: lists.targetType,
|
|
130
|
+
consentPurposeId: lists.consentPurposeId,
|
|
131
|
+
})
|
|
132
|
+
.from(lists)
|
|
133
|
+
.where(and(eq(lists.workspaceId, workspaceId), inArray(lists.id, ids)))
|
|
134
|
+
}
|
|
135
|
+
|
|
106
136
|
async function countMembers(db: Queryable, listId: string): Promise<number> {
|
|
107
137
|
const [row] = await db
|
|
108
138
|
.select({ count: sql<number>`count(*)::int` })
|
|
@@ -240,6 +270,40 @@ export async function deleteListMember(
|
|
|
240
270
|
return deleted.length
|
|
241
271
|
}
|
|
242
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Removes the membership that points at a given target, if one is on the list.
|
|
275
|
+
*
|
|
276
|
+
* The addressed-by-target counterpart to `deleteListMember`, which addresses a
|
|
277
|
+
* row by its own id. An inbound integration webhook (Resend unsubscribe, for
|
|
278
|
+
* example) knows the person, not the list_member row that ties them to a list,
|
|
279
|
+
* and reading the row just to delete it is a round trip that adds nothing.
|
|
280
|
+
*
|
|
281
|
+
* @returns The removed row's id, or undefined if no member of that list points
|
|
282
|
+
* at that target — the same shape a caller wanting to decide whether to emit
|
|
283
|
+
* `lists.member.removed` needs.
|
|
284
|
+
*/
|
|
285
|
+
export async function deleteListMemberByTarget(
|
|
286
|
+
db: Queryable,
|
|
287
|
+
workspaceId: string,
|
|
288
|
+
listId: string,
|
|
289
|
+
targetType: string,
|
|
290
|
+
targetId: string,
|
|
291
|
+
): Promise<{ id: string } | undefined> {
|
|
292
|
+
const [deleted] = await db
|
|
293
|
+
.delete(listMembers)
|
|
294
|
+
.where(
|
|
295
|
+
and(
|
|
296
|
+
eq(listMembers.workspaceId, workspaceId),
|
|
297
|
+
eq(listMembers.listId, listId),
|
|
298
|
+
eq(listMembers.targetType, targetType),
|
|
299
|
+
eq(listMembers.targetId, targetId),
|
|
300
|
+
),
|
|
301
|
+
)
|
|
302
|
+
.returning({ id: listMembers.id })
|
|
303
|
+
|
|
304
|
+
return deleted
|
|
305
|
+
}
|
|
306
|
+
|
|
243
307
|
/** A membership row enriched with the list it points at. */
|
|
244
308
|
export interface MembershipWithList {
|
|
245
309
|
readonly id: string
|
|
@@ -31,12 +31,14 @@ export const createBody = z.strictObject({
|
|
|
31
31
|
name: z.string().min(1),
|
|
32
32
|
target_type: z.enum(RECORD_TARGET_TYPES),
|
|
33
33
|
description: z.string().nullable().default(null),
|
|
34
|
+
consent_purpose_id: z.string().min(1).nullable().default(null),
|
|
34
35
|
})
|
|
35
36
|
|
|
36
37
|
export const updateBody = z
|
|
37
38
|
.strictObject({
|
|
38
39
|
name: z.string().min(1),
|
|
39
40
|
description: z.string().nullable(),
|
|
41
|
+
consent_purpose_id: z.string().min(1).nullable(),
|
|
40
42
|
})
|
|
41
43
|
.partial()
|
|
42
44
|
|
|
@@ -54,6 +56,7 @@ export function toCreateInput(body: z.infer<typeof createBody>): CreateListInput
|
|
|
54
56
|
name: body.name,
|
|
55
57
|
targetType: body.target_type,
|
|
56
58
|
description: body.description,
|
|
59
|
+
consentPurposeId: body.consent_purpose_id,
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -61,6 +64,9 @@ export function toUpdateInput(body: z.infer<typeof updateBody>): UpdateListInput
|
|
|
61
64
|
return {
|
|
62
65
|
...(body.name === undefined ? {} : { name: body.name }),
|
|
63
66
|
...(body.description === undefined ? {} : { description: body.description }),
|
|
67
|
+
...(body.consent_purpose_id === undefined
|
|
68
|
+
? {}
|
|
69
|
+
: { consentPurposeId: body.consent_purpose_id }),
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
72
|
|
|
@@ -78,6 +84,8 @@ export function listResponse(list: ListView): Record<string, unknown> {
|
|
|
78
84
|
description: list.description,
|
|
79
85
|
target_type: list.targetType,
|
|
80
86
|
member_count: list.memberCount,
|
|
87
|
+
consent_purpose_id: list.consentPurposeId,
|
|
88
|
+
consent_purpose_slug: list.consentPurposeSlug,
|
|
81
89
|
created_at: list.createdAt.toISOString(),
|
|
82
90
|
updated_at: list.updatedAt.toISOString(),
|
|
83
91
|
}
|
|
@@ -2,6 +2,7 @@ import { RECORD_TARGET_TYPES } from '@kelpie/schemas'
|
|
|
2
2
|
import { foreignKey, index, pgTable, text, timestamp, unique } from 'drizzle-orm/pg-core'
|
|
3
3
|
|
|
4
4
|
import { checkOneOf, createdAt, primaryId, updatedAt } from '../../lib/columns.ts'
|
|
5
|
+
import { consentPurposes } from '../consent-purposes/schema.ts'
|
|
5
6
|
import { workspaces } from '../workspace/schema.ts'
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -34,6 +35,15 @@ export const lists = pgTable(
|
|
|
34
35
|
name: text('name').notNull(),
|
|
35
36
|
description: text('description'),
|
|
36
37
|
targetType: text('target_type').notNull(),
|
|
38
|
+
/**
|
|
39
|
+
* The consent purpose captured when a form submit adds a person to this
|
|
40
|
+
* list. Person lists only — the service refuses a non-null value on any
|
|
41
|
+
* other target type. `restrict` on delete so a purpose in use is not
|
|
42
|
+
* silently unset behind the list's back.
|
|
43
|
+
*/
|
|
44
|
+
consentPurposeId: text('consent_purpose_id').references(() => consentPurposes.id, {
|
|
45
|
+
onDelete: 'restrict',
|
|
46
|
+
}),
|
|
37
47
|
createdAt: createdAt(),
|
|
38
48
|
updatedAt: updatedAt(),
|
|
39
49
|
},
|
|
@@ -9,6 +9,7 @@ import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
|
9
9
|
import { toEventActor } from '../../lib/actor.ts'
|
|
10
10
|
import type { Actor } from '../auth/actor.ts'
|
|
11
11
|
import { requireWorkspaceId } from '../auth/actor.ts'
|
|
12
|
+
import * as consentPurposesRepository from '../consent-purposes/repository.ts'
|
|
12
13
|
import { missingTargets, resolveTargetNames, targetKey } from '../recordTargets.ts'
|
|
13
14
|
import type { RecordTargetType } from '../recordTargets.ts'
|
|
14
15
|
import './events.ts'
|
|
@@ -43,8 +44,14 @@ export interface ListsDependencies {
|
|
|
43
44
|
readonly now: () => Date
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
/**
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
|
+
* A list as the API returns one: the stored row minus the tenancy column,
|
|
49
|
+
* plus the denormalised slug of the consent purpose (when set) so a reader
|
|
50
|
+
* needs no second call.
|
|
51
|
+
*/
|
|
52
|
+
export type ListView = Omit<ListWithCount, 'workspaceId'> & {
|
|
53
|
+
readonly consentPurposeSlug: string | null
|
|
54
|
+
}
|
|
48
55
|
|
|
49
56
|
/** A membership plus the list it points at, as `/v1/list-memberships` returns one. */
|
|
50
57
|
export interface ListMembershipView {
|
|
@@ -71,12 +78,18 @@ export interface CreateListInput {
|
|
|
71
78
|
readonly name: string
|
|
72
79
|
readonly targetType: RecordTargetType
|
|
73
80
|
readonly description: string | null
|
|
81
|
+
/**
|
|
82
|
+
* Optional consent purpose captured on form-driven adds. Person lists only.
|
|
83
|
+
* A non-null value on any other target type is refused at 422.
|
|
84
|
+
*/
|
|
85
|
+
readonly consentPurposeId: string | null
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
/** PATCH semantics: an absent field is left alone. The type never moves. */
|
|
77
89
|
export interface UpdateListInput {
|
|
78
90
|
readonly name?: string | undefined
|
|
79
91
|
readonly description?: string | null | undefined
|
|
92
|
+
readonly consentPurposeId?: string | null | undefined
|
|
80
93
|
}
|
|
81
94
|
|
|
82
95
|
export interface AddListMemberInput {
|
|
@@ -104,10 +117,10 @@ export interface ListsService {
|
|
|
104
117
|
): Promise<readonly ListMembershipView[]>
|
|
105
118
|
}
|
|
106
119
|
|
|
107
|
-
function toView(record: ListWithCount): ListView {
|
|
120
|
+
function toView(record: ListWithCount, consentPurposeSlug: string | null): ListView {
|
|
108
121
|
const { workspaceId: _workspaceId, ...view } = record
|
|
109
122
|
|
|
110
|
-
return view
|
|
123
|
+
return { ...view, consentPurposeSlug }
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
function toMembershipView(row: MembershipWithList): ListMembershipView {
|
|
@@ -157,6 +170,13 @@ function alreadyMember(): AppError {
|
|
|
157
170
|
])
|
|
158
171
|
}
|
|
159
172
|
|
|
173
|
+
function purposeNotPersonList(): AppError {
|
|
174
|
+
return AppError.validationFailed(
|
|
175
|
+
'Only person lists capture consent — remove consent_purpose_id or change the list type',
|
|
176
|
+
[{ field: 'consent_purpose_id', message: 'Person lists only' }],
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
160
180
|
export function createListsService(dependencies: ListsDependencies): ListsService {
|
|
161
181
|
async function require(workspaceId: string, id: string): Promise<ListWithCount> {
|
|
162
182
|
const list = await repository.findList(dependencies.db, workspaceId, id)
|
|
@@ -180,23 +200,77 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
180
200
|
}
|
|
181
201
|
}
|
|
182
202
|
|
|
203
|
+
async function resolveConsentPurposeSlug(
|
|
204
|
+
workspaceId: string,
|
|
205
|
+
purposeId: string | null,
|
|
206
|
+
): Promise<string | null> {
|
|
207
|
+
if (purposeId === null) return null
|
|
208
|
+
const [row] = await consentPurposesRepository.listPurposesByIds(
|
|
209
|
+
dependencies.db,
|
|
210
|
+
workspaceId,
|
|
211
|
+
[purposeId],
|
|
212
|
+
)
|
|
213
|
+
return row?.slug ?? null
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function requireConsentPurposeExists(
|
|
217
|
+
workspaceId: string,
|
|
218
|
+
purposeId: string,
|
|
219
|
+
): Promise<void> {
|
|
220
|
+
const rows = await consentPurposesRepository.listPurposesByIds(
|
|
221
|
+
dependencies.db,
|
|
222
|
+
workspaceId,
|
|
223
|
+
[purposeId],
|
|
224
|
+
)
|
|
225
|
+
if (rows.length === 0) {
|
|
226
|
+
throw AppError.validationFailed('That consent purpose was not found', [
|
|
227
|
+
{ field: 'consent_purpose_id', message: `No purpose ${purposeId} here` },
|
|
228
|
+
])
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
183
232
|
return {
|
|
184
233
|
async list(actor, filters, query) {
|
|
185
234
|
const workspaceId = requireWorkspaceId(actor)
|
|
186
235
|
const window = readListWindow(query, LIST_SORTS, DEFAULT_LIST_SORT)
|
|
187
236
|
const rows = await repository.listLists(dependencies.db, workspaceId, filters, window)
|
|
237
|
+
const purposeIds = Array.from(
|
|
238
|
+
new Set(
|
|
239
|
+
rows
|
|
240
|
+
.map((row) => row.consentPurposeId)
|
|
241
|
+
.filter((id): id is string => id !== null),
|
|
242
|
+
),
|
|
243
|
+
)
|
|
244
|
+
const purposes = await consentPurposesRepository.listPurposesByIds(
|
|
245
|
+
dependencies.db,
|
|
246
|
+
workspaceId,
|
|
247
|
+
purposeIds,
|
|
248
|
+
)
|
|
249
|
+
const slugByPurpose = new Map(purposes.map((purpose) => [purpose.id, purpose.slug]))
|
|
188
250
|
|
|
189
|
-
return mapPage(toPage(rows, window, (row) => row.id),
|
|
251
|
+
return mapPage(toPage(rows, window, (row) => row.id), (row) =>
|
|
252
|
+
toView(row, row.consentPurposeId === null ? null : (slugByPurpose.get(row.consentPurposeId) ?? null)),
|
|
253
|
+
)
|
|
190
254
|
},
|
|
191
255
|
|
|
192
256
|
async get(actor, id) {
|
|
193
|
-
|
|
257
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
258
|
+
const record = await require(workspaceId, id)
|
|
259
|
+
const slug = await resolveConsentPurposeSlug(workspaceId, record.consentPurposeId)
|
|
260
|
+
return toView(record, slug)
|
|
194
261
|
},
|
|
195
262
|
|
|
196
263
|
async create(actor, input) {
|
|
197
264
|
const workspaceId = requireWorkspaceId(actor)
|
|
198
265
|
const id = dependencies.createId('list')
|
|
199
266
|
|
|
267
|
+
if (input.consentPurposeId !== null) {
|
|
268
|
+
if (input.targetType !== 'person') {
|
|
269
|
+
throw purposeNotPersonList()
|
|
270
|
+
}
|
|
271
|
+
await requireConsentPurposeExists(workspaceId, input.consentPurposeId)
|
|
272
|
+
}
|
|
273
|
+
|
|
200
274
|
return dependencies.transaction(
|
|
201
275
|
async ({ tx, events }) => {
|
|
202
276
|
let created
|
|
@@ -207,6 +281,7 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
207
281
|
name: input.name,
|
|
208
282
|
description: input.description,
|
|
209
283
|
targetType: input.targetType,
|
|
284
|
+
consentPurposeId: input.consentPurposeId,
|
|
210
285
|
})
|
|
211
286
|
} catch (error: unknown) {
|
|
212
287
|
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
@@ -218,7 +293,12 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
218
293
|
|
|
219
294
|
events.emit('lists.list.created', { type: 'list', id: created.id }, {})
|
|
220
295
|
|
|
221
|
-
|
|
296
|
+
const slug = await resolveConsentPurposeSlug(
|
|
297
|
+
workspaceId,
|
|
298
|
+
created.consentPurposeId,
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
return toView({ ...created, memberCount: 0 }, slug)
|
|
222
302
|
},
|
|
223
303
|
{ workspaceId, actor: toEventActor(actor) },
|
|
224
304
|
)
|
|
@@ -227,14 +307,33 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
227
307
|
async update(actor, id, changes) {
|
|
228
308
|
const workspaceId = requireWorkspaceId(actor)
|
|
229
309
|
const existing = await require(workspaceId, id)
|
|
310
|
+
|
|
311
|
+
if (
|
|
312
|
+
changes.consentPurposeId !== undefined &&
|
|
313
|
+
changes.consentPurposeId !== null &&
|
|
314
|
+
existing.targetType !== 'person'
|
|
315
|
+
) {
|
|
316
|
+
throw purposeNotPersonList()
|
|
317
|
+
}
|
|
318
|
+
if (
|
|
319
|
+
changes.consentPurposeId !== undefined &&
|
|
320
|
+
changes.consentPurposeId !== null
|
|
321
|
+
) {
|
|
322
|
+
await requireConsentPurposeExists(workspaceId, changes.consentPurposeId)
|
|
323
|
+
}
|
|
324
|
+
|
|
230
325
|
const columns: Partial<repository.ListColumns> = {
|
|
231
326
|
...(changes.name === undefined ? {} : { name: changes.name }),
|
|
232
327
|
...(changes.description === undefined ? {} : { description: changes.description }),
|
|
328
|
+
...(changes.consentPurposeId === undefined
|
|
329
|
+
? {}
|
|
330
|
+
: { consentPurposeId: changes.consentPurposeId }),
|
|
233
331
|
}
|
|
234
332
|
const changed = changedKeys(existing, columns)
|
|
235
333
|
|
|
236
334
|
if (changed.length === 0) {
|
|
237
|
-
|
|
335
|
+
const slug = await resolveConsentPurposeSlug(workspaceId, existing.consentPurposeId)
|
|
336
|
+
return toView(existing, slug)
|
|
238
337
|
}
|
|
239
338
|
|
|
240
339
|
return dependencies.transaction(
|
|
@@ -259,7 +358,9 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
259
358
|
|
|
260
359
|
events.emit('lists.list.updated', { type: 'list', id }, { changed })
|
|
261
360
|
|
|
262
|
-
|
|
361
|
+
const slug = await resolveConsentPurposeSlug(workspaceId, updated.consentPurposeId)
|
|
362
|
+
|
|
363
|
+
return toView({ ...updated, memberCount: existing.memberCount }, slug)
|
|
263
364
|
},
|
|
264
365
|
{ workspaceId, actor: toEventActor(actor) },
|
|
265
366
|
)
|
package/src/modules/mcp/index.ts
CHANGED
|
@@ -44,6 +44,11 @@ export const MCP_INSTRUCTIONS = [
|
|
|
44
44
|
'- The handbook holds voice, ICP, and how this company sells. Read handbook_pages_list',
|
|
45
45
|
' before writing anything a customer will see.',
|
|
46
46
|
'- A job title belongs to a position, not a person. A person may hold several.',
|
|
47
|
+
'- A person has one name, which is what to call them and what every list shows.',
|
|
48
|
+
' first_name, last_name, salutation and suffix are optional detail beside it. Send',
|
|
49
|
+
' the parts when you know them; people_create composes a name from first_name and',
|
|
50
|
+
' last_name when you send no name. Never split a name into parts yourself, and note',
|
|
51
|
+
' that changing a part does not rename the person — send name to do that.',
|
|
47
52
|
'- Next steps are plan_items with a date and an owner, not prose in a summary field.',
|
|
48
53
|
].join('\n')
|
|
49
54
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
2
|
import { createActivityRecorder } from '../activities/index.ts'
|
|
3
|
+
import { createCustomFieldValues } from '../custom-fields/index.ts'
|
|
3
4
|
import { opportunitiesEvents } from './events.ts'
|
|
4
5
|
import { mountOpportunitiesRoutes } from './routes.ts'
|
|
5
6
|
import * as schema from './schema.ts'
|
|
@@ -17,7 +18,7 @@ import { registerOpportunitiesTools } from './tools.ts'
|
|
|
17
18
|
export function createOpportunitiesModule(migrationsDirectory: string): KelpieModule {
|
|
18
19
|
return {
|
|
19
20
|
id: 'opportunities',
|
|
20
|
-
requires: ['companies', 'pipelines', 'activities'],
|
|
21
|
+
requires: ['companies', 'pipelines', 'activities', 'custom-fields'],
|
|
21
22
|
events: opportunitiesEvents,
|
|
22
23
|
|
|
23
24
|
register(context) {
|
|
@@ -30,6 +31,7 @@ export function createOpportunitiesModule(migrationsDirectory: string): KelpieMo
|
|
|
30
31
|
createId: context.createId,
|
|
31
32
|
now: context.now,
|
|
32
33
|
}),
|
|
34
|
+
customFields: createCustomFieldValues({ db: context.db }),
|
|
33
35
|
})
|
|
34
36
|
|
|
35
37
|
context.schema(schema, migrationsDirectory)
|
|
@@ -6,6 +6,7 @@ import type { ListWindow, SortableFields } from '../../lib/pagination.ts'
|
|
|
6
6
|
import { arrayContainsPattern, containsPattern } from '../../lib/search.ts'
|
|
7
7
|
import type { Queryable } from '../../runtime/transaction.ts'
|
|
8
8
|
import { companies } from '../companies/schema.ts'
|
|
9
|
+
import { anyPersonLinked } from '../personLinks.ts'
|
|
9
10
|
import { workspaceMembers } from '../workspace/schema.ts'
|
|
10
11
|
import { opportunities } from './schema.ts'
|
|
11
12
|
|
|
@@ -32,6 +33,8 @@ export interface OpportunityFilters {
|
|
|
32
33
|
readonly companyIds?: readonly string[] | undefined
|
|
33
34
|
/** `?stage_id=`, repeatable: the board fetches one column with one of these. */
|
|
34
35
|
readonly stageIds?: readonly string[] | undefined
|
|
36
|
+
/** `?person_id=`, repeatable: opportunities any of these people are on. */
|
|
37
|
+
readonly personIds?: readonly string[] | undefined
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
/**
|
|
@@ -69,6 +72,14 @@ function conditionsFor(workspaceId: string, filters: OpportunityFilters): (SQL |
|
|
|
69
72
|
? undefined
|
|
70
73
|
: inArray(opportunities.companyId, filters.companyIds),
|
|
71
74
|
filters.stageIds === undefined ? undefined : inArray(opportunities.stageId, filters.stageIds),
|
|
75
|
+
filters.personIds === undefined
|
|
76
|
+
? undefined
|
|
77
|
+
: anyPersonLinked(
|
|
78
|
+
'opportunity',
|
|
79
|
+
opportunities.id,
|
|
80
|
+
opportunities.workspaceId,
|
|
81
|
+
filters.personIds,
|
|
82
|
+
),
|
|
72
83
|
]
|
|
73
84
|
}
|
|
74
85
|
|