@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,505 @@
|
|
|
1
|
+
import { changedKeys } from '../../lib/changes.ts'
|
|
2
|
+
import { UNIQUE_VIOLATION, postgresErrorCode } from '../../lib/database.ts'
|
|
3
|
+
import type { Database } from '../../lib/database.ts'
|
|
4
|
+
import { AppError } from '../../lib/errors.ts'
|
|
5
|
+
import type { IdFactory } from '../../lib/ids.ts'
|
|
6
|
+
import { mapPage, readListWindow, toPage } from '../../lib/pagination.ts'
|
|
7
|
+
import type { ListQueryParameters, Page } from '../../lib/pagination.ts'
|
|
8
|
+
import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
9
|
+
import { toEventActor } from '../../lib/actor.ts'
|
|
10
|
+
import type { Actor } from '../auth/actor.ts'
|
|
11
|
+
import { requireWorkspaceId } from '../auth/actor.ts'
|
|
12
|
+
import * as consentPurposesRepository from '../consent-purposes/repository.ts'
|
|
13
|
+
import { missingTargets, resolveTargetNames, targetKey } from '../recordTargets.ts'
|
|
14
|
+
import type { RecordTargetType } from '../recordTargets.ts'
|
|
15
|
+
import './events.ts'
|
|
16
|
+
import * as repository from './repository.ts'
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_LIST_MEMBER_SORT,
|
|
19
|
+
DEFAULT_LIST_SORT,
|
|
20
|
+
LIST_MEMBER_SORTS,
|
|
21
|
+
LIST_SORTS,
|
|
22
|
+
} from './repository.ts'
|
|
23
|
+
import type {
|
|
24
|
+
ListFilters,
|
|
25
|
+
ListMemberFilters,
|
|
26
|
+
ListMemberRecord,
|
|
27
|
+
ListWithCount,
|
|
28
|
+
MembershipWithList,
|
|
29
|
+
} from './repository.ts'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Lists: named collections of records of one type.
|
|
33
|
+
*
|
|
34
|
+
* The type is fixed at creation. A member's type must match the parent list's,
|
|
35
|
+
* a rule the database enforces through a composite foreign key. The service
|
|
36
|
+
* checks the same before the insert so a mismatch produces a friendly 422
|
|
37
|
+
* rather than a driver error the caller has to decode.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
export interface ListsDependencies {
|
|
41
|
+
readonly db: Database
|
|
42
|
+
readonly transaction: TransactionScope
|
|
43
|
+
readonly createId: IdFactory
|
|
44
|
+
readonly now: () => Date
|
|
45
|
+
}
|
|
46
|
+
|
|
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
|
+
}
|
|
55
|
+
|
|
56
|
+
/** A membership plus the list it points at, as `/v1/list-memberships` returns one. */
|
|
57
|
+
export interface ListMembershipView {
|
|
58
|
+
readonly id: string
|
|
59
|
+
readonly listId: string
|
|
60
|
+
readonly listName: string
|
|
61
|
+
readonly listTargetType: RecordTargetType
|
|
62
|
+
readonly targetType: RecordTargetType
|
|
63
|
+
readonly targetId: string
|
|
64
|
+
readonly addedAt: Date
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** A member enriched with the resolved name of the record it points at. */
|
|
68
|
+
export interface ListMemberView {
|
|
69
|
+
readonly id: string
|
|
70
|
+
readonly listId: string
|
|
71
|
+
readonly targetType: RecordTargetType
|
|
72
|
+
readonly targetId: string
|
|
73
|
+
readonly targetName: string | null
|
|
74
|
+
readonly addedAt: Date
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface CreateListInput {
|
|
78
|
+
readonly name: string
|
|
79
|
+
readonly targetType: RecordTargetType
|
|
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
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** PATCH semantics: an absent field is left alone. The type never moves. */
|
|
89
|
+
export interface UpdateListInput {
|
|
90
|
+
readonly name?: string | undefined
|
|
91
|
+
readonly description?: string | null | undefined
|
|
92
|
+
readonly consentPurposeId?: string | null | undefined
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface AddListMemberInput {
|
|
96
|
+
readonly targetType: RecordTargetType
|
|
97
|
+
readonly targetId: string
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ListsService {
|
|
101
|
+
list(actor: Actor, filters: ListFilters, query: ListQueryParameters): Promise<Page<ListView>>
|
|
102
|
+
get(actor: Actor, id: string): Promise<ListView>
|
|
103
|
+
create(actor: Actor, input: CreateListInput): Promise<ListView>
|
|
104
|
+
update(actor: Actor, id: string, changes: UpdateListInput): Promise<ListView>
|
|
105
|
+
remove(actor: Actor, id: string): Promise<void>
|
|
106
|
+
listMembers(
|
|
107
|
+
actor: Actor,
|
|
108
|
+
filters: ListMemberFilters,
|
|
109
|
+
query: ListQueryParameters,
|
|
110
|
+
): Promise<Page<ListMemberView>>
|
|
111
|
+
addMember(actor: Actor, listId: string, input: AddListMemberInput): Promise<ListMemberView>
|
|
112
|
+
removeMember(actor: Actor, listId: string, id: string): Promise<void>
|
|
113
|
+
membershipsFor(
|
|
114
|
+
actor: Actor,
|
|
115
|
+
targetType: RecordTargetType,
|
|
116
|
+
targetId: string,
|
|
117
|
+
): Promise<readonly ListMembershipView[]>
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function toView(record: ListWithCount, consentPurposeSlug: string | null): ListView {
|
|
121
|
+
const { workspaceId: _workspaceId, ...view } = record
|
|
122
|
+
|
|
123
|
+
return { ...view, consentPurposeSlug }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function toMembershipView(row: MembershipWithList): ListMembershipView {
|
|
127
|
+
return {
|
|
128
|
+
id: row.id,
|
|
129
|
+
listId: row.listId,
|
|
130
|
+
listName: row.listName,
|
|
131
|
+
listTargetType: row.listTargetType as RecordTargetType,
|
|
132
|
+
targetType: row.targetType as RecordTargetType,
|
|
133
|
+
targetId: row.targetId,
|
|
134
|
+
addedAt: row.addedAt,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function toMemberView(record: ListMemberRecord, name: string | undefined): ListMemberView {
|
|
139
|
+
return {
|
|
140
|
+
id: record.id,
|
|
141
|
+
listId: record.listId,
|
|
142
|
+
targetType: record.targetType as RecordTargetType,
|
|
143
|
+
targetId: record.targetId,
|
|
144
|
+
targetName: name ?? null,
|
|
145
|
+
addedAt: record.addedAt,
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function duplicateName(): AppError {
|
|
150
|
+
return AppError.conflict('Another list in this workspace already has that name', [
|
|
151
|
+
{ field: 'name', message: 'Already in use' },
|
|
152
|
+
])
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function typeMismatch(expected: RecordTargetType, got: RecordTargetType): AppError {
|
|
156
|
+
return AppError.validationFailed(
|
|
157
|
+
`That record cannot join a ${expected} list`,
|
|
158
|
+
[
|
|
159
|
+
{
|
|
160
|
+
field: 'target_type',
|
|
161
|
+
message: `Expected ${expected} to match the list's type, got ${got}`,
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function alreadyMember(): AppError {
|
|
168
|
+
return AppError.conflict('That record is already on the list', [
|
|
169
|
+
{ field: 'target_id', message: 'Already a member' },
|
|
170
|
+
])
|
|
171
|
+
}
|
|
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
|
+
|
|
180
|
+
export function createListsService(dependencies: ListsDependencies): ListsService {
|
|
181
|
+
async function require(workspaceId: string, id: string): Promise<ListWithCount> {
|
|
182
|
+
const list = await repository.findList(dependencies.db, workspaceId, id)
|
|
183
|
+
|
|
184
|
+
if (list === undefined) {
|
|
185
|
+
throw AppError.notFound('List not found')
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return list
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function requireTarget(
|
|
192
|
+
workspaceId: string,
|
|
193
|
+
targetType: RecordTargetType,
|
|
194
|
+
targetId: string,
|
|
195
|
+
): Promise<void> {
|
|
196
|
+
const missing = await missingTargets(dependencies.db, workspaceId, targetType, [targetId])
|
|
197
|
+
|
|
198
|
+
if (missing.length > 0) {
|
|
199
|
+
throw AppError.notFound('Record not found')
|
|
200
|
+
}
|
|
201
|
+
}
|
|
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
|
+
|
|
232
|
+
return {
|
|
233
|
+
async list(actor, filters, query) {
|
|
234
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
235
|
+
const window = readListWindow(query, LIST_SORTS, DEFAULT_LIST_SORT)
|
|
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]))
|
|
250
|
+
|
|
251
|
+
return mapPage(toPage(rows, window, (row) => row.id), (row) =>
|
|
252
|
+
toView(row, row.consentPurposeId === null ? null : (slugByPurpose.get(row.consentPurposeId) ?? null)),
|
|
253
|
+
)
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
async get(actor, id) {
|
|
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)
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
async create(actor, input) {
|
|
264
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
265
|
+
const id = dependencies.createId('list')
|
|
266
|
+
|
|
267
|
+
if (input.consentPurposeId !== null) {
|
|
268
|
+
if (input.targetType !== 'person') {
|
|
269
|
+
throw purposeNotPersonList()
|
|
270
|
+
}
|
|
271
|
+
await requireConsentPurposeExists(workspaceId, input.consentPurposeId)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return dependencies.transaction(
|
|
275
|
+
async ({ tx, events }) => {
|
|
276
|
+
let created
|
|
277
|
+
try {
|
|
278
|
+
created = await repository.insertList(tx, {
|
|
279
|
+
id,
|
|
280
|
+
workspaceId,
|
|
281
|
+
name: input.name,
|
|
282
|
+
description: input.description,
|
|
283
|
+
targetType: input.targetType,
|
|
284
|
+
consentPurposeId: input.consentPurposeId,
|
|
285
|
+
})
|
|
286
|
+
} catch (error: unknown) {
|
|
287
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
288
|
+
throw duplicateName()
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
throw error
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
events.emit('lists.list.created', { type: 'list', id: created.id }, {})
|
|
295
|
+
|
|
296
|
+
const slug = await resolveConsentPurposeSlug(
|
|
297
|
+
workspaceId,
|
|
298
|
+
created.consentPurposeId,
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
return toView({ ...created, memberCount: 0 }, slug)
|
|
302
|
+
},
|
|
303
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
304
|
+
)
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
async update(actor, id, changes) {
|
|
308
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
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
|
+
|
|
325
|
+
const columns: Partial<repository.ListColumns> = {
|
|
326
|
+
...(changes.name === undefined ? {} : { name: changes.name }),
|
|
327
|
+
...(changes.description === undefined ? {} : { description: changes.description }),
|
|
328
|
+
...(changes.consentPurposeId === undefined
|
|
329
|
+
? {}
|
|
330
|
+
: { consentPurposeId: changes.consentPurposeId }),
|
|
331
|
+
}
|
|
332
|
+
const changed = changedKeys(existing, columns)
|
|
333
|
+
|
|
334
|
+
if (changed.length === 0) {
|
|
335
|
+
const slug = await resolveConsentPurposeSlug(workspaceId, existing.consentPurposeId)
|
|
336
|
+
return toView(existing, slug)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return dependencies.transaction(
|
|
340
|
+
async ({ tx, events }) => {
|
|
341
|
+
let updated
|
|
342
|
+
try {
|
|
343
|
+
updated = await repository.updateList(tx, workspaceId, id, {
|
|
344
|
+
...columns,
|
|
345
|
+
updatedAt: dependencies.now(),
|
|
346
|
+
})
|
|
347
|
+
} catch (error: unknown) {
|
|
348
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
349
|
+
throw duplicateName()
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
throw error
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (updated === undefined) {
|
|
356
|
+
throw AppError.notFound('List not found')
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
events.emit('lists.list.updated', { type: 'list', id }, { changed })
|
|
360
|
+
|
|
361
|
+
const slug = await resolveConsentPurposeSlug(workspaceId, updated.consentPurposeId)
|
|
362
|
+
|
|
363
|
+
return toView({ ...updated, memberCount: existing.memberCount }, slug)
|
|
364
|
+
},
|
|
365
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
366
|
+
)
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
async remove(actor, id) {
|
|
370
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
371
|
+
|
|
372
|
+
await dependencies.transaction(
|
|
373
|
+
async ({ tx, events }) => {
|
|
374
|
+
await require(workspaceId, id)
|
|
375
|
+
// Members cascade with the list; nothing else references it.
|
|
376
|
+
await repository.deleteList(tx, workspaceId, id)
|
|
377
|
+
|
|
378
|
+
events.emit('lists.list.deleted', { type: 'list', id }, {})
|
|
379
|
+
},
|
|
380
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
381
|
+
)
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
async listMembers(actor, filters, query) {
|
|
385
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
386
|
+
// The list must exist. A caller reading members of a missing list gets a
|
|
387
|
+
// 404, not a silent empty page.
|
|
388
|
+
await require(workspaceId, filters.listId)
|
|
389
|
+
|
|
390
|
+
const window = readListWindow(query, LIST_MEMBER_SORTS, DEFAULT_LIST_MEMBER_SORT)
|
|
391
|
+
const rows = await repository.listListMembers(dependencies.db, workspaceId, filters, window)
|
|
392
|
+
const names = await resolveTargetNames(
|
|
393
|
+
dependencies.db,
|
|
394
|
+
workspaceId,
|
|
395
|
+
rows.map((row) => ({
|
|
396
|
+
targetType: row.targetType as RecordTargetType,
|
|
397
|
+
targetId: row.targetId,
|
|
398
|
+
})),
|
|
399
|
+
)
|
|
400
|
+
const page = toPage(rows, window, (row) => row.id)
|
|
401
|
+
|
|
402
|
+
return mapPage(page, (row) =>
|
|
403
|
+
toMemberView(
|
|
404
|
+
row,
|
|
405
|
+
names.get(
|
|
406
|
+
targetKey({
|
|
407
|
+
targetType: row.targetType as RecordTargetType,
|
|
408
|
+
targetId: row.targetId,
|
|
409
|
+
}),
|
|
410
|
+
),
|
|
411
|
+
),
|
|
412
|
+
)
|
|
413
|
+
},
|
|
414
|
+
|
|
415
|
+
async addMember(actor, listId, input) {
|
|
416
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
417
|
+
const list = await require(workspaceId, listId)
|
|
418
|
+
|
|
419
|
+
if (list.targetType !== input.targetType) {
|
|
420
|
+
throw typeMismatch(list.targetType as RecordTargetType, input.targetType)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
await requireTarget(workspaceId, input.targetType, input.targetId)
|
|
424
|
+
|
|
425
|
+
const id = dependencies.createId('listMember')
|
|
426
|
+
|
|
427
|
+
return dependencies.transaction(
|
|
428
|
+
async ({ tx, events }) => {
|
|
429
|
+
let created
|
|
430
|
+
try {
|
|
431
|
+
created = await repository.insertListMember(tx, {
|
|
432
|
+
id,
|
|
433
|
+
workspaceId,
|
|
434
|
+
listId,
|
|
435
|
+
targetType: input.targetType,
|
|
436
|
+
targetId: input.targetId,
|
|
437
|
+
})
|
|
438
|
+
} catch (error: unknown) {
|
|
439
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
440
|
+
throw alreadyMember()
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
throw error
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
events.emit(
|
|
447
|
+
'lists.member.added',
|
|
448
|
+
{ type: input.targetType, id: input.targetId },
|
|
449
|
+
{ listId },
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
const names = await resolveTargetNames(tx, workspaceId, [
|
|
453
|
+
{ targetType: input.targetType, targetId: input.targetId },
|
|
454
|
+
])
|
|
455
|
+
|
|
456
|
+
return toMemberView(
|
|
457
|
+
created,
|
|
458
|
+
names.get(targetKey({ targetType: input.targetType, targetId: input.targetId })),
|
|
459
|
+
)
|
|
460
|
+
},
|
|
461
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
462
|
+
)
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
async membershipsFor(actor, targetType, targetId) {
|
|
466
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
467
|
+
// The target must exist. A caller listing memberships of a missing record
|
|
468
|
+
// gets 404, not a silent empty list — same rule as notes/decisions.
|
|
469
|
+
await requireTarget(workspaceId, targetType, targetId)
|
|
470
|
+
|
|
471
|
+
const rows = await repository.listMembershipsForTarget(
|
|
472
|
+
dependencies.db,
|
|
473
|
+
workspaceId,
|
|
474
|
+
targetType,
|
|
475
|
+
targetId,
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
return rows.map(toMembershipView)
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
async removeMember(actor, listId, id) {
|
|
482
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
483
|
+
await require(workspaceId, listId)
|
|
484
|
+
|
|
485
|
+
const existing = await repository.findListMember(dependencies.db, workspaceId, listId, id)
|
|
486
|
+
|
|
487
|
+
if (existing === undefined) {
|
|
488
|
+
throw AppError.notFound('List member not found')
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
await dependencies.transaction(
|
|
492
|
+
async ({ tx, events }) => {
|
|
493
|
+
await repository.deleteListMember(tx, workspaceId, listId, id)
|
|
494
|
+
|
|
495
|
+
events.emit(
|
|
496
|
+
'lists.member.removed',
|
|
497
|
+
{ type: existing.targetType as RecordTargetType, id: existing.targetId },
|
|
498
|
+
{ listId },
|
|
499
|
+
)
|
|
500
|
+
},
|
|
501
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
502
|
+
)
|
|
503
|
+
},
|
|
504
|
+
}
|
|
505
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { RECORD_TARGET_TYPES } from '@kelpie/schemas'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
import type { McpToolRegistry } from '../../runtime/module.ts'
|
|
5
|
+
import {
|
|
6
|
+
deleteResult,
|
|
7
|
+
idArg,
|
|
8
|
+
listWindowShape,
|
|
9
|
+
pageResult,
|
|
10
|
+
registerCrudTools,
|
|
11
|
+
toListQuery,
|
|
12
|
+
} from '../crudTools.ts'
|
|
13
|
+
import {
|
|
14
|
+
addMemberBody,
|
|
15
|
+
createBody,
|
|
16
|
+
listMemberResponse,
|
|
17
|
+
listMembershipResponse,
|
|
18
|
+
listResponse,
|
|
19
|
+
toAddMemberInput,
|
|
20
|
+
toCreateInput,
|
|
21
|
+
toUpdateInput,
|
|
22
|
+
updateBody,
|
|
23
|
+
} from './routes.ts'
|
|
24
|
+
import type { ListsService } from './service.ts'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* `lists_*`. Same schemas and mappers as `/v1/lists`, so the two cannot drift.
|
|
28
|
+
*
|
|
29
|
+
* The list-level five come from `registerCrudTools`; the three membership tools
|
|
30
|
+
* are declared by hand because they hang off `/v1/lists/:id/members`, which does
|
|
31
|
+
* not fit the by-id CRUD shape.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const listArgs = z.strictObject({
|
|
35
|
+
...listWindowShape,
|
|
36
|
+
q: z
|
|
37
|
+
.string()
|
|
38
|
+
.min(1)
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Free text. Matches list names.'),
|
|
41
|
+
target_type: z
|
|
42
|
+
.enum(RECORD_TARGET_TYPES)
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('Only lists that hold this kind of record.'),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const membersListArgs = z.strictObject({
|
|
48
|
+
...listWindowShape,
|
|
49
|
+
list_id: idArg.describe('The list whose members you want.'),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const addMemberArgs = addMemberBody.extend({
|
|
53
|
+
list_id: idArg.describe('The list to add to. Its type must match target_type.'),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const removeMemberArgs = z.strictObject({
|
|
57
|
+
list_id: idArg.describe('The list to remove from.'),
|
|
58
|
+
id: idArg.describe('The membership id, from list_members_list.'),
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const membershipsForArgs = z.strictObject({
|
|
62
|
+
target_type: z.enum(RECORD_TARGET_TYPES).describe('The kind of record.'),
|
|
63
|
+
target_id: idArg.describe('The record whose list memberships you want.'),
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
export function registerListsTools(mcp: McpToolRegistry, service: ListsService): void {
|
|
67
|
+
registerCrudTools(mcp, {
|
|
68
|
+
resource: 'lists',
|
|
69
|
+
subject: 'list',
|
|
70
|
+
about:
|
|
71
|
+
'A named collection of records of one type, chosen when the list is created and fixed for its lifetime.',
|
|
72
|
+
service,
|
|
73
|
+
render: listResponse,
|
|
74
|
+
listArgs,
|
|
75
|
+
toFilters: (args) => ({ term: args.q, targetType: args.target_type }),
|
|
76
|
+
createArgs: createBody,
|
|
77
|
+
toCreateInput,
|
|
78
|
+
updateArgs: updateBody.extend({ id: idArg }),
|
|
79
|
+
toUpdateInput,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
mcp.tool({
|
|
83
|
+
name: 'list_members_list',
|
|
84
|
+
description:
|
|
85
|
+
'List the records on one list. Cursor paged. Mirrors GET /v1/lists/{id}/members.',
|
|
86
|
+
inputSchema: membersListArgs,
|
|
87
|
+
invoke: async (args, actor) =>
|
|
88
|
+
pageResult(
|
|
89
|
+
await service.listMembers(actor, { listId: args.list_id }, toListQuery(args)),
|
|
90
|
+
listMemberResponse,
|
|
91
|
+
),
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
mcp.tool({
|
|
95
|
+
name: 'list_members_add',
|
|
96
|
+
description:
|
|
97
|
+
'Add a record to a list. The record\'s type must match the list\'s. ' +
|
|
98
|
+
'Mirrors POST /v1/lists/{id}/members.',
|
|
99
|
+
inputSchema: addMemberArgs,
|
|
100
|
+
invoke: async (args, actor) =>
|
|
101
|
+
listMemberResponse(await service.addMember(actor, args.list_id, toAddMemberInput(args))),
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
mcp.tool({
|
|
105
|
+
name: 'list_members_remove',
|
|
106
|
+
description:
|
|
107
|
+
'Remove a record from a list. Mirrors DELETE /v1/lists/{id}/members/{memberId}.',
|
|
108
|
+
inputSchema: removeMemberArgs,
|
|
109
|
+
invoke: async (args, actor) => {
|
|
110
|
+
await service.removeMember(actor, args.list_id, args.id)
|
|
111
|
+
|
|
112
|
+
return deleteResult(args.id)
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
mcp.tool({
|
|
117
|
+
name: 'list_memberships_for',
|
|
118
|
+
description:
|
|
119
|
+
'Which lists is this record on? Returns one row per membership, with the ' +
|
|
120
|
+
'list joined in. Mirrors GET /v1/list-memberships.',
|
|
121
|
+
inputSchema: membershipsForArgs,
|
|
122
|
+
invoke: async (args, actor) => {
|
|
123
|
+
const memberships = await service.membershipsFor(actor, args.target_type, args.target_id)
|
|
124
|
+
|
|
125
|
+
return { data: memberships.map(listMembershipResponse), next_cursor: null }
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
}
|
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
|
|