@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UNIQUE_VIOLATION, postgresErrorCode } from '../../lib/database.js';
|
|
1
2
|
import { AppError } from '../../lib/errors.js';
|
|
2
3
|
import { requireCapability } from '../../runtime/entitlements.js';
|
|
3
4
|
import { moduleCapabilityName } from '../../runtime/moduleConfig.js';
|
|
@@ -6,14 +7,26 @@ import '../companies/events.js';
|
|
|
6
7
|
import * as companyRepository from '../companies/repository.js';
|
|
7
8
|
import * as dealRepository from '../deals/repository.js';
|
|
8
9
|
import '../deals/events.js';
|
|
10
|
+
import * as enquiryRepository from '../enquiries/repository.js';
|
|
11
|
+
import '../enquiries/events.js';
|
|
12
|
+
import '../lists/events.js';
|
|
13
|
+
import * as listsRepository from '../lists/repository.js';
|
|
14
|
+
import * as opportunityRepository from '../opportunities/repository.js';
|
|
15
|
+
import '../opportunities/events.js';
|
|
16
|
+
import * as partnershipRepository from '../partnerships/repository.js';
|
|
17
|
+
import '../partnerships/events.js';
|
|
18
|
+
import * as consentPurposesRepository from '../consent-purposes/repository.js';
|
|
9
19
|
import '../people/events.js';
|
|
20
|
+
import { upsertPersonConsent } from '../people/personConsentWrites.js';
|
|
10
21
|
import * as peopleRepository from '../people/repository.js';
|
|
22
|
+
import * as personLinks from '../personLinks.js';
|
|
11
23
|
import * as pipelineRepository from '../pipelines/repository.js';
|
|
12
24
|
import '../positions/events.js';
|
|
13
25
|
import * as positionRepository from '../positions/repository.js';
|
|
26
|
+
import { targetExists } from '../recordTargets.js';
|
|
14
27
|
import * as workspaceRepository from '../workspace/repository.js';
|
|
15
28
|
import './events.js';
|
|
16
|
-
import { DEAL_CLOSE_HORIZON_DAYS, companyNameFrom, describeAnswers,
|
|
29
|
+
import { DEAL_CLOSE_HORIZON_DAYS, companyNameFrom, describeAnswers, expandNameTemplate, expectedCloseFrom, fillBlank, findAnswerProblems, mapAnswers, mergeTags, readConsentGrants, readIntent, } from './mapping.js';
|
|
17
30
|
import * as repository from './repository.js';
|
|
18
31
|
/**
|
|
19
32
|
* The public submit: `forms.md` rules 1 to 7, server-side.
|
|
@@ -63,30 +76,24 @@ const NEW_PERSON_DEFAULTS = {
|
|
|
63
76
|
influence: 'influencer',
|
|
64
77
|
};
|
|
65
78
|
/**
|
|
66
|
-
* One `record.created` per record this submit invented,
|
|
67
|
-
* `record.updated` per record it filled a blank on.
|
|
79
|
+
* One `record.created` per record this submit invented (person, company,
|
|
80
|
+
* position), and one `record.updated` per record it filled a blank on. The
|
|
81
|
+
* pipeline creates (deal, opportunity, partnership) publish their own
|
|
82
|
+
* `*.created` events from inside their action's shim so a rolled-back
|
|
83
|
+
* savepoint drops the event alongside the row.
|
|
68
84
|
*
|
|
69
|
-
* A submit that matched an existing person and changed nothing about them
|
|
70
|
-
* neither: a consumer mirroring the CRM has nothing to mirror, and
|
|
85
|
+
* A submit that matched an existing person and changed nothing about them
|
|
86
|
+
* emits neither: a consumer mirroring the CRM has nothing to mirror, and
|
|
71
87
|
* `form.submitted` already says the submission happened.
|
|
72
|
-
*
|
|
73
|
-
* The Deal has no `Upserted` because it is only ever created, and its people
|
|
74
|
-
* link rides along with it rather than as a separate `record.updated`, the same
|
|
75
|
-
* way the deals service treats a create.
|
|
76
88
|
*/
|
|
77
89
|
function emitRecordEvents(events, workspaceId, touched) {
|
|
78
|
-
|
|
79
|
-
emitUpsertEvent(events, 'person', touched.person);
|
|
80
|
-
}
|
|
90
|
+
emitUpsertEvent(events, 'person', touched.person);
|
|
81
91
|
if (touched.company !== undefined) {
|
|
82
92
|
emitUpsertEvent(events, 'company', touched.company);
|
|
83
93
|
}
|
|
84
94
|
if (touched.position !== undefined) {
|
|
85
95
|
emitUpsertEvent(events, 'position', touched.position);
|
|
86
96
|
}
|
|
87
|
-
if (touched.dealId !== null) {
|
|
88
|
-
events.emit('deals.deal.created', { type: 'deal', id: touched.dealId }, {});
|
|
89
|
-
}
|
|
90
97
|
// workspaceId is used by the transaction scope's envelope stamping; the
|
|
91
98
|
// parameter stays on the signature so future call sites keep the same shape.
|
|
92
99
|
void workspaceId;
|
|
@@ -144,22 +151,34 @@ export function createFormSubmitService(dependencies) {
|
|
|
144
151
|
id: dependencies.createId('person'),
|
|
145
152
|
workspaceId,
|
|
146
153
|
name: intent.personName,
|
|
154
|
+
firstName: intent.personFirstName ?? null,
|
|
155
|
+
lastName: intent.personLastName ?? null,
|
|
147
156
|
email: intent.email,
|
|
148
157
|
lastContactedAt: now,
|
|
149
158
|
...NEW_PERSON_DEFAULTS,
|
|
150
159
|
});
|
|
151
160
|
return { record: created, created: true, filled: [] };
|
|
152
161
|
}
|
|
153
|
-
|
|
162
|
+
// Each part fills its own blank. A stored first name is what the team has
|
|
163
|
+
// learned and an inbound one is what a visitor typed, so the rule that keeps
|
|
164
|
+
// an inbound "Alex" off a stored "Alex Rivera" covers these unchanged.
|
|
165
|
+
const filledName = fillBlank(existing.name, intent.personName);
|
|
166
|
+
const filledFirstName = fillBlank(existing.firstName, intent.personFirstName);
|
|
167
|
+
const filledLastName = fillBlank(existing.lastName, intent.personLastName);
|
|
168
|
+
const changes = {
|
|
169
|
+
...(filledName === undefined ? {} : { name: filledName }),
|
|
170
|
+
...(filledFirstName === undefined ? {} : { firstName: filledFirstName }),
|
|
171
|
+
...(filledLastName === undefined ? {} : { lastName: filledLastName }),
|
|
172
|
+
};
|
|
154
173
|
const updated = await peopleRepository.updatePerson(tx, workspaceId, existing.id, {
|
|
155
|
-
...
|
|
174
|
+
...changes,
|
|
156
175
|
lastContactedAt: now,
|
|
157
176
|
updatedAt: now,
|
|
158
177
|
});
|
|
159
178
|
if (updated === undefined) {
|
|
160
179
|
throw new Error(`Person ${existing.id} disappeared during a form submit`);
|
|
161
180
|
}
|
|
162
|
-
return { record: updated, created: false, filled:
|
|
181
|
+
return { record: updated, created: false, filled: Object.keys(changes) };
|
|
163
182
|
}
|
|
164
183
|
/**
|
|
165
184
|
* Upserts the Company, by domain when there is one and by name otherwise
|
|
@@ -233,20 +252,57 @@ export function createFormSubmitService(dependencies) {
|
|
|
233
252
|
});
|
|
234
253
|
return { record: created, created: true, filled: [] };
|
|
235
254
|
}
|
|
236
|
-
/**
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
255
|
+
/**
|
|
256
|
+
* The stage a form's created record opens in: the one the form names, or
|
|
257
|
+
* the pipeline's first open stage. Shared by the three create-triggers.
|
|
258
|
+
*/
|
|
259
|
+
async function openingStageId(tx, workspaceId, kind, configured) {
|
|
260
|
+
if (configured !== null) {
|
|
261
|
+
return configured;
|
|
240
262
|
}
|
|
241
|
-
const stages = await pipelineRepository.listStagesOfKind(tx, workspaceId,
|
|
263
|
+
const stages = await pipelineRepository.listStagesOfKind(tx, workspaceId, kind);
|
|
242
264
|
const first = stages.find((stage) => stage.open) ?? stages[0];
|
|
243
265
|
if (first === undefined) {
|
|
244
266
|
// Unreachable through the API: a workspace seeds its stages at creation
|
|
245
267
|
// and the last stage of a pipeline cannot be removed.
|
|
246
|
-
throw AppError.conflict(
|
|
268
|
+
throw AppError.conflict(`This workspace has no ${kind} stages`);
|
|
247
269
|
}
|
|
248
270
|
return first.id;
|
|
249
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Runs `work` under a nested `tx.transaction()` — a SAVEPOINT in
|
|
274
|
+
* postgres-js — and captures every event the action emits into a local
|
|
275
|
+
* buffer. On success (`ok` or `skipped`) the events are forwarded to the
|
|
276
|
+
* real `BufferedEvents`; on throw the savepoint has already rolled back so
|
|
277
|
+
* the events are discarded and a `{status: 'error'}` entry lands on the log.
|
|
278
|
+
* Either way the outer transaction stays alive: the next action runs, and
|
|
279
|
+
* the visitor's 201 survives.
|
|
280
|
+
*/
|
|
281
|
+
async function runAction(tx, events, log, action, work) {
|
|
282
|
+
const pending = [];
|
|
283
|
+
const emit = (name, target, data) => {
|
|
284
|
+
pending.push({ name, target, data });
|
|
285
|
+
};
|
|
286
|
+
try {
|
|
287
|
+
const result = await tx.transaction(async (inner) => work(inner, emit));
|
|
288
|
+
log.push({ action, status: result.status, detail: result.detail });
|
|
289
|
+
for (const event of pending) {
|
|
290
|
+
// The typed emit rejects an unrelated (name, data) pair; the shim
|
|
291
|
+
// captured them as one call so the pair is already validated.
|
|
292
|
+
events.emit(event.name, event.target, event.data);
|
|
293
|
+
}
|
|
294
|
+
return result.value;
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
const detail = error instanceof AppError
|
|
298
|
+
? error.message
|
|
299
|
+
: error instanceof Error
|
|
300
|
+
? error.message
|
|
301
|
+
: 'unknown error';
|
|
302
|
+
log.push({ action, status: 'error', detail });
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
250
306
|
/**
|
|
251
307
|
* Creates the Deal, when the form makes them and a company was resolved.
|
|
252
308
|
*
|
|
@@ -254,25 +310,144 @@ export function createFormSubmitService(dependencies) {
|
|
|
254
310
|
* that resolved none creates no deal and says so through a null `deal_id` on
|
|
255
311
|
* the submission rather than by inventing one.
|
|
256
312
|
*/
|
|
257
|
-
async function createDeal(tx, workspaceId, form, intent, company, personId) {
|
|
313
|
+
async function createDeal(tx, emit, workspaceId, form, intent, company, personId) {
|
|
258
314
|
const id = dependencies.createId('deal');
|
|
259
315
|
const owner = await workspaceRepository.findDefaultMember(tx, workspaceId);
|
|
260
316
|
await dealRepository.insertDeal(tx, {
|
|
261
317
|
id,
|
|
262
318
|
workspaceId,
|
|
263
319
|
name: intent.dealName ??
|
|
264
|
-
|
|
320
|
+
expandNameTemplate(form.dealNameTemplate ?? DEFAULT_DEAL_NAME_TEMPLATE, {
|
|
265
321
|
companyName: company.name,
|
|
266
322
|
personName: intent.personName,
|
|
267
323
|
}),
|
|
268
324
|
companyId: company.id,
|
|
269
|
-
stageId: await openingStageId(tx, workspaceId, form),
|
|
325
|
+
stageId: await openingStageId(tx, workspaceId, 'deal', form.dealStageId),
|
|
270
326
|
valueCents: 0,
|
|
271
327
|
currency: null,
|
|
272
328
|
ownerId: owner?.id ?? null,
|
|
273
329
|
expectedClose: expectedCloseFrom(dependencies.now(), DEAL_CLOSE_HORIZON_DAYS),
|
|
274
330
|
});
|
|
275
|
-
await
|
|
331
|
+
await personLinks.linkPeople(tx, dependencies.createId, workspaceId, { targetType: 'deal', targetId: id }, [personId]);
|
|
332
|
+
await dependencies.recordActivity(tx, workspaceId, FORM_ACTOR, {
|
|
333
|
+
targetType: 'deal',
|
|
334
|
+
targetId: id,
|
|
335
|
+
kind: 'created',
|
|
336
|
+
...describeCreationVia('Deal', form.name),
|
|
337
|
+
});
|
|
338
|
+
emit('deals.deal.created', { type: 'deal', id }, {});
|
|
339
|
+
return id;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Creates the Opportunity, when the form makes them.
|
|
343
|
+
*
|
|
344
|
+
* `opportunities.company_id` is nullable, so a submit that resolved no
|
|
345
|
+
* company still creates the opportunity, with the company link null. The
|
|
346
|
+
* kind is required at form-write time (see `service.ts`), so it is always
|
|
347
|
+
* present here.
|
|
348
|
+
*/
|
|
349
|
+
async function createOpportunity(tx, emit, workspaceId, form, intent, company, personId) {
|
|
350
|
+
const id = dependencies.createId('opportunity');
|
|
351
|
+
const owner = form.opportunityOwnerId === null
|
|
352
|
+
? await workspaceRepository.findDefaultMember(tx, workspaceId)
|
|
353
|
+
: { id: form.opportunityOwnerId };
|
|
354
|
+
await opportunityRepository.insertOpportunity(tx, {
|
|
355
|
+
id,
|
|
356
|
+
workspaceId,
|
|
357
|
+
name: intent.opportunityName ??
|
|
358
|
+
expandNameTemplate(form.opportunityNameTemplate ?? DEFAULT_DEAL_NAME_TEMPLATE, {
|
|
359
|
+
companyName: company?.name ?? '',
|
|
360
|
+
personName: intent.personName,
|
|
361
|
+
}),
|
|
362
|
+
// requireKindWhenCreating refuses an empty kind at write; the ?? is a
|
|
363
|
+
// narrowing convenience, not a runtime fallback.
|
|
364
|
+
kind: form.opportunityKind ?? '',
|
|
365
|
+
stageId: await openingStageId(tx, workspaceId, 'opportunity', form.opportunityStageId),
|
|
366
|
+
companyId: company?.id ?? null,
|
|
367
|
+
ownerId: owner?.id ?? null,
|
|
368
|
+
expectedClose: expectedCloseFrom(dependencies.now(), DEAL_CLOSE_HORIZON_DAYS),
|
|
369
|
+
});
|
|
370
|
+
await personLinks.linkPeople(tx, dependencies.createId, workspaceId, { targetType: 'opportunity', targetId: id }, [personId]);
|
|
371
|
+
await dependencies.recordActivity(tx, workspaceId, FORM_ACTOR, {
|
|
372
|
+
targetType: 'opportunity',
|
|
373
|
+
targetId: id,
|
|
374
|
+
kind: 'created',
|
|
375
|
+
...describeCreationVia('Opportunity', form.name),
|
|
376
|
+
});
|
|
377
|
+
emit('opportunities.opportunity.created', { type: 'opportunity', id }, {});
|
|
378
|
+
return id;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Creates the Partnership, when the form makes them and a company was
|
|
382
|
+
* resolved. `partnerships.company_id` is `NOT NULL`, matching Deal.
|
|
383
|
+
*/
|
|
384
|
+
async function createPartnership(tx, emit, workspaceId, form, intent, company, personId) {
|
|
385
|
+
const id = dependencies.createId('partnership');
|
|
386
|
+
const owner = form.partnershipOwnerId === null
|
|
387
|
+
? await workspaceRepository.findDefaultMember(tx, workspaceId)
|
|
388
|
+
: { id: form.partnershipOwnerId };
|
|
389
|
+
const nextTouchpoint = expectedCloseFrom(dependencies.now(), DEAL_CLOSE_HORIZON_DAYS);
|
|
390
|
+
await partnershipRepository.insertPartnership(tx, {
|
|
391
|
+
id,
|
|
392
|
+
workspaceId,
|
|
393
|
+
name: intent.partnershipName ??
|
|
394
|
+
expandNameTemplate(form.partnershipNameTemplate ?? DEFAULT_DEAL_NAME_TEMPLATE, {
|
|
395
|
+
companyName: company.name,
|
|
396
|
+
personName: intent.personName,
|
|
397
|
+
}),
|
|
398
|
+
companyId: company.id,
|
|
399
|
+
stageId: await openingStageId(tx, workspaceId, 'partnership', form.partnershipStageId),
|
|
400
|
+
kind: form.partnershipKind ?? '',
|
|
401
|
+
nextTouchpoint,
|
|
402
|
+
ownerId: owner?.id ?? null,
|
|
403
|
+
goals: '',
|
|
404
|
+
successLooksLike: '',
|
|
405
|
+
});
|
|
406
|
+
await personLinks.linkPeople(tx, dependencies.createId, workspaceId, { targetType: 'partnership', targetId: id }, [personId]);
|
|
407
|
+
await dependencies.recordActivity(tx, workspaceId, FORM_ACTOR, {
|
|
408
|
+
targetType: 'partnership',
|
|
409
|
+
targetId: id,
|
|
410
|
+
kind: 'created',
|
|
411
|
+
...describeCreationVia('Partnership', form.name),
|
|
412
|
+
});
|
|
413
|
+
emit('partnerships.partnership.created', { type: 'partnership', id }, {});
|
|
414
|
+
return id;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Creates the Enquiry, when the form makes them.
|
|
418
|
+
*
|
|
419
|
+
* `enquiries.company_id` is nullable, so a submit that resolved no company
|
|
420
|
+
* still creates the enquiry. Enquiries have no `kind`; the form's optional
|
|
421
|
+
* `enquirySource` is written to the enquiry's `source` column, or empty when
|
|
422
|
+
* unset — an unclassified source reads as unclassified.
|
|
423
|
+
*/
|
|
424
|
+
async function createEnquiry(tx, emit, workspaceId, form, intent, company, personId) {
|
|
425
|
+
const id = dependencies.createId('enquiry');
|
|
426
|
+
const owner = form.enquiryOwnerId === null
|
|
427
|
+
? await workspaceRepository.findDefaultMember(tx, workspaceId)
|
|
428
|
+
: { id: form.enquiryOwnerId };
|
|
429
|
+
await enquiryRepository.insertEnquiry(tx, {
|
|
430
|
+
id,
|
|
431
|
+
workspaceId,
|
|
432
|
+
name: intent.enquiryName ??
|
|
433
|
+
expandNameTemplate(form.enquiryNameTemplate ?? DEFAULT_DEAL_NAME_TEMPLATE, {
|
|
434
|
+
companyName: company?.name ?? '',
|
|
435
|
+
personName: intent.personName,
|
|
436
|
+
}),
|
|
437
|
+
source: form.enquirySource ?? '',
|
|
438
|
+
stageId: await openingStageId(tx, workspaceId, 'enquiry', form.enquiryStageId),
|
|
439
|
+
companyId: company?.id ?? null,
|
|
440
|
+
ownerId: owner?.id ?? null,
|
|
441
|
+
convertedDealId: null,
|
|
442
|
+
});
|
|
443
|
+
await personLinks.linkPeople(tx, dependencies.createId, workspaceId, { targetType: 'enquiry', targetId: id }, [personId]);
|
|
444
|
+
await dependencies.recordActivity(tx, workspaceId, FORM_ACTOR, {
|
|
445
|
+
targetType: 'enquiry',
|
|
446
|
+
targetId: id,
|
|
447
|
+
kind: 'created',
|
|
448
|
+
...describeCreationVia('Enquiry', form.name),
|
|
449
|
+
});
|
|
450
|
+
emit('enquiries.enquiry.created', { type: 'enquiry', id }, {});
|
|
276
451
|
return id;
|
|
277
452
|
}
|
|
278
453
|
/**
|
|
@@ -310,21 +485,217 @@ export function createFormSubmitService(dependencies) {
|
|
|
310
485
|
}
|
|
311
486
|
return intent;
|
|
312
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* The purposes any grants name, keyed by id, so the submit transaction
|
|
490
|
+
* knows the slug and label without a per-grant round trip.
|
|
491
|
+
*/
|
|
492
|
+
async function loadPurposesForGrants(db, workspaceId, grants) {
|
|
493
|
+
if (grants.length === 0)
|
|
494
|
+
return new Map();
|
|
495
|
+
const ids = Array.from(new Set(grants.map((grant) => grant.purposeId)));
|
|
496
|
+
const rows = await consentPurposesRepository.listPurposesByIds(db, workspaceId, ids);
|
|
497
|
+
return new Map(rows.map((row) => [row.id, { slug: row.slug, label: row.label }]));
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Writes each ticked grant as a `person_consents` row and appends an
|
|
501
|
+
* Activity to the person carrying the verbatim statement. A grant whose
|
|
502
|
+
* purpose has since been removed is silently skipped — the form's own
|
|
503
|
+
* consent field would have been left dangling anyway, and the submit
|
|
504
|
+
* cannot know that from the answer alone.
|
|
505
|
+
*/
|
|
506
|
+
async function applyFormConsentGrants(tx, workspaceId, formId, formName, personId, grants, purposes, deps) {
|
|
507
|
+
if (grants.length === 0)
|
|
508
|
+
return;
|
|
509
|
+
const now = deps.now();
|
|
510
|
+
const source = `form:${formId}`;
|
|
511
|
+
for (const grant of grants) {
|
|
512
|
+
const purpose = purposes.get(grant.purposeId);
|
|
513
|
+
if (purpose === undefined)
|
|
514
|
+
continue;
|
|
515
|
+
await upsertPersonConsent(tx, workspaceId, personId, grant.purposeId, purpose.slug, purpose.label, 'granted', source, now);
|
|
516
|
+
// The exact text the visitor ticked — the field's per-purpose override
|
|
517
|
+
// when set, else the workspace purpose's label. Recorded as the
|
|
518
|
+
// Activity detail so the timeline shows what they actually saw.
|
|
519
|
+
const ticked = grant.customLabel.length > 0 ? grant.customLabel : purpose.label;
|
|
520
|
+
const detail = grant.statement.length > 0 ? `${grant.statement} — ${ticked}` : ticked;
|
|
521
|
+
await deps.recordActivity(tx, workspaceId, FORM_ACTOR, {
|
|
522
|
+
targetType: 'person',
|
|
523
|
+
targetId: personId,
|
|
524
|
+
kind: 'updated',
|
|
525
|
+
action: `granted ${purpose.label} consent via ${formName}`,
|
|
526
|
+
detail,
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
313
530
|
return {
|
|
314
531
|
async submit(publicKey, answers) {
|
|
315
532
|
const form = await requireOpenForm(publicKey);
|
|
316
533
|
const { workspaceId } = form;
|
|
317
534
|
const fields = await repository.listFields(dependencies.db, form.id);
|
|
318
535
|
const intent = readAnswers(fields, answers);
|
|
536
|
+
const consentGrants = readConsentGrants(fields, answers);
|
|
537
|
+
const [formListRows, attachTargets, consentPurposesForGrants] = await Promise.all([
|
|
538
|
+
repository.listFormLists(dependencies.db, form.id),
|
|
539
|
+
repository.listAttachTargets(dependencies.db, form.id),
|
|
540
|
+
loadPurposesForGrants(dependencies.db, workspaceId, consentGrants),
|
|
541
|
+
]);
|
|
319
542
|
return dependencies.transaction(async ({ tx, events }) => {
|
|
543
|
+
// Core capture: atomic. A failure here fails the submit; every
|
|
544
|
+
// post-action below runs under its own savepoint and logs.
|
|
320
545
|
const person = await upsertPerson(tx, workspaceId, intent);
|
|
321
546
|
const company = await upsertCompany(tx, workspaceId, intent);
|
|
322
547
|
const position = company === undefined || intent.positionTitle === undefined
|
|
323
548
|
? undefined
|
|
324
549
|
: await upsertPosition(tx, workspaceId, person.record.id, company.record.id, intent.positionTitle);
|
|
325
|
-
|
|
326
|
-
|
|
550
|
+
// Consent grants (from ticked `consent` fields) are core capture, not
|
|
551
|
+
// post-actions: they commit with the person, and an Activity records
|
|
552
|
+
// the exact statement text as it was shown to the visitor.
|
|
553
|
+
await applyFormConsentGrants(tx, workspaceId, form.id, form.name, person.record.id, consentGrants, consentPurposesForGrants, dependencies);
|
|
554
|
+
const actionLog = [];
|
|
555
|
+
// --- Create triggers ---
|
|
556
|
+
const dealId = form.createDeal
|
|
557
|
+
? ((await runAction(tx, events, actionLog, 'create_deal', async (inner, emit) => {
|
|
558
|
+
if (company === undefined) {
|
|
559
|
+
return { status: 'skipped', detail: 'no company resolved' };
|
|
560
|
+
}
|
|
561
|
+
const id = await createDeal(inner, emit, workspaceId, form, intent, company.record, person.record.id);
|
|
562
|
+
return { status: 'ok', detail: id, value: id };
|
|
563
|
+
})) ?? null)
|
|
564
|
+
: null;
|
|
565
|
+
const opportunityId = form.createOpportunity
|
|
566
|
+
? ((await runAction(tx, events, actionLog, 'create_opportunity', async (inner, emit) => {
|
|
567
|
+
const id = await createOpportunity(inner, emit, workspaceId, form, intent, company?.record, person.record.id);
|
|
568
|
+
return { status: 'ok', detail: id, value: id };
|
|
569
|
+
})) ?? null)
|
|
327
570
|
: null;
|
|
571
|
+
const partnershipId = form.createPartnership
|
|
572
|
+
? ((await runAction(tx, events, actionLog, 'create_partnership', async (inner, emit) => {
|
|
573
|
+
if (company === undefined) {
|
|
574
|
+
return { status: 'skipped', detail: 'no company resolved' };
|
|
575
|
+
}
|
|
576
|
+
const id = await createPartnership(inner, emit, workspaceId, form, intent, company.record, person.record.id);
|
|
577
|
+
return { status: 'ok', detail: id, value: id };
|
|
578
|
+
})) ?? null)
|
|
579
|
+
: null;
|
|
580
|
+
const enquiryId = form.createEnquiry
|
|
581
|
+
? ((await runAction(tx, events, actionLog, 'create_enquiry', async (inner, emit) => {
|
|
582
|
+
const id = await createEnquiry(inner, emit, workspaceId, form, intent, company?.record, person.record.id);
|
|
583
|
+
return { status: 'ok', detail: id, value: id };
|
|
584
|
+
})) ?? null)
|
|
585
|
+
: null;
|
|
586
|
+
// --- Tag merges ---
|
|
587
|
+
if (form.personTags.length > 0) {
|
|
588
|
+
await runAction(tx, events, actionLog, 'tag_person', async (inner, emit) => {
|
|
589
|
+
const merged = mergeTags(person.record.tags, form.personTags);
|
|
590
|
+
if (!merged.changed) {
|
|
591
|
+
return { status: 'ok', detail: 'no new tags' };
|
|
592
|
+
}
|
|
593
|
+
const now = dependencies.now();
|
|
594
|
+
await peopleRepository.updatePerson(inner, workspaceId, person.record.id, {
|
|
595
|
+
tags: [...merged.next],
|
|
596
|
+
updatedAt: now,
|
|
597
|
+
});
|
|
598
|
+
emit('people.person.updated', { type: 'person', id: person.record.id }, { changed: ['tags'] });
|
|
599
|
+
return { status: 'ok', detail: `merged ${String(merged.next.length - person.record.tags.length)}` };
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
if (form.companyTags.length > 0) {
|
|
603
|
+
await runAction(tx, events, actionLog, 'tag_company', async (inner, emit) => {
|
|
604
|
+
if (company === undefined) {
|
|
605
|
+
return { status: 'skipped', detail: 'no company resolved' };
|
|
606
|
+
}
|
|
607
|
+
const merged = mergeTags(company.record.tags, form.companyTags);
|
|
608
|
+
if (!merged.changed) {
|
|
609
|
+
return { status: 'ok', detail: 'no new tags' };
|
|
610
|
+
}
|
|
611
|
+
const now = dependencies.now();
|
|
612
|
+
await companyRepository.updateCompany(inner, workspaceId, company.record.id, {
|
|
613
|
+
tags: [...merged.next],
|
|
614
|
+
updatedAt: now,
|
|
615
|
+
});
|
|
616
|
+
emit('companies.company.updated', { type: 'company', id: company.record.id }, { changed: ['tags'] });
|
|
617
|
+
return { status: 'ok', detail: `merged ${String(merged.next.length - company.record.tags.length)}` };
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
// --- List memberships ---
|
|
621
|
+
// Every purpose named by a person list on this form, so consent
|
|
622
|
+
// capture below needs no per-row round trip.
|
|
623
|
+
const listConsentPurposeIds = Array.from(new Set(formListRows
|
|
624
|
+
.map((row) => row.consentPurposeId)
|
|
625
|
+
.filter((id) => id !== null)));
|
|
626
|
+
const listConsentPurposes = listConsentPurposeIds.length === 0
|
|
627
|
+
? new Map()
|
|
628
|
+
: new Map((await consentPurposesRepository.listPurposesByIds(tx, workspaceId, listConsentPurposeIds)).map((row) => [row.id, { slug: row.slug, label: row.label }]));
|
|
629
|
+
for (const row of formListRows) {
|
|
630
|
+
const inserted = await runAction(tx, events, actionLog, `add_list:${row.listId}`, async (inner, emit) => {
|
|
631
|
+
const targetId = row.targetType === 'person'
|
|
632
|
+
? person.record.id
|
|
633
|
+
: row.targetType === 'company' && company !== undefined
|
|
634
|
+
? company.record.id
|
|
635
|
+
: undefined;
|
|
636
|
+
if (targetId === undefined) {
|
|
637
|
+
return { status: 'skipped', detail: 'no company resolved', value: false };
|
|
638
|
+
}
|
|
639
|
+
try {
|
|
640
|
+
await listsRepository.insertListMember(inner, {
|
|
641
|
+
id: dependencies.createId('listMember'),
|
|
642
|
+
workspaceId,
|
|
643
|
+
listId: row.listId,
|
|
644
|
+
targetType: row.targetType,
|
|
645
|
+
targetId,
|
|
646
|
+
addedAt: dependencies.now(),
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
catch (error) {
|
|
650
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
651
|
+
return { status: 'ok', detail: 'already a member', value: false };
|
|
652
|
+
}
|
|
653
|
+
throw error;
|
|
654
|
+
}
|
|
655
|
+
emit('lists.member.added', { type: row.targetType, id: targetId }, { listId: row.listId });
|
|
656
|
+
return { status: 'ok', detail: targetId, value: true };
|
|
657
|
+
});
|
|
658
|
+
// Consent capture rides with the add — only on person lists, only
|
|
659
|
+
// when the list carries a purpose, and only when we actually added
|
|
660
|
+
// (or the person was already on it, since a returning submitter
|
|
661
|
+
// did the same thing again). A record already on the list has
|
|
662
|
+
// already been consented for its purpose; the upsert reflects
|
|
663
|
+
// that a fresh submit is fresh evidence.
|
|
664
|
+
if (row.targetType === 'person' &&
|
|
665
|
+
row.consentPurposeId !== null &&
|
|
666
|
+
inserted !== null) {
|
|
667
|
+
const purpose = listConsentPurposes.get(row.consentPurposeId);
|
|
668
|
+
if (purpose !== undefined) {
|
|
669
|
+
await runAction(tx, events, actionLog, `consent:${row.listId}`, async (inner) => {
|
|
670
|
+
await upsertPersonConsent(inner, workspaceId, person.record.id, row.consentPurposeId, purpose.slug, purpose.label, 'granted', `list:${row.listId}`, dependencies.now());
|
|
671
|
+
await dependencies.recordActivity(inner, workspaceId, FORM_ACTOR, {
|
|
672
|
+
targetType: 'person',
|
|
673
|
+
targetId: person.record.id,
|
|
674
|
+
kind: 'updated',
|
|
675
|
+
action: `granted ${purpose.label} consent via ${form.name}`,
|
|
676
|
+
detail: `Added to list membership`,
|
|
677
|
+
});
|
|
678
|
+
return { status: 'ok', detail: purpose.slug };
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
// --- Attach the submitter to pre-existing pipeline records ---
|
|
684
|
+
for (const target of attachTargets) {
|
|
685
|
+
await runAction(tx, events, actionLog, `attach:${target.targetType}:${target.targetId}`, async (inner) => {
|
|
686
|
+
// Racing a target delete would fail the FK-less insert with the
|
|
687
|
+
// same effect as an existence check: log an error, continue.
|
|
688
|
+
if (!(await targetExists(inner, workspaceId, target.targetType, target.targetId))) {
|
|
689
|
+
throw AppError.notFound(`${target.targetType} ${target.targetId} not found`);
|
|
690
|
+
}
|
|
691
|
+
const inserted = await personLinks.linkPersonIfAbsent(inner, dependencies.createId, workspaceId, target, person.record.id);
|
|
692
|
+
return {
|
|
693
|
+
status: 'ok',
|
|
694
|
+
detail: inserted ? 'linked' : 'already linked',
|
|
695
|
+
};
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
// --- Persist submission + core activity + record events ---
|
|
328
699
|
const submission = await repository.insertSubmission(tx, {
|
|
329
700
|
id: dependencies.createId('formSubmission'),
|
|
330
701
|
workspaceId,
|
|
@@ -334,7 +705,11 @@ export function createFormSubmitService(dependencies) {
|
|
|
334
705
|
companyId: company?.record.id ?? null,
|
|
335
706
|
positionId: position?.record.id ?? null,
|
|
336
707
|
dealId,
|
|
708
|
+
opportunityId,
|
|
709
|
+
partnershipId,
|
|
710
|
+
enquiryId,
|
|
337
711
|
submittedAt: dependencies.now(),
|
|
712
|
+
actionLog,
|
|
338
713
|
});
|
|
339
714
|
await dependencies.recordActivity(tx, workspaceId, FORM_ACTOR, {
|
|
340
715
|
targetType: 'person',
|
|
@@ -342,16 +717,15 @@ export function createFormSubmitService(dependencies) {
|
|
|
342
717
|
kind: 'created',
|
|
343
718
|
...describeFormSubmission(form.name, describeAnswers(fields, answers)),
|
|
344
719
|
});
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
events.emit('forms.submission.submitted', { type: 'submission', id: submission.id }, { formId: form.id, submissionId: submission.id });
|
|
720
|
+
emitRecordEvents(events, workspaceId, { person, company, position });
|
|
721
|
+
events.emit('forms.submission.submitted', { type: 'submission', id: submission.id }, {
|
|
722
|
+
formId: form.id,
|
|
723
|
+
submissionId: submission.id,
|
|
724
|
+
opportunityId,
|
|
725
|
+
partnershipId,
|
|
726
|
+
enquiryId,
|
|
727
|
+
actions: actionLog.map((entry) => ({ action: entry.action, status: entry.status })),
|
|
728
|
+
});
|
|
355
729
|
return {
|
|
356
730
|
submissionId: submission.id,
|
|
357
731
|
formId: form.id,
|
|
@@ -359,8 +733,12 @@ export function createFormSubmitService(dependencies) {
|
|
|
359
733
|
companyId: company?.record.id ?? null,
|
|
360
734
|
positionId: position?.record.id ?? null,
|
|
361
735
|
dealId,
|
|
736
|
+
opportunityId,
|
|
737
|
+
partnershipId,
|
|
738
|
+
enquiryId,
|
|
362
739
|
submittedAt: submission.submittedAt,
|
|
363
740
|
thankYouMessage: form.thankYouMessage,
|
|
741
|
+
actionLog,
|
|
364
742
|
};
|
|
365
743
|
}, { workspaceId });
|
|
366
744
|
},
|