@kelpie/server 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/consumerEmailDomains.d.ts +2 -0
- package/dist/lib/consumerEmailDomains.d.ts.map +1 -0
- package/dist/lib/consumerEmailDomains.js +62 -0
- package/dist/lib/consumerEmailDomains.js.map +1 -0
- package/dist/lib/email.d.ts +7 -0
- package/dist/lib/email.d.ts.map +1 -1
- package/dist/lib/email.js.map +1 -1
- package/dist/lib/emailContent.d.ts +33 -0
- package/dist/lib/emailContent.d.ts.map +1 -0
- package/dist/lib/emailContent.js +54 -0
- package/dist/lib/emailContent.js.map +1 -0
- package/dist/lib/emailDomainAutoLink.d.ts +27 -0
- package/dist/lib/emailDomainAutoLink.d.ts.map +1 -0
- package/dist/lib/emailDomainAutoLink.js +119 -0
- package/dist/lib/emailDomainAutoLink.js.map +1 -0
- package/dist/lib/ids.d.ts +13 -0
- package/dist/lib/ids.d.ts.map +1 -1
- package/dist/lib/ids.js +13 -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 +18 -2
- package/dist/modules/attachedRecords.js.map +1 -1
- package/dist/modules/auth/preferences.d.ts +11 -1
- package/dist/modules/auth/preferences.d.ts.map +1 -1
- package/dist/modules/auth/preferences.js +11 -0
- package/dist/modules/auth/preferences.js.map +1 -1
- package/dist/modules/auth/routes.d.ts.map +1 -1
- package/dist/modules/auth/routes.js +18 -0
- package/dist/modules/auth/routes.js.map +1 -1
- package/dist/modules/auth/schema.d.ts +20 -0
- package/dist/modules/auth/schema.d.ts.map +1 -1
- package/dist/modules/auth/schema.js +11 -1
- package/dist/modules/auth/schema.js.map +1 -1
- package/dist/modules/auth/service.d.ts.map +1 -1
- package/dist/modules/auth/service.js +27 -3
- package/dist/modules/auth/service.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/repository.d.ts +2 -0
- package/dist/modules/companies/repository.d.ts.map +1 -1
- package/dist/modules/companies/repository.js +1 -0
- package/dist/modules/companies/repository.js.map +1 -1
- package/dist/modules/companies/routes.d.ts +16 -0
- package/dist/modules/companies/routes.d.ts.map +1 -1
- package/dist/modules/companies/routes.js +18 -0
- package/dist/modules/companies/routes.js.map +1 -1
- package/dist/modules/companies/schema.d.ts +37 -0
- package/dist/modules/companies/schema.d.ts.map +1 -1
- package/dist/modules/companies/schema.js +10 -1
- package/dist/modules/companies/schema.js.map +1 -1
- package/dist/modules/companies/service.d.ts +6 -0
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +45 -11
- 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 +21 -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/email-domain-linker/index.d.ts +12 -0
- package/dist/modules/email-domain-linker/index.d.ts.map +1 -0
- package/dist/modules/email-domain-linker/index.js +34 -0
- package/dist/modules/email-domain-linker/index.js.map +1 -0
- package/dist/modules/email-domain-linker/routes.d.ts +14 -0
- package/dist/modules/email-domain-linker/routes.d.ts.map +1 -0
- package/dist/modules/email-domain-linker/routes.js +15 -0
- package/dist/modules/email-domain-linker/routes.js.map +1 -0
- package/dist/modules/email-domain-linker/service.d.ts +37 -0
- package/dist/modules/email-domain-linker/service.d.ts.map +1 -0
- package/dist/modules/email-domain-linker/service.js +63 -0
- package/dist/modules/email-domain-linker/service.js.map +1 -0
- 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 +4 -0
- package/dist/modules/eventCatalogs.d.ts.map +1 -1
- package/dist/modules/eventCatalogs.js +4 -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/events.d.ts +42 -0
- package/dist/modules/lists/events.d.ts.map +1 -0
- package/dist/modules/lists/events.js +16 -0
- package/dist/modules/lists/events.js.map +1 -0
- package/dist/modules/lists/index.d.ts +10 -0
- package/dist/modules/lists/index.d.ts.map +1 -0
- package/dist/modules/lists/index.js +35 -0
- package/dist/modules/lists/index.js.map +1 -0
- package/dist/modules/lists/repository.d.ts +80 -0
- package/dist/modules/lists/repository.d.ts.map +1 -0
- package/dist/modules/lists/repository.js +178 -0
- package/dist/modules/lists/repository.js.map +1 -0
- package/dist/modules/lists/routes.d.ts +55 -0
- package/dist/modules/lists/routes.d.ts.map +1 -0
- package/dist/modules/lists/routes.js +168 -0
- package/dist/modules/lists/routes.js.map +1 -0
- package/dist/modules/lists/schema.d.ts +281 -0
- package/dist/modules/lists/schema.d.ts.map +1 -0
- package/dist/modules/lists/schema.js +83 -0
- package/dist/modules/lists/schema.js.map +1 -0
- package/dist/modules/lists/service.d.ts +82 -0
- package/dist/modules/lists/service.d.ts.map +1 -0
- package/dist/modules/lists/service.js +262 -0
- package/dist/modules/lists/service.js.map +1 -0
- package/dist/modules/lists/tools.d.ts +4 -0
- package/dist/modules/lists/tools.d.ts.map +1 -0
- package/dist/modules/lists/tools.js +86 -0
- package/dist/modules/lists/tools.js.map +1 -0
- 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 +11 -0
- package/dist/modules/people/repository.d.ts.map +1 -1
- package/dist/modules/people/repository.js +21 -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 +131 -36
- 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/positions/routes.d.ts.map +1 -1
- package/dist/modules/positions/routes.js +4 -2
- package/dist/modules/positions/routes.js.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 +160 -0
- package/dist/modules/sample-data/fixture.d.ts.map +1 -0
- package/dist/modules/sample-data/fixture.js +501 -0
- package/dist/modules/sample-data/fixture.js.map +1 -0
- package/dist/modules/sample-data/index.d.ts +11 -0
- package/dist/modules/sample-data/index.d.ts.map +1 -0
- package/dist/modules/sample-data/index.js +44 -0
- package/dist/modules/sample-data/index.js.map +1 -0
- package/dist/modules/sample-data/routes.d.ts +15 -0
- package/dist/modules/sample-data/routes.d.ts.map +1 -0
- package/dist/modules/sample-data/routes.js +25 -0
- package/dist/modules/sample-data/routes.js.map +1 -0
- package/dist/modules/sample-data/service.d.ts +39 -0
- package/dist/modules/sample-data/service.d.ts.map +1 -0
- package/dist/modules/sample-data/service.js +481 -0
- package/dist/modules/sample-data/service.js.map +1 -0
- package/dist/modules/sample-data/tools.d.ts +4 -0
- package/dist/modules/sample-data/tools.d.ts.map +1 -0
- package/dist/modules/sample-data/tools.js +22 -0
- package/dist/modules/sample-data/tools.js.map +1 -0
- 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/smtp-email/index.d.ts +1 -0
- package/dist/modules/smtp-email/index.d.ts.map +1 -1
- package/dist/modules/smtp-email/index.js +1 -0
- package/dist/modules/smtp-email/index.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 +20 -1
- 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 +4 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +4 -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/0021_certain_maggott.sql +30 -0
- package/migrations/0022_stormy_manta.sql +1 -0
- package/migrations/0023_funny_maddog.sql +1 -0
- 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/0021_snapshot.json +5389 -0
- package/migrations/meta/0022_snapshot.json +5396 -0
- package/migrations/meta/0023_snapshot.json +5403 -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 +112 -0
- package/package.json +3 -2
- package/src/lib/consumerEmailDomains.ts +62 -0
- package/src/lib/email.ts +7 -0
- package/src/lib/emailContent.ts +91 -0
- package/src/lib/emailDomainAutoLink.ts +165 -0
- package/src/lib/ids.ts +13 -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 +37 -3
- package/src/modules/auth/preferences.ts +13 -1
- package/src/modules/auth/routes.ts +22 -0
- package/src/modules/auth/schema.ts +12 -2
- package/src/modules/auth/service.ts +37 -3
- package/src/modules/companies/index.ts +3 -1
- package/src/modules/companies/repository.ts +3 -0
- package/src/modules/companies/routes.ts +20 -0
- package/src/modules/companies/schema.ts +11 -1
- package/src/modules/companies/service.ts +72 -12
- 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 +21 -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/email-domain-linker/index.ts +40 -0
- package/src/modules/email-domain-linker/routes.ts +40 -0
- package/src/modules/email-domain-linker/service.ts +122 -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 +4 -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/events.ts +41 -0
- package/src/modules/lists/index.ts +41 -0
- package/src/modules/lists/repository.ts +343 -0
- package/src/modules/lists/routes.ts +255 -0
- package/src/modules/lists/schema.ts +95 -0
- package/src/modules/lists/service.ts +505 -0
- package/src/modules/lists/tools.ts +128 -0
- 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 +31 -0
- package/src/modules/people/routes.ts +127 -18
- package/src/modules/people/schema.ts +109 -3
- package/src/modules/people/service.ts +205 -39
- package/src/modules/people/tools.ts +5 -1
- package/src/modules/personLinks.ts +278 -0
- package/src/modules/positions/routes.ts +4 -2
- 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 +690 -0
- package/src/modules/sample-data/index.ts +51 -0
- package/src/modules/sample-data/routes.ts +50 -0
- package/src/modules/sample-data/service.ts +679 -0
- package/src/modules/sample-data/tools.ts +32 -0
- 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/smtp-email/index.ts +8 -1
- 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 +27 -1
- package/src/modules/workspace/starters.ts +5 -0
- package/src/runtime/events.ts +1 -0
- package/src/schema/index.ts +4 -0
- package/src/testing/database.ts +97 -11
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type { ConsentStatus } from '@kelpie/schemas'
|
|
2
|
+
import { and, eq, inArray } from 'drizzle-orm'
|
|
3
|
+
|
|
4
|
+
import { AppError } from '../../lib/errors.ts'
|
|
5
|
+
import type { Transaction } from '../../runtime/transaction.ts'
|
|
6
|
+
import { consentPurposes } from '../consent-purposes/schema.ts'
|
|
7
|
+
import { personConsents } from './schema.ts'
|
|
8
|
+
|
|
9
|
+
/**
|
|
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
|
|
12
|
+
* grant for the same (person, purpose) with the same source is a no-op.
|
|
13
|
+
*
|
|
14
|
+
* `source` follows the shape in `docs/privacy.md`:
|
|
15
|
+
* `form:<form_id>` | `list:<list_id>` | `import` | `manual`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export interface ConsentWriteChange {
|
|
19
|
+
readonly purposeSlug: string
|
|
20
|
+
readonly purposeLabel: string
|
|
21
|
+
readonly status: ConsentStatus | null
|
|
22
|
+
readonly previousStatus: ConsentStatus | null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ConsentWriteInput {
|
|
26
|
+
readonly purposeSlug: string
|
|
27
|
+
readonly status: ConsentStatus | null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface PurposeRow {
|
|
31
|
+
readonly id: string
|
|
32
|
+
readonly slug: string
|
|
33
|
+
readonly label: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function resolvePurposesBySlug(
|
|
37
|
+
tx: Transaction,
|
|
38
|
+
workspaceId: string,
|
|
39
|
+
slugs: readonly string[],
|
|
40
|
+
): Promise<ReadonlyMap<string, PurposeRow>> {
|
|
41
|
+
if (slugs.length === 0) return new Map()
|
|
42
|
+
const rows = await tx
|
|
43
|
+
.select({
|
|
44
|
+
id: consentPurposes.id,
|
|
45
|
+
slug: consentPurposes.slug,
|
|
46
|
+
label: consentPurposes.label,
|
|
47
|
+
})
|
|
48
|
+
.from(consentPurposes)
|
|
49
|
+
.where(
|
|
50
|
+
and(
|
|
51
|
+
eq(consentPurposes.workspaceId, workspaceId),
|
|
52
|
+
inArray(consentPurposes.slug, [...slugs]),
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
return new Map(rows.map((row) => [row.slug, row]))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Applies one `PersonConsent` write. `status: null` deletes the row (falls
|
|
60
|
+
* back to the purpose default); any other status upserts it.
|
|
61
|
+
*
|
|
62
|
+
* @returns The change that landed — with the previous status so a caller can
|
|
63
|
+
* file a "no change" as a no-op activity.
|
|
64
|
+
*/
|
|
65
|
+
export async function upsertPersonConsent(
|
|
66
|
+
tx: Transaction,
|
|
67
|
+
workspaceId: string,
|
|
68
|
+
personId: string,
|
|
69
|
+
purposeId: string,
|
|
70
|
+
purposeSlug: string,
|
|
71
|
+
purposeLabel: string,
|
|
72
|
+
status: ConsentStatus | null,
|
|
73
|
+
source: string,
|
|
74
|
+
now: Date,
|
|
75
|
+
): Promise<ConsentWriteChange> {
|
|
76
|
+
const [existing] = await tx
|
|
77
|
+
.select({ status: personConsents.status })
|
|
78
|
+
.from(personConsents)
|
|
79
|
+
.where(
|
|
80
|
+
and(eq(personConsents.personId, personId), eq(personConsents.purposeId, purposeId)),
|
|
81
|
+
)
|
|
82
|
+
.limit(1)
|
|
83
|
+
|
|
84
|
+
const previousStatus = (existing?.status ?? null) as ConsentStatus | null
|
|
85
|
+
|
|
86
|
+
if (status === null) {
|
|
87
|
+
if (existing !== undefined) {
|
|
88
|
+
await tx
|
|
89
|
+
.delete(personConsents)
|
|
90
|
+
.where(
|
|
91
|
+
and(eq(personConsents.personId, personId), eq(personConsents.purposeId, purposeId)),
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
return { purposeSlug, purposeLabel, status: null, previousStatus }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await tx
|
|
98
|
+
.insert(personConsents)
|
|
99
|
+
.values({
|
|
100
|
+
workspaceId,
|
|
101
|
+
personId,
|
|
102
|
+
purposeId,
|
|
103
|
+
status,
|
|
104
|
+
notedAt: now,
|
|
105
|
+
source,
|
|
106
|
+
updatedAt: now,
|
|
107
|
+
})
|
|
108
|
+
.onConflictDoUpdate({
|
|
109
|
+
target: [personConsents.personId, personConsents.purposeId],
|
|
110
|
+
set: {
|
|
111
|
+
status,
|
|
112
|
+
notedAt: now,
|
|
113
|
+
source,
|
|
114
|
+
updatedAt: now,
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
return { purposeSlug, purposeLabel, status, previousStatus }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Reads by slug for a manual PATCH: resolves each named purpose to its id,
|
|
123
|
+
* refuses an unknown slug with a `422`, and applies the writes. Every write
|
|
124
|
+
* ridden through here uses `source: 'manual'`.
|
|
125
|
+
*/
|
|
126
|
+
export async function applyManualConsentWrites(
|
|
127
|
+
tx: Transaction,
|
|
128
|
+
workspaceId: string,
|
|
129
|
+
personId: string,
|
|
130
|
+
writes: readonly ConsentWriteInput[],
|
|
131
|
+
now: Date,
|
|
132
|
+
): Promise<readonly ConsentWriteChange[]> {
|
|
133
|
+
if (writes.length === 0) return []
|
|
134
|
+
const slugs = writes.map((write) => write.purposeSlug)
|
|
135
|
+
const purposesBySlug = await resolvePurposesBySlug(tx, workspaceId, slugs)
|
|
136
|
+
|
|
137
|
+
const missing = slugs.filter((slug) => !purposesBySlug.has(slug))
|
|
138
|
+
if (missing.length > 0) {
|
|
139
|
+
throw AppError.validationFailed(
|
|
140
|
+
'One or more consent purposes were not found in this workspace',
|
|
141
|
+
missing.map((slug) => ({
|
|
142
|
+
field: `consents.${slug}`,
|
|
143
|
+
message: `Unknown consent purpose "${slug}"`,
|
|
144
|
+
})),
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const changes: ConsentWriteChange[] = []
|
|
149
|
+
for (const write of writes) {
|
|
150
|
+
const purpose = purposesBySlug.get(write.purposeSlug)
|
|
151
|
+
if (purpose === undefined) continue // impossible after the check above
|
|
152
|
+
const change = await upsertPersonConsent(
|
|
153
|
+
tx,
|
|
154
|
+
workspaceId,
|
|
155
|
+
personId,
|
|
156
|
+
purpose.id,
|
|
157
|
+
purpose.slug,
|
|
158
|
+
purpose.label,
|
|
159
|
+
write.status,
|
|
160
|
+
'manual',
|
|
161
|
+
now,
|
|
162
|
+
)
|
|
163
|
+
changes.push(change)
|
|
164
|
+
}
|
|
165
|
+
return changes
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The `changed` paths a person update event emits for consent writes. Names
|
|
170
|
+
* every purpose that actually moved, shaped as `consents.<slug>`.
|
|
171
|
+
*/
|
|
172
|
+
export function consentChangedPaths(changes: readonly ConsentWriteChange[]): readonly string[] {
|
|
173
|
+
return changes
|
|
174
|
+
.filter((change) => change.status !== change.previousStatus)
|
|
175
|
+
.map((change) => `consents.${change.purposeSlug}`)
|
|
176
|
+
}
|
|
177
|
+
|
|
@@ -66,6 +66,11 @@ function matchesTerm(term: string): SQL | undefined {
|
|
|
66
66
|
|
|
67
67
|
return or(
|
|
68
68
|
ilike(people.name, pattern),
|
|
69
|
+
// The same two parts `search_vector` carries, so filtering this list and
|
|
70
|
+
// searching the workspace find a person by their surname alike. Salutation
|
|
71
|
+
// and suffix are in neither: "Dr" matches half a workspace.
|
|
72
|
+
ilike(people.firstName, pattern),
|
|
73
|
+
ilike(people.lastName, pattern),
|
|
69
74
|
ilike(people.email, pattern),
|
|
70
75
|
ilike(people.summary, pattern),
|
|
71
76
|
arrayContainsPattern(people.tags, pattern),
|
|
@@ -132,6 +137,32 @@ export async function findPersonByEmail(
|
|
|
132
137
|
return found
|
|
133
138
|
}
|
|
134
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Every person in this workspace whose email is exactly at `domain`, case-
|
|
142
|
+
* insensitive. Used by the email-domain auto-linker when a Company is created
|
|
143
|
+
* or its domain is set.
|
|
144
|
+
*
|
|
145
|
+
* Not `ilike '%@domain'`: that also matches `alex@sub.domain`, which the
|
|
146
|
+
* person-side matcher (exact `email.slice(at + 1) = companies.domain`) would
|
|
147
|
+
* never link. `split_part` peels off the address at the last `@`, keeping the
|
|
148
|
+
* two directions consistent.
|
|
149
|
+
*/
|
|
150
|
+
export async function findPeopleByEmailDomain(
|
|
151
|
+
db: Queryable,
|
|
152
|
+
workspaceId: string,
|
|
153
|
+
domain: string,
|
|
154
|
+
): Promise<PersonRecord[]> {
|
|
155
|
+
return db
|
|
156
|
+
.select()
|
|
157
|
+
.from(people)
|
|
158
|
+
.where(
|
|
159
|
+
and(
|
|
160
|
+
eq(people.workspaceId, workspaceId),
|
|
161
|
+
sql`split_part(${people.email}::text, '@', 2) = lower(${domain})`,
|
|
162
|
+
),
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
135
166
|
export async function insertPerson(db: Queryable, values: PersonColumns): Promise<PersonRecord> {
|
|
136
167
|
const [created] = await db.insert(people).values(values).returning()
|
|
137
168
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { CONSENT_STATUSES, composeName, customFieldsPatchShape } from '@kelpie/schemas'
|
|
2
|
+
import type { NameParts } from '@kelpie/schemas'
|
|
1
3
|
import type { Context, Hono } from 'hono'
|
|
2
4
|
import { z } from 'zod'
|
|
3
5
|
|
|
@@ -5,6 +7,8 @@ import { pageBody, readIdFilter, readJsonBody, readListParameters } from '../../
|
|
|
5
7
|
import type { Actor } from '../auth/actor.ts'
|
|
6
8
|
import { resolveActorFrom } from '../auth/credentials.ts'
|
|
7
9
|
import type { CredentialDependencies } from '../auth/credentials.ts'
|
|
10
|
+
import { renderCustomFieldsForWire } from '../custom-fields/wire.ts'
|
|
11
|
+
import type { EffectiveConsent } from './consentHydration.ts'
|
|
8
12
|
import {
|
|
9
13
|
INFLUENCE_LEVELS,
|
|
10
14
|
PREFERRED_CHANNELS,
|
|
@@ -26,9 +30,32 @@ const socialProfileBody = z.strictObject({
|
|
|
26
30
|
url: z.string().min(1),
|
|
27
31
|
})
|
|
28
32
|
|
|
33
|
+
/**
|
|
34
|
+
* One manual consent write on a Person body. `purpose_slug` names the
|
|
35
|
+
* workspace purpose; `status: null` clears the row and falls back to the
|
|
36
|
+
* purpose default, any other value upserts `source: manual`.
|
|
37
|
+
*/
|
|
38
|
+
const consentWriteBody = z.strictObject({
|
|
39
|
+
purpose_slug: z.string().min(1),
|
|
40
|
+
status: z.enum(CONSENT_STATUSES).nullable(),
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
/** The name parts of a body, under the names `composeName` reads them by. */
|
|
44
|
+
function toNameParts(body: {
|
|
45
|
+
readonly first_name?: string | null
|
|
46
|
+
readonly last_name?: string | null
|
|
47
|
+
readonly suffix?: string | null
|
|
48
|
+
}): NameParts {
|
|
49
|
+
return { firstName: body.first_name, lastName: body.last_name, suffix: body.suffix }
|
|
50
|
+
}
|
|
51
|
+
|
|
29
52
|
/** The full field set, without defaults. `createBody` adds those; `updateBody` makes it partial. */
|
|
30
53
|
const personShape = {
|
|
31
54
|
name: z.string().min(1),
|
|
55
|
+
salutation: z.string().nullable(),
|
|
56
|
+
first_name: z.string().nullable(),
|
|
57
|
+
last_name: z.string().nullable(),
|
|
58
|
+
suffix: z.string().nullable(),
|
|
32
59
|
email: z.string().nullable(),
|
|
33
60
|
phones: z.array(z.string().min(1)),
|
|
34
61
|
social_profiles: z.array(socialProfileBody),
|
|
@@ -40,27 +67,56 @@ const personShape = {
|
|
|
40
67
|
summary: z.string(),
|
|
41
68
|
tags: z.array(z.string().min(1)),
|
|
42
69
|
last_contacted_at: z.iso.datetime().nullable(),
|
|
70
|
+
do_not_contact: z.boolean(),
|
|
71
|
+
consents: z.array(consentWriteBody),
|
|
72
|
+
custom_fields: customFieldsPatchShape,
|
|
43
73
|
}
|
|
44
74
|
|
|
45
75
|
/**
|
|
46
|
-
*
|
|
47
|
-
* button writes, so creating through the API and
|
|
48
|
-
* the same record.
|
|
76
|
+
* A create names its person and defaults everything else. The defaults are the
|
|
77
|
+
* ones the mockup's own Add person button writes, so creating through the API and
|
|
78
|
+
* creating through the UI produce the same record.
|
|
79
|
+
*
|
|
80
|
+
* Naming the person means `name`, or the `first_name` / `last_name` pair for one
|
|
81
|
+
* to be composed from — the shape a caller holding a row out of another CRM
|
|
82
|
+
* already has. Sending neither is the one refusal, because `name` is what every
|
|
83
|
+
* list, picker and timeline in Kelpie renders and a blank one is a record nobody
|
|
84
|
+
* can pick out again.
|
|
49
85
|
*/
|
|
50
|
-
export const createBody = z
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
export const createBody = z
|
|
87
|
+
.strictObject({
|
|
88
|
+
...personShape,
|
|
89
|
+
name: personShape.name.optional(),
|
|
90
|
+
salutation: personShape.salutation.default(null),
|
|
91
|
+
first_name: personShape.first_name.default(null),
|
|
92
|
+
last_name: personShape.last_name.default(null),
|
|
93
|
+
suffix: personShape.suffix.default(null),
|
|
94
|
+
email: personShape.email.default(null),
|
|
95
|
+
phones: personShape.phones.default([]),
|
|
96
|
+
social_profiles: personShape.social_profiles.default([]),
|
|
97
|
+
timezone: personShape.timezone.default(null),
|
|
98
|
+
location: personShape.location.default(null),
|
|
99
|
+
preferred_channel: personShape.preferred_channel.default('email'),
|
|
100
|
+
influence: personShape.influence.default('influencer'),
|
|
101
|
+
relationship: personShape.relationship.default('cold'),
|
|
102
|
+
summary: personShape.summary.default(''),
|
|
103
|
+
tags: personShape.tags.default([]),
|
|
104
|
+
last_contacted_at: personShape.last_contacted_at.default(null),
|
|
105
|
+
do_not_contact: personShape.do_not_contact.default(false),
|
|
106
|
+
consents: personShape.consents.default([]),
|
|
107
|
+
custom_fields: personShape.custom_fields.default({}),
|
|
108
|
+
})
|
|
109
|
+
.superRefine((body, context) => {
|
|
110
|
+
if (body.name !== undefined || composeName(toNameParts(body)).length > 0) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
context.addIssue({
|
|
115
|
+
code: 'custom',
|
|
116
|
+
path: ['name'],
|
|
117
|
+
message: 'Send a name, or a first_name or last_name to compose one from',
|
|
118
|
+
})
|
|
119
|
+
})
|
|
64
120
|
|
|
65
121
|
export const updateBody = z.strictObject(personShape).partial()
|
|
66
122
|
|
|
@@ -70,7 +126,13 @@ export interface PeopleRoutesDependencies extends CredentialDependencies {
|
|
|
70
126
|
|
|
71
127
|
export function toCreateInput(body: z.infer<typeof createBody>): CreatePersonInput {
|
|
72
128
|
return {
|
|
73
|
-
name
|
|
129
|
+
// Composed only here, on the way in, and only when the caller sent no name.
|
|
130
|
+
// `createBody` has already refused a body that would leave this blank.
|
|
131
|
+
name: body.name ?? composeName(toNameParts(body)),
|
|
132
|
+
salutation: body.salutation,
|
|
133
|
+
firstName: body.first_name,
|
|
134
|
+
lastName: body.last_name,
|
|
135
|
+
suffix: body.suffix,
|
|
74
136
|
email: body.email,
|
|
75
137
|
phones: body.phones,
|
|
76
138
|
socialProfiles: body.social_profiles,
|
|
@@ -82,12 +144,31 @@ export function toCreateInput(body: z.infer<typeof createBody>): CreatePersonInp
|
|
|
82
144
|
summary: body.summary,
|
|
83
145
|
tags: body.tags,
|
|
84
146
|
lastContactedAt: body.last_contacted_at === null ? null : new Date(body.last_contacted_at),
|
|
147
|
+
doNotContact: body.do_not_contact,
|
|
148
|
+
consents: body.consents.map((consent) => ({
|
|
149
|
+
purposeSlug: consent.purpose_slug,
|
|
150
|
+
status: consent.status,
|
|
151
|
+
})),
|
|
152
|
+
customFields: body.custom_fields,
|
|
85
153
|
}
|
|
86
154
|
}
|
|
87
155
|
|
|
156
|
+
/**
|
|
157
|
+
* A patch changes exactly the fields it names.
|
|
158
|
+
*
|
|
159
|
+
* Sending `first_name` alone does **not** recompute `name`. A display name is
|
|
160
|
+
* something somebody chose — "Chris" for a Christopher, a married name, a
|
|
161
|
+
* transliteration — and silently rewriting it from a part would undo that
|
|
162
|
+
* choice from across the room. Renaming is `name`, which is one more field in
|
|
163
|
+
* the same request for a caller that wants both.
|
|
164
|
+
*/
|
|
88
165
|
export function toUpdateInput(body: z.infer<typeof updateBody>): UpdatePersonInput {
|
|
89
166
|
return {
|
|
90
167
|
...(body.name === undefined ? {} : { name: body.name }),
|
|
168
|
+
...(body.salutation === undefined ? {} : { salutation: body.salutation }),
|
|
169
|
+
...(body.first_name === undefined ? {} : { firstName: body.first_name }),
|
|
170
|
+
...(body.last_name === undefined ? {} : { lastName: body.last_name }),
|
|
171
|
+
...(body.suffix === undefined ? {} : { suffix: body.suffix }),
|
|
91
172
|
...(body.email === undefined ? {} : { email: body.email }),
|
|
92
173
|
...(body.phones === undefined ? {} : { phones: body.phones }),
|
|
93
174
|
...(body.social_profiles === undefined ? {} : { socialProfiles: body.social_profiles }),
|
|
@@ -104,6 +185,27 @@ export function toUpdateInput(body: z.infer<typeof updateBody>): UpdatePersonInp
|
|
|
104
185
|
lastContactedAt:
|
|
105
186
|
body.last_contacted_at === null ? null : new Date(body.last_contacted_at),
|
|
106
187
|
}),
|
|
188
|
+
...(body.do_not_contact === undefined ? {} : { doNotContact: body.do_not_contact }),
|
|
189
|
+
...(body.consents === undefined
|
|
190
|
+
? {}
|
|
191
|
+
: {
|
|
192
|
+
consents: body.consents.map((consent) => ({
|
|
193
|
+
purposeSlug: consent.purpose_slug,
|
|
194
|
+
status: consent.status,
|
|
195
|
+
})),
|
|
196
|
+
}),
|
|
197
|
+
...(body.custom_fields === undefined ? {} : { customFields: body.custom_fields }),
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function consentEntry(entry: EffectiveConsent): Record<string, unknown> {
|
|
202
|
+
return {
|
|
203
|
+
purpose_slug: entry.purposeSlug,
|
|
204
|
+
purpose_label: entry.purposeLabel,
|
|
205
|
+
status: entry.status,
|
|
206
|
+
source: entry.source,
|
|
207
|
+
noted_at: entry.notedAt === null ? null : entry.notedAt.toISOString(),
|
|
208
|
+
inherited: entry.inherited,
|
|
107
209
|
}
|
|
108
210
|
}
|
|
109
211
|
|
|
@@ -111,6 +213,10 @@ export function personResponse(person: PersonView): Record<string, unknown> {
|
|
|
111
213
|
return {
|
|
112
214
|
id: person.id,
|
|
113
215
|
name: person.name,
|
|
216
|
+
salutation: person.salutation,
|
|
217
|
+
first_name: person.firstName,
|
|
218
|
+
last_name: person.lastName,
|
|
219
|
+
suffix: person.suffix,
|
|
114
220
|
email: person.email,
|
|
115
221
|
phones: person.phones,
|
|
116
222
|
social_profiles: person.socialProfiles,
|
|
@@ -122,6 +228,9 @@ export function personResponse(person: PersonView): Record<string, unknown> {
|
|
|
122
228
|
summary: person.summary,
|
|
123
229
|
tags: person.tags,
|
|
124
230
|
last_contacted_at: person.lastContactedAt === null ? null : person.lastContactedAt.toISOString(),
|
|
231
|
+
do_not_contact: person.doNotContact,
|
|
232
|
+
consents: person.consents.map(consentEntry),
|
|
233
|
+
custom_fields: renderCustomFieldsForWire(person.customFields),
|
|
125
234
|
created_at: person.createdAt.toISOString(),
|
|
126
235
|
updated_at: person.updatedAt.toISOString(),
|
|
127
236
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
CONSENT_STATUSES,
|
|
3
|
+
INFLUENCE_LEVELS,
|
|
4
|
+
PIPELINE_KINDS,
|
|
5
|
+
PREFERRED_CHANNELS,
|
|
6
|
+
RELATIONSHIP_LEVELS,
|
|
7
|
+
} from '@kelpie/schemas'
|
|
8
|
+
import type { CustomFieldValue, SocialProfile } from '@kelpie/schemas'
|
|
9
|
+
import { boolean, index, jsonb, pgTable, primaryKey, text, unique } from 'drizzle-orm/pg-core'
|
|
4
10
|
|
|
5
11
|
import {
|
|
6
12
|
checkOneOf,
|
|
@@ -12,6 +18,7 @@ import {
|
|
|
12
18
|
updatedAt,
|
|
13
19
|
} from '../../lib/columns.ts'
|
|
14
20
|
import type { SearchVectorPart } from '../../lib/columns.ts'
|
|
21
|
+
import { consentPurposes } from '../consent-purposes/schema.ts'
|
|
15
22
|
import { workspaces } from '../workspace/schema.ts'
|
|
16
23
|
|
|
17
24
|
/**
|
|
@@ -53,6 +60,14 @@ export const people = pgTable(
|
|
|
53
60
|
.notNull()
|
|
54
61
|
.references(() => workspaces.id, { onDelete: 'cascade' }),
|
|
55
62
|
name: text('name').notNull(),
|
|
63
|
+
// The canonical display name is `name`, and it is the only one of these that
|
|
64
|
+
// is required. The parts are recorded when they are known and left null when
|
|
65
|
+
// they are not; nothing composes them back into `name` after the row exists,
|
|
66
|
+
// so an edit to one never renames the record behind the editor's back.
|
|
67
|
+
salutation: text('salutation'),
|
|
68
|
+
firstName: text('first_name'),
|
|
69
|
+
lastName: text('last_name'),
|
|
70
|
+
suffix: text('suffix'),
|
|
56
71
|
email: citext('email'),
|
|
57
72
|
phones: jsonb('phones').$type<readonly string[]>().notNull().default([]),
|
|
58
73
|
socialProfiles: jsonb('social_profiles')
|
|
@@ -67,12 +82,31 @@ export const people = pgTable(
|
|
|
67
82
|
summary: text('summary').notNull().default(''),
|
|
68
83
|
tags: text('tags').array().notNull().default([]),
|
|
69
84
|
lastContactedAt: moment('last_contacted_at'),
|
|
85
|
+
// The Article 21 objection. A global do-not-contact signal, independent
|
|
86
|
+
// of consent purposes: agents check this before outreach regardless of
|
|
87
|
+
// per-purpose consent state. Never touched by forms, lists, or imports —
|
|
88
|
+
// the workspace member owns this flag.
|
|
89
|
+
doNotContact: boolean('do_not_contact').notNull().default(false),
|
|
90
|
+
// Workspace-defined fields, keyed by definition key. The custom-fields
|
|
91
|
+
// service validates every key on write; the store here just carries the
|
|
92
|
+
// shape. Default `{}` mirrors `tags`'s default — the object is always
|
|
93
|
+
// present, never null.
|
|
94
|
+
customFields: jsonb('custom_fields')
|
|
95
|
+
.$type<Readonly<Record<string, CustomFieldValue>>>()
|
|
96
|
+
.notNull()
|
|
97
|
+
.default({}),
|
|
70
98
|
createdAt: createdAt(),
|
|
71
99
|
updatedAt: updatedAt(),
|
|
72
100
|
// Their title is not here because it is not on this table. `GET /v1/search`
|
|
73
101
|
// reaches it through `positions.search_vector`.
|
|
74
102
|
searchVector: searchVector((): readonly SearchVectorPart[] => [
|
|
75
103
|
{ column: people.name, weight: 'A' },
|
|
104
|
+
// The parts carry the same weight as the display name: they exist so a
|
|
105
|
+
// person can be found by a name they are not displayed under, and finding
|
|
106
|
+
// them is the whole point of storing them. `salutation` and `suffix` are
|
|
107
|
+
// left out — "Dr" and "Jr" match half a workspace and narrow nothing.
|
|
108
|
+
{ column: people.firstName, weight: 'A' },
|
|
109
|
+
{ column: people.lastName, weight: 'A' },
|
|
76
110
|
{ column: people.email, weight: 'B' },
|
|
77
111
|
{ column: people.summary, weight: 'B' },
|
|
78
112
|
{ column: people.tags, weight: 'C', array: true },
|
|
@@ -87,3 +121,75 @@ export const people = pgTable(
|
|
|
87
121
|
checkOneOf('people_relationship_check', table.relationship, RELATIONSHIP_LEVELS),
|
|
88
122
|
],
|
|
89
123
|
)
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The explicit consent decision for one (person, purpose) pair.
|
|
127
|
+
*
|
|
128
|
+
* Absence of a row means "inherits the purpose's `default_status`", so no
|
|
129
|
+
* `unknown` status here — a stored row always carries a decision. The pk is
|
|
130
|
+
* composite on `(person_id, purpose_id)` with no public id; the row is
|
|
131
|
+
* addressed by the pair, like `form_lists` and `form_attach_targets`.
|
|
132
|
+
*
|
|
133
|
+
* `source` records where the decision came from: `form:<form_id>`,
|
|
134
|
+
* `list:<list_id>`, `import`, or `manual`. Cascade with both the person and
|
|
135
|
+
* the purpose — erasing a person drops these with the rest of their record,
|
|
136
|
+
* and removing a purpose drops every row that still names it.
|
|
137
|
+
*/
|
|
138
|
+
export const personConsents = pgTable(
|
|
139
|
+
'person_consents',
|
|
140
|
+
{
|
|
141
|
+
workspaceId: text('workspace_id')
|
|
142
|
+
.notNull()
|
|
143
|
+
.references(() => workspaces.id, { onDelete: 'cascade' }),
|
|
144
|
+
personId: text('person_id')
|
|
145
|
+
.notNull()
|
|
146
|
+
.references(() => people.id, { onDelete: 'cascade' }),
|
|
147
|
+
purposeId: text('purpose_id')
|
|
148
|
+
.notNull()
|
|
149
|
+
.references(() => consentPurposes.id, { onDelete: 'cascade' }),
|
|
150
|
+
status: text('status').notNull(),
|
|
151
|
+
notedAt: moment('noted_at').notNull().defaultNow(),
|
|
152
|
+
source: text('source').notNull(),
|
|
153
|
+
createdAt: createdAt(),
|
|
154
|
+
updatedAt: updatedAt(),
|
|
155
|
+
},
|
|
156
|
+
(table) => [
|
|
157
|
+
primaryKey({ columns: [table.personId, table.purposeId] }),
|
|
158
|
+
index('person_consents_workspace_idx').on(table.workspaceId),
|
|
159
|
+
index('person_consents_purpose_idx').on(table.purposeId),
|
|
160
|
+
checkOneOf('person_consents_status_check', table.status, CONSENT_STATUSES),
|
|
161
|
+
],
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* A person's involvement in a pipeline record — a deal, opportunity, raise, or
|
|
166
|
+
* partnership. One polymorphic table instead of a join per pipeline type; the
|
|
167
|
+
* person side keeps a real foreign key with **restrict**, so the database still
|
|
168
|
+
* blocks deleting a person who is on a deal. The target side is polymorphic per
|
|
169
|
+
* the convention: no FK, existence checked by the service, rows removed in the
|
|
170
|
+
* target's own delete transaction (`attachedRecords.ts`).
|
|
171
|
+
*
|
|
172
|
+
* `company` and `role` are deliberately absent from the check constraint: a
|
|
173
|
+
* link with a payload and its own lifecycle stays a typed object —
|
|
174
|
+
* Person↔Company is **Position** (title), Person↔Role is **Candidate** (status,
|
|
175
|
+
* stage, referrer).
|
|
176
|
+
*/
|
|
177
|
+
export const personLinks = pgTable(
|
|
178
|
+
'person_links',
|
|
179
|
+
{
|
|
180
|
+
id: primaryId(),
|
|
181
|
+
workspaceId: text('workspace_id')
|
|
182
|
+
.notNull()
|
|
183
|
+
.references(() => workspaces.id, { onDelete: 'cascade' }),
|
|
184
|
+
personId: text('person_id')
|
|
185
|
+
.notNull()
|
|
186
|
+
.references(() => people.id, { onDelete: 'restrict' }),
|
|
187
|
+
targetType: text('target_type').notNull(),
|
|
188
|
+
targetId: text('target_id').notNull(),
|
|
189
|
+
},
|
|
190
|
+
(table) => [
|
|
191
|
+
index('person_links_target_idx').on(table.workspaceId, table.targetType, table.targetId),
|
|
192
|
+
unique('person_links_person_target_key').on(table.personId, table.targetType, table.targetId),
|
|
193
|
+
checkOneOf('person_links_target_type_check', table.targetType, PIPELINE_KINDS),
|
|
194
|
+
],
|
|
195
|
+
)
|