@kelpie/server 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ids.d.ts +11 -0
- package/dist/lib/ids.d.ts.map +1 -1
- package/dist/lib/ids.js +11 -0
- package/dist/lib/ids.js.map +1 -1
- package/dist/modules/activities/repository.d.ts.map +1 -1
- package/dist/modules/activities/repository.js +19 -20
- package/dist/modules/activities/repository.js.map +1 -1
- package/dist/modules/activities/wording.d.ts +12 -0
- package/dist/modules/activities/wording.d.ts.map +1 -1
- package/dist/modules/activities/wording.js +16 -0
- package/dist/modules/activities/wording.js.map +1 -1
- package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
- package/dist/modules/agent-tasks/catalog.js +62 -0
- package/dist/modules/agent-tasks/catalog.js.map +1 -1
- package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
- package/dist/modules/agent-tasks/resolve.js +42 -9
- package/dist/modules/agent-tasks/resolve.js.map +1 -1
- package/dist/modules/agent-tasks/routes.d.ts +2 -0
- package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
- package/dist/modules/attachedRecords.d.ts +6 -1
- package/dist/modules/attachedRecords.d.ts.map +1 -1
- package/dist/modules/attachedRecords.js +15 -1
- package/dist/modules/attachedRecords.js.map +1 -1
- package/dist/modules/companies/index.d.ts.map +1 -1
- package/dist/modules/companies/index.js +3 -1
- package/dist/modules/companies/index.js.map +1 -1
- package/dist/modules/companies/routes.d.ts +14 -0
- package/dist/modules/companies/routes.d.ts.map +1 -1
- package/dist/modules/companies/routes.js +7 -0
- package/dist/modules/companies/routes.js.map +1 -1
- package/dist/modules/companies/schema.d.ts +20 -0
- package/dist/modules/companies/schema.d.ts.map +1 -1
- package/dist/modules/companies/schema.js +6 -1
- package/dist/modules/companies/schema.js.map +1 -1
- package/dist/modules/companies/service.d.ts +5 -0
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +24 -12
- package/dist/modules/companies/service.js.map +1 -1
- package/dist/modules/consent-purposes/capabilities.d.ts +7 -0
- package/dist/modules/consent-purposes/capabilities.d.ts.map +1 -0
- package/dist/modules/consent-purposes/capabilities.js +10 -0
- package/dist/modules/consent-purposes/capabilities.js.map +1 -0
- package/dist/modules/consent-purposes/events.d.ts +38 -0
- package/dist/modules/consent-purposes/events.d.ts.map +1 -0
- package/dist/modules/consent-purposes/events.js +17 -0
- package/dist/modules/consent-purposes/events.js.map +1 -0
- package/dist/modules/consent-purposes/index.d.ts +13 -0
- package/dist/modules/consent-purposes/index.d.ts.map +1 -0
- package/dist/modules/consent-purposes/index.js +41 -0
- package/dist/modules/consent-purposes/index.js.map +1 -0
- package/dist/modules/consent-purposes/repository.d.ts +21 -0
- package/dist/modules/consent-purposes/repository.d.ts.map +1 -0
- package/dist/modules/consent-purposes/repository.js +98 -0
- package/dist/modules/consent-purposes/repository.js.map +1 -0
- package/dist/modules/consent-purposes/routes.d.ts +39 -0
- package/dist/modules/consent-purposes/routes.d.ts.map +1 -0
- package/dist/modules/consent-purposes/routes.js +79 -0
- package/dist/modules/consent-purposes/routes.js.map +1 -0
- package/dist/modules/consent-purposes/schema.d.ts +175 -0
- package/dist/modules/consent-purposes/schema.d.ts.map +1 -0
- package/dist/modules/consent-purposes/schema.js +35 -0
- package/dist/modules/consent-purposes/schema.js.map +1 -0
- package/dist/modules/consent-purposes/service.d.ts +50 -0
- package/dist/modules/consent-purposes/service.d.ts.map +1 -0
- package/dist/modules/consent-purposes/service.js +263 -0
- package/dist/modules/consent-purposes/service.js.map +1 -0
- package/dist/modules/consent-purposes/starters.d.ts +17 -0
- package/dist/modules/consent-purposes/starters.d.ts.map +1 -0
- package/dist/modules/consent-purposes/starters.js +15 -0
- package/dist/modules/consent-purposes/starters.js.map +1 -0
- package/dist/modules/consent-purposes/tools.d.ts +4 -0
- package/dist/modules/consent-purposes/tools.d.ts.map +1 -0
- package/dist/modules/consent-purposes/tools.js +29 -0
- package/dist/modules/consent-purposes/tools.js.map +1 -0
- package/dist/modules/core.d.ts.map +1 -1
- package/dist/modules/core.js +10 -0
- package/dist/modules/core.js.map +1 -1
- package/dist/modules/custom-fields/capabilities.d.ts +12 -0
- package/dist/modules/custom-fields/capabilities.d.ts.map +1 -0
- package/dist/modules/custom-fields/capabilities.js +15 -0
- package/dist/modules/custom-fields/capabilities.js.map +1 -0
- package/dist/modules/custom-fields/events.d.ts +49 -0
- package/dist/modules/custom-fields/events.d.ts.map +1 -0
- package/dist/modules/custom-fields/events.js +25 -0
- package/dist/modules/custom-fields/events.js.map +1 -0
- package/dist/modules/custom-fields/index.d.ts +19 -0
- package/dist/modules/custom-fields/index.d.ts.map +1 -0
- package/dist/modules/custom-fields/index.js +46 -0
- package/dist/modules/custom-fields/index.js.map +1 -0
- package/dist/modules/custom-fields/repository.d.ts +37 -0
- package/dist/modules/custom-fields/repository.d.ts.map +1 -0
- package/dist/modules/custom-fields/repository.js +144 -0
- package/dist/modules/custom-fields/repository.js.map +1 -0
- package/dist/modules/custom-fields/routes.d.ts +44 -0
- package/dist/modules/custom-fields/routes.d.ts.map +1 -0
- package/dist/modules/custom-fields/routes.js +103 -0
- package/dist/modules/custom-fields/routes.js.map +1 -0
- package/dist/modules/custom-fields/schema.d.ts +215 -0
- package/dist/modules/custom-fields/schema.d.ts.map +1 -0
- package/dist/modules/custom-fields/schema.js +43 -0
- package/dist/modules/custom-fields/schema.js.map +1 -0
- package/dist/modules/custom-fields/service.d.ts +57 -0
- package/dist/modules/custom-fields/service.d.ts.map +1 -0
- package/dist/modules/custom-fields/service.js +273 -0
- package/dist/modules/custom-fields/service.js.map +1 -0
- package/dist/modules/custom-fields/tools.d.ts +4 -0
- package/dist/modules/custom-fields/tools.d.ts.map +1 -0
- package/dist/modules/custom-fields/tools.js +38 -0
- package/dist/modules/custom-fields/tools.js.map +1 -0
- package/dist/modules/custom-fields/values.d.ts +49 -0
- package/dist/modules/custom-fields/values.d.ts.map +1 -0
- package/dist/modules/custom-fields/values.js +249 -0
- package/dist/modules/custom-fields/values.js.map +1 -0
- package/dist/modules/custom-fields/wire.d.ts +12 -0
- package/dist/modules/custom-fields/wire.d.ts.map +1 -0
- package/dist/modules/custom-fields/wire.js +30 -0
- package/dist/modules/custom-fields/wire.js.map +1 -0
- package/dist/modules/dashboard/repository.d.ts.map +1 -1
- package/dist/modules/dashboard/repository.js +4 -3
- package/dist/modules/dashboard/repository.js.map +1 -1
- package/dist/modules/deals/index.d.ts +2 -1
- package/dist/modules/deals/index.d.ts.map +1 -1
- package/dist/modules/deals/index.js +5 -2
- package/dist/modules/deals/index.js.map +1 -1
- package/dist/modules/deals/repository.d.ts +0 -16
- package/dist/modules/deals/repository.d.ts.map +1 -1
- package/dist/modules/deals/repository.js +6 -76
- package/dist/modules/deals/repository.js.map +1 -1
- package/dist/modules/deals/routes.d.ts +14 -0
- package/dist/modules/deals/routes.d.ts.map +1 -1
- package/dist/modules/deals/routes.js +7 -0
- package/dist/modules/deals/routes.js.map +1 -1
- package/dist/modules/deals/schema.d.ts +20 -42
- package/dist/modules/deals/schema.d.ts.map +1 -1
- package/dist/modules/deals/schema.js +6 -11
- package/dist/modules/deals/schema.js.map +1 -1
- package/dist/modules/deals/service.d.ts +13 -2
- package/dist/modules/deals/service.d.ts.map +1 -1
- package/dist/modules/deals/service.js +43 -20
- package/dist/modules/deals/service.js.map +1 -1
- package/dist/modules/decisions/repository.d.ts.map +1 -1
- package/dist/modules/decisions/repository.js +2 -0
- package/dist/modules/decisions/repository.js.map +1 -1
- package/dist/modules/decisions/routes.d.ts +1 -0
- package/dist/modules/decisions/routes.d.ts.map +1 -1
- package/dist/modules/enquiries/events.d.ts +44 -0
- package/dist/modules/enquiries/events.d.ts.map +1 -0
- package/dist/modules/enquiries/events.js +19 -0
- package/dist/modules/enquiries/events.js.map +1 -0
- package/dist/modules/enquiries/index.d.ts +13 -0
- package/dist/modules/enquiries/index.d.ts.map +1 -0
- package/dist/modules/enquiries/index.js +44 -0
- package/dist/modules/enquiries/index.js.map +1 -0
- package/dist/modules/enquiries/repository.d.ts +30 -0
- package/dist/modules/enquiries/repository.d.ts.map +1 -0
- package/dist/modules/enquiries/repository.js +94 -0
- package/dist/modules/enquiries/repository.js.map +1 -0
- package/dist/modules/enquiries/routes.d.ts +52 -0
- package/dist/modules/enquiries/routes.d.ts.map +1 -0
- package/dist/modules/enquiries/routes.js +127 -0
- package/dist/modules/enquiries/routes.js.map +1 -0
- package/dist/modules/enquiries/schema.d.ts +290 -0
- package/dist/modules/enquiries/schema.d.ts.map +1 -0
- package/dist/modules/enquiries/schema.js +52 -0
- package/dist/modules/enquiries/schema.js.map +1 -0
- package/dist/modules/enquiries/service.d.ts +85 -0
- package/dist/modules/enquiries/service.d.ts.map +1 -0
- package/dist/modules/enquiries/service.js +370 -0
- package/dist/modules/enquiries/service.js.map +1 -0
- package/dist/modules/enquiries/tools.d.ts +4 -0
- package/dist/modules/enquiries/tools.d.ts.map +1 -0
- package/dist/modules/enquiries/tools.js +50 -0
- package/dist/modules/enquiries/tools.js.map +1 -0
- package/dist/modules/eventCatalogs.d.ts +3 -0
- package/dist/modules/eventCatalogs.d.ts.map +1 -1
- package/dist/modules/eventCatalogs.js +3 -0
- package/dist/modules/eventCatalogs.js.map +1 -1
- package/dist/modules/forms/embed.d.ts +20 -6
- package/dist/modules/forms/embed.d.ts.map +1 -1
- package/dist/modules/forms/embed.js +359 -43
- package/dist/modules/forms/embed.js.map +1 -1
- package/dist/modules/forms/events.d.ts +20 -7
- package/dist/modules/forms/events.d.ts.map +1 -1
- package/dist/modules/forms/events.js +20 -2
- package/dist/modules/forms/events.js.map +1 -1
- package/dist/modules/forms/fields.d.ts +14 -1
- package/dist/modules/forms/fields.d.ts.map +1 -1
- package/dist/modules/forms/fields.js +87 -3
- package/dist/modules/forms/fields.js.map +1 -1
- package/dist/modules/forms/index.d.ts.map +1 -1
- package/dist/modules/forms/index.js +12 -1
- package/dist/modules/forms/index.js.map +1 -1
- package/dist/modules/forms/mapping.d.ts +62 -5
- package/dist/modules/forms/mapping.d.ts.map +1 -1
- package/dist/modules/forms/mapping.js +139 -5
- package/dist/modules/forms/mapping.js.map +1 -1
- package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
- package/dist/modules/forms/publicRoutes.js +29 -1
- package/dist/modules/forms/publicRoutes.js.map +1 -1
- package/dist/modules/forms/repository.d.ts +31 -0
- package/dist/modules/forms/repository.d.ts.map +1 -1
- package/dist/modules/forms/repository.js +90 -1
- package/dist/modules/forms/repository.js.map +1 -1
- package/dist/modules/forms/routes.d.ts +83 -1
- package/dist/modules/forms/routes.d.ts.map +1 -1
- package/dist/modules/forms/routes.js +185 -2
- package/dist/modules/forms/routes.js.map +1 -1
- package/dist/modules/forms/schema.d.ts +672 -1
- package/dist/modules/forms/schema.d.ts.map +1 -1
- package/dist/modules/forms/schema.js +146 -3
- package/dist/modules/forms/schema.js.map +1 -1
- package/dist/modules/forms/service.d.ts +54 -1
- package/dist/modules/forms/service.d.ts.map +1 -1
- package/dist/modules/forms/service.js +338 -28
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/submission.d.ts +15 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +418 -40
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/import-export/drafts.d.ts +10 -0
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +16 -2
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/exportRows.d.ts +7 -4
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +20 -5
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts +12 -1
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +29 -2
- package/dist/modules/import-export/plan.js.map +1 -1
- package/dist/modules/import-export/presets.d.ts.map +1 -1
- package/dist/modules/import-export/presets.js +10 -0
- package/dist/modules/import-export/presets.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +11 -1
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +42 -9
- package/dist/modules/import-export/repository.js.map +1 -1
- package/dist/modules/import-export/routes.d.ts.map +1 -1
- package/dist/modules/import-export/routes.js +4 -0
- package/dist/modules/import-export/routes.js.map +1 -1
- package/dist/modules/import-export/schema.d.ts +17 -0
- package/dist/modules/import-export/schema.d.ts.map +1 -1
- package/dist/modules/import-export/schema.js +11 -0
- package/dist/modules/import-export/schema.js.map +1 -1
- package/dist/modules/import-export/service.d.ts +6 -0
- package/dist/modules/import-export/service.d.ts.map +1 -1
- package/dist/modules/import-export/service.js +14 -2
- package/dist/modules/import-export/service.js.map +1 -1
- package/dist/modules/import-export/streams.d.ts.map +1 -1
- package/dist/modules/import-export/streams.js +3 -3
- package/dist/modules/import-export/streams.js.map +1 -1
- package/dist/modules/import-export/tools.d.ts.map +1 -1
- package/dist/modules/import-export/tools.js +8 -0
- package/dist/modules/import-export/tools.js.map +1 -1
- package/dist/modules/import-export/validation.d.ts.map +1 -1
- package/dist/modules/import-export/validation.js +22 -1
- package/dist/modules/import-export/validation.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +37 -4
- package/dist/modules/import-export/writes.js.map +1 -1
- package/dist/modules/lists/index.d.ts +38 -0
- package/dist/modules/lists/index.d.ts.map +1 -1
- package/dist/modules/lists/index.js +27 -0
- package/dist/modules/lists/index.js.map +1 -1
- package/dist/modules/lists/repository.d.ts +26 -0
- package/dist/modules/lists/repository.d.ts.map +1 -1
- package/dist/modules/lists/repository.js +32 -0
- package/dist/modules/lists/repository.js.map +1 -1
- package/dist/modules/lists/routes.d.ts +4 -0
- package/dist/modules/lists/routes.d.ts.map +1 -1
- package/dist/modules/lists/routes.js +8 -0
- package/dist/modules/lists/routes.js.map +1 -1
- package/dist/modules/lists/schema.d.ts +17 -0
- package/dist/modules/lists/schema.d.ts.map +1 -1
- package/dist/modules/lists/schema.js +10 -0
- package/dist/modules/lists/schema.js.map +1 -1
- package/dist/modules/lists/service.d.ts +14 -2
- package/dist/modules/lists/service.d.ts.map +1 -1
- package/dist/modules/lists/service.js +55 -7
- package/dist/modules/lists/service.js.map +1 -1
- package/dist/modules/mcp/index.d.ts.map +1 -1
- package/dist/modules/mcp/index.js +5 -0
- package/dist/modules/mcp/index.js.map +1 -1
- package/dist/modules/notes/routes.d.ts +1 -0
- package/dist/modules/notes/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/index.d.ts.map +1 -1
- package/dist/modules/opportunities/index.js +3 -1
- package/dist/modules/opportunities/index.js.map +1 -1
- package/dist/modules/opportunities/repository.d.ts +2 -0
- package/dist/modules/opportunities/repository.d.ts.map +1 -1
- package/dist/modules/opportunities/repository.js +4 -0
- package/dist/modules/opportunities/repository.js.map +1 -1
- package/dist/modules/opportunities/routes.d.ts +16 -0
- package/dist/modules/opportunities/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/routes.js +13 -0
- package/dist/modules/opportunities/routes.js.map +1 -1
- package/dist/modules/opportunities/schema.d.ts +20 -0
- package/dist/modules/opportunities/schema.d.ts.map +1 -1
- package/dist/modules/opportunities/schema.js +6 -1
- package/dist/modules/opportunities/schema.js.map +1 -1
- package/dist/modules/opportunities/service.d.ts +20 -3
- package/dist/modules/opportunities/service.d.ts.map +1 -1
- package/dist/modules/opportunities/service.js +99 -18
- package/dist/modules/opportunities/service.js.map +1 -1
- package/dist/modules/opportunities/tools.d.ts.map +1 -1
- package/dist/modules/opportunities/tools.js +2 -0
- package/dist/modules/opportunities/tools.js.map +1 -1
- package/dist/modules/partnerships/index.d.ts.map +1 -1
- package/dist/modules/partnerships/index.js +3 -1
- package/dist/modules/partnerships/index.js.map +1 -1
- package/dist/modules/partnerships/repository.d.ts +0 -17
- package/dist/modules/partnerships/repository.d.ts.map +1 -1
- package/dist/modules/partnerships/repository.js +6 -82
- package/dist/modules/partnerships/repository.js.map +1 -1
- package/dist/modules/partnerships/routes.d.ts +14 -0
- package/dist/modules/partnerships/routes.d.ts.map +1 -1
- package/dist/modules/partnerships/routes.js +7 -0
- package/dist/modules/partnerships/routes.js.map +1 -1
- package/dist/modules/partnerships/schema.d.ts +20 -41
- package/dist/modules/partnerships/schema.d.ts.map +1 -1
- package/dist/modules/partnerships/schema.js +6 -10
- package/dist/modules/partnerships/schema.js.map +1 -1
- package/dist/modules/partnerships/service.d.ts +11 -1
- package/dist/modules/partnerships/service.d.ts.map +1 -1
- package/dist/modules/partnerships/service.js +43 -20
- package/dist/modules/partnerships/service.js.map +1 -1
- package/dist/modules/people/consentHydration.d.ts +26 -0
- package/dist/modules/people/consentHydration.d.ts.map +1 -0
- package/dist/modules/people/consentHydration.js +100 -0
- package/dist/modules/people/consentHydration.js.map +1 -0
- package/dist/modules/people/index.d.ts.map +1 -1
- package/dist/modules/people/index.js +3 -1
- package/dist/modules/people/index.js.map +1 -1
- package/dist/modules/people/personConsentWrites.d.ts +40 -0
- package/dist/modules/people/personConsentWrites.d.ts.map +1 -0
- package/dist/modules/people/personConsentWrites.js +98 -0
- package/dist/modules/people/personConsentWrites.js.map +1 -0
- package/dist/modules/people/repository.d.ts.map +1 -1
- package/dist/modules/people/repository.js +5 -1
- package/dist/modules/people/repository.js.map +1 -1
- package/dist/modules/people/routes.d.ts +57 -4
- package/dist/modules/people/routes.d.ts.map +1 -1
- package/dist/modules/people/routes.js +104 -5
- package/dist/modules/people/routes.js.map +1 -1
- package/dist/modules/people/schema.d.ts +366 -1
- package/dist/modules/people/schema.d.ts.map +1 -1
- package/dist/modules/people/schema.js +92 -2
- package/dist/modules/people/schema.js.map +1 -1
- package/dist/modules/people/service.d.ts +30 -1
- package/dist/modules/people/service.d.ts.map +1 -1
- package/dist/modules/people/service.js +115 -38
- package/dist/modules/people/service.js.map +1 -1
- package/dist/modules/people/tools.d.ts.map +1 -1
- package/dist/modules/people/tools.js +4 -1
- package/dist/modules/people/tools.js.map +1 -1
- package/dist/modules/personLinks.d.ts +79 -0
- package/dist/modules/personLinks.d.ts.map +1 -0
- package/dist/modules/personLinks.js +155 -0
- package/dist/modules/personLinks.js.map +1 -0
- package/dist/modules/pipelines/routes.d.ts +1 -0
- package/dist/modules/pipelines/routes.d.ts.map +1 -1
- package/dist/modules/plans/routes.d.ts +1 -0
- package/dist/modules/plans/routes.d.ts.map +1 -1
- package/dist/modules/raises/index.d.ts.map +1 -1
- package/dist/modules/raises/index.js +3 -1
- package/dist/modules/raises/index.js.map +1 -1
- package/dist/modules/raises/repository.d.ts +0 -17
- package/dist/modules/raises/repository.d.ts.map +1 -1
- package/dist/modules/raises/repository.js +6 -77
- package/dist/modules/raises/repository.js.map +1 -1
- package/dist/modules/raises/routes.d.ts +14 -0
- package/dist/modules/raises/routes.d.ts.map +1 -1
- package/dist/modules/raises/routes.js +7 -0
- package/dist/modules/raises/routes.js.map +1 -1
- package/dist/modules/raises/schema.d.ts +20 -41
- package/dist/modules/raises/schema.d.ts.map +1 -1
- package/dist/modules/raises/schema.js +6 -10
- package/dist/modules/raises/schema.js.map +1 -1
- package/dist/modules/raises/service.d.ts +11 -1
- package/dist/modules/raises/service.d.ts.map +1 -1
- package/dist/modules/raises/service.js +41 -18
- package/dist/modules/raises/service.js.map +1 -1
- package/dist/modules/recordTargets.d.ts.map +1 -1
- package/dist/modules/recordTargets.js +2 -0
- package/dist/modules/recordTargets.js.map +1 -1
- package/dist/modules/references.d.ts +10 -0
- package/dist/modules/references.d.ts.map +1 -1
- package/dist/modules/references.js +27 -4
- package/dist/modules/references.js.map +1 -1
- package/dist/modules/sample-data/fixture.d.ts +21 -0
- package/dist/modules/sample-data/fixture.d.ts.map +1 -1
- package/dist/modules/sample-data/fixture.js +40 -0
- package/dist/modules/sample-data/fixture.js.map +1 -1
- package/dist/modules/sample-data/index.d.ts.map +1 -1
- package/dist/modules/sample-data/index.js +1 -0
- package/dist/modules/sample-data/index.js.map +1 -1
- package/dist/modules/sample-data/routes.d.ts.map +1 -1
- package/dist/modules/sample-data/routes.js +1 -0
- package/dist/modules/sample-data/routes.js.map +1 -1
- package/dist/modules/sample-data/service.d.ts +1 -0
- package/dist/modules/sample-data/service.d.ts.map +1 -1
- package/dist/modules/sample-data/service.js +77 -8
- package/dist/modules/sample-data/service.js.map +1 -1
- package/dist/modules/search/index.d.ts +1 -1
- package/dist/modules/search/index.d.ts.map +1 -1
- package/dist/modules/search/index.js +2 -1
- package/dist/modules/search/index.js.map +1 -1
- package/dist/modules/search/repository.d.ts +1 -0
- package/dist/modules/search/repository.d.ts.map +1 -1
- package/dist/modules/search/repository.js +23 -0
- package/dist/modules/search/repository.js.map +1 -1
- package/dist/modules/search/service.d.ts +3 -3
- package/dist/modules/search/service.d.ts.map +1 -1
- package/dist/modules/search/service.js +5 -4
- package/dist/modules/search/service.js.map +1 -1
- package/dist/modules/stagedRecords.d.ts +3 -3
- package/dist/modules/stagedRecords.d.ts.map +1 -1
- package/dist/modules/stagedRecords.js +9 -0
- package/dist/modules/stagedRecords.js.map +1 -1
- package/dist/modules/webhooks/payloads.d.ts.map +1 -1
- package/dist/modules/webhooks/payloads.js +15 -2
- package/dist/modules/webhooks/payloads.js.map +1 -1
- package/dist/modules/workspace/repository.d.ts +2 -0
- package/dist/modules/workspace/repository.d.ts.map +1 -1
- package/dist/modules/workspace/repository.js +7 -0
- package/dist/modules/workspace/repository.js.map +1 -1
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +10 -0
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/modules/workspace/starters.d.ts.map +1 -1
- package/dist/modules/workspace/starters.js +5 -0
- package/dist/modules/workspace/starters.js.map +1 -1
- package/dist/runtime/events.d.ts +1 -1
- package/dist/runtime/events.d.ts.map +1 -1
- package/dist/runtime/events.js +1 -0
- package/dist/runtime/events.js.map +1 -1
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/database.d.ts +5 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js +81 -10
- package/dist/testing/database.js.map +1 -1
- package/migrations/0024_third_king_cobra.sql +46 -0
- package/migrations/0025_worthless_chimera.sql +3 -0
- package/migrations/0026_late_aqueduct.sql +46 -0
- package/migrations/0027_brainy_silver_sable.sql +3 -0
- package/migrations/0028_freezing_scrambler.sql +19 -0
- package/migrations/0029_custom_fields.sql +26 -0
- package/migrations/0030_enquiries.sql +79 -0
- package/migrations/0031_consent.sql +45 -0
- package/migrations/0032_form_field_statement.sql +1 -0
- package/migrations/0033_form_field_consent_purpose_ids.sql +5 -0
- package/migrations/0034_drop_form_field_consent_purpose_id.sql +1 -0
- package/migrations/0035_form_field_consent_purpose_labels.sql +1 -0
- package/migrations/0036_form_field_notice_type.sql +2 -0
- package/migrations/meta/0024_snapshot.json +5516 -0
- package/migrations/meta/0025_snapshot.json +5336 -0
- package/migrations/meta/0026_snapshot.json +5710 -0
- package/migrations/meta/0027_snapshot.json +5716 -0
- package/migrations/meta/0028_snapshot.json +5740 -0
- package/migrations/meta/0029_snapshot.json +5935 -0
- package/migrations/meta/0030_snapshot.json +6245 -0
- package/migrations/meta/0031_snapshot.json +6572 -0
- package/migrations/meta/0032_snapshot.json +6578 -0
- package/migrations/meta/0033_snapshot.json +6572 -0
- package/migrations/meta/0034_snapshot.json +6566 -0
- package/migrations/meta/0035_snapshot.json +6573 -0
- package/migrations/meta/0036_snapshot.json +6573 -0
- package/migrations/meta/_journal.json +91 -0
- package/package.json +2 -2
- package/src/index.ts +6 -0
- package/src/lib/ids.ts +11 -0
- package/src/modules/activities/repository.ts +22 -23
- package/src/modules/activities/wording.ts +18 -0
- package/src/modules/agent-tasks/catalog.ts +63 -0
- package/src/modules/agent-tasks/resolve.ts +64 -24
- package/src/modules/attachedRecords.ts +29 -2
- package/src/modules/companies/index.ts +3 -1
- package/src/modules/companies/routes.ts +7 -0
- package/src/modules/companies/schema.ts +7 -1
- package/src/modules/companies/service.ts +48 -13
- package/src/modules/consent-purposes/capabilities.ts +12 -0
- package/src/modules/consent-purposes/events.ts +38 -0
- package/src/modules/consent-purposes/index.ts +48 -0
- package/src/modules/consent-purposes/repository.ts +163 -0
- package/src/modules/consent-purposes/routes.ts +122 -0
- package/src/modules/consent-purposes/schema.ts +46 -0
- package/src/modules/consent-purposes/service.ts +423 -0
- package/src/modules/consent-purposes/starters.ts +32 -0
- package/src/modules/consent-purposes/tools.ts +44 -0
- package/src/modules/core.ts +10 -0
- package/src/modules/custom-fields/capabilities.ts +17 -0
- package/src/modules/custom-fields/events.ts +51 -0
- package/src/modules/custom-fields/index.ts +61 -0
- package/src/modules/custom-fields/repository.ts +225 -0
- package/src/modules/custom-fields/routes.ts +155 -0
- package/src/modules/custom-fields/schema.ts +61 -0
- package/src/modules/custom-fields/service.ts +439 -0
- package/src/modules/custom-fields/tools.ts +53 -0
- package/src/modules/custom-fields/values.ts +352 -0
- package/src/modules/custom-fields/wire.ts +32 -0
- package/src/modules/dashboard/repository.ts +4 -3
- package/src/modules/deals/index.ts +5 -2
- package/src/modules/deals/repository.ts +6 -106
- package/src/modules/deals/routes.ts +7 -0
- package/src/modules/deals/schema.ts +7 -15
- package/src/modules/deals/service.ts +92 -23
- package/src/modules/decisions/repository.ts +2 -0
- package/src/modules/enquiries/events.ts +45 -0
- package/src/modules/enquiries/index.ts +50 -0
- package/src/modules/enquiries/repository.ts +164 -0
- package/src/modules/enquiries/routes.ts +172 -0
- package/src/modules/enquiries/schema.ts +59 -0
- package/src/modules/enquiries/service.ts +644 -0
- package/src/modules/enquiries/tools.ts +66 -0
- package/src/modules/eventCatalogs.ts +3 -0
- package/src/modules/forms/embed.ts +391 -44
- package/src/modules/forms/events.ts +30 -2
- package/src/modules/forms/fields.ts +102 -2
- package/src/modules/forms/index.ts +12 -1
- package/src/modules/forms/mapping.ts +183 -6
- package/src/modules/forms/publicRoutes.ts +43 -1
- package/src/modules/forms/repository.ts +162 -1
- package/src/modules/forms/routes.ts +212 -2
- package/src/modules/forms/schema.ts +166 -4
- package/src/modules/forms/service.ts +565 -41
- package/src/modules/forms/submission.ts +718 -44
- package/src/modules/import-export/drafts.ts +20 -1
- package/src/modules/import-export/exportRows.ts +21 -5
- package/src/modules/import-export/plan.ts +47 -2
- package/src/modules/import-export/presets.ts +10 -0
- package/src/modules/import-export/repository.ts +73 -8
- package/src/modules/import-export/routes.ts +4 -0
- package/src/modules/import-export/schema.ts +11 -0
- package/src/modules/import-export/service.ts +28 -2
- package/src/modules/import-export/streams.ts +3 -1
- package/src/modules/import-export/tools.ts +10 -0
- package/src/modules/import-export/validation.ts +28 -0
- package/src/modules/import-export/writes.ts +70 -5
- package/src/modules/lists/index.ts +71 -0
- package/src/modules/lists/repository.ts +64 -0
- package/src/modules/lists/routes.ts +8 -0
- package/src/modules/lists/schema.ts +10 -0
- package/src/modules/lists/service.ts +110 -9
- package/src/modules/mcp/index.ts +5 -0
- package/src/modules/opportunities/index.ts +3 -1
- package/src/modules/opportunities/repository.ts +11 -0
- package/src/modules/opportunities/routes.ts +13 -0
- package/src/modules/opportunities/schema.ts +7 -1
- package/src/modules/opportunities/service.ts +188 -22
- package/src/modules/opportunities/tools.ts +2 -0
- package/src/modules/partnerships/index.ts +3 -1
- package/src/modules/partnerships/repository.ts +6 -117
- package/src/modules/partnerships/routes.ts +7 -0
- package/src/modules/partnerships/schema.ts +7 -14
- package/src/modules/partnerships/service.ts +93 -22
- package/src/modules/people/consentHydration.ts +167 -0
- package/src/modules/people/index.ts +3 -1
- package/src/modules/people/personConsentWrites.ts +177 -0
- package/src/modules/people/repository.ts +5 -0
- package/src/modules/people/routes.ts +127 -18
- package/src/modules/people/schema.ts +109 -3
- package/src/modules/people/service.ts +186 -40
- package/src/modules/people/tools.ts +5 -1
- package/src/modules/personLinks.ts +278 -0
- package/src/modules/raises/index.ts +3 -1
- package/src/modules/raises/repository.ts +6 -107
- package/src/modules/raises/routes.ts +7 -0
- package/src/modules/raises/schema.ts +7 -14
- package/src/modules/raises/service.ts +91 -20
- package/src/modules/recordTargets.ts +2 -0
- package/src/modules/references.ts +43 -4
- package/src/modules/sample-data/fixture.ts +63 -0
- package/src/modules/sample-data/index.ts +1 -0
- package/src/modules/sample-data/routes.ts +1 -0
- package/src/modules/sample-data/service.ts +97 -8
- package/src/modules/search/index.ts +2 -1
- package/src/modules/search/repository.ts +33 -1
- package/src/modules/search/service.ts +7 -5
- package/src/modules/stagedRecords.ts +18 -3
- package/src/modules/webhooks/payloads.ts +20 -2
- package/src/modules/workspace/repository.ts +12 -0
- package/src/modules/workspace/service.ts +14 -0
- package/src/modules/workspace/starters.ts +5 -0
- package/src/runtime/events.ts +1 -0
- package/src/schema/index.ts +3 -0
- package/src/testing/database.ts +97 -11
|
@@ -0,0 +1,439 @@
|
|
|
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 { toEventActor } from '../../lib/actor.ts'
|
|
9
|
+
import type { EntitlementRegistry } from '../../runtime/entitlements.ts'
|
|
10
|
+
import { limitFor } from '../../runtime/entitlements.ts'
|
|
11
|
+
import type { Transaction, TransactionScope } from '../../runtime/transaction.ts'
|
|
12
|
+
import type { Actor } from '../auth/actor.ts'
|
|
13
|
+
import { requireWorkspaceId } from '../auth/actor.ts'
|
|
14
|
+
import { roleAllows } from '../workspace/roles.ts'
|
|
15
|
+
import { CUSTOM_FIELDS_LIMIT } from './capabilities.ts'
|
|
16
|
+
import './events.ts'
|
|
17
|
+
import * as repository from './repository.ts'
|
|
18
|
+
import {
|
|
19
|
+
CUSTOM_FIELD_DEFINITION_SORTS,
|
|
20
|
+
DEFAULT_CUSTOM_FIELD_DEFINITION_SORT,
|
|
21
|
+
} from './repository.ts'
|
|
22
|
+
import type {
|
|
23
|
+
CustomFieldDefinitionFilters,
|
|
24
|
+
CustomFieldDefinitionRecord,
|
|
25
|
+
} from './repository.ts'
|
|
26
|
+
import { CUSTOM_FIELD_OBJECT_TYPES } from './schema.ts'
|
|
27
|
+
import type { CustomFieldObjectType, CustomFieldType } from './schema.ts'
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Definition-side CRUD for custom fields.
|
|
31
|
+
*
|
|
32
|
+
* Reads are open to any workspace actor: agents that write values must be able
|
|
33
|
+
* to list definitions first, and detail pages fetch them for every viewer.
|
|
34
|
+
* Writes require the admin role, matching how API keys and webhooks are gated
|
|
35
|
+
* — a definition changes the shape of every record of one object type and is
|
|
36
|
+
* team-wide config, not a per-user preference.
|
|
37
|
+
*
|
|
38
|
+
* The record-side write path lives in `values.ts`: create/update pass their
|
|
39
|
+
* sent `custom_fields` through `createCustomFieldValues(...).forCreate` /
|
|
40
|
+
* `.forUpdate`, which reads definitions and enforces per-type validity.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/** Hard cap per (workspace, object_type). Bites when the entitlement leaves the count unlimited. */
|
|
44
|
+
export const CUSTOM_FIELDS_PER_OBJECT_HARD_CAP = 100
|
|
45
|
+
|
|
46
|
+
const KEY_PATTERN = /^[a-z][a-z0-9_]*$/u
|
|
47
|
+
const MAX_KEY_LENGTH = 64
|
|
48
|
+
const MAX_LABEL_LENGTH = 120
|
|
49
|
+
const MIN_LABEL_LENGTH = 1
|
|
50
|
+
const MAX_DESCRIPTION_LENGTH = 2000
|
|
51
|
+
const MAX_OPTIONS = 100
|
|
52
|
+
const MIN_OPTION_LENGTH = 1
|
|
53
|
+
const MAX_OPTION_LENGTH = 120
|
|
54
|
+
|
|
55
|
+
/** The wire types that require a non-empty `options`. */
|
|
56
|
+
const TYPES_WITH_OPTIONS: ReadonlySet<CustomFieldType> = new Set(['select', 'multi_select'])
|
|
57
|
+
|
|
58
|
+
export interface CustomFieldDefinitionsDependencies {
|
|
59
|
+
readonly db: Database
|
|
60
|
+
readonly transaction: TransactionScope
|
|
61
|
+
readonly createId: IdFactory
|
|
62
|
+
readonly now: () => Date
|
|
63
|
+
readonly entitlements: EntitlementRegistry
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The definition as the API returns it: the stored row minus the tenancy column. */
|
|
67
|
+
export type CustomFieldDefinitionView = Omit<CustomFieldDefinitionRecord, 'workspaceId'>
|
|
68
|
+
|
|
69
|
+
export interface CreateCustomFieldDefinitionInput {
|
|
70
|
+
readonly objectType: CustomFieldObjectType
|
|
71
|
+
readonly key: string
|
|
72
|
+
readonly label: string
|
|
73
|
+
readonly type: CustomFieldType
|
|
74
|
+
readonly options: readonly string[]
|
|
75
|
+
readonly description: string
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** PATCH semantics: `key`, `type`, `object_type` are immutable and refused by the route body. */
|
|
79
|
+
export interface UpdateCustomFieldDefinitionInput {
|
|
80
|
+
readonly label?: string | undefined
|
|
81
|
+
readonly description?: string | undefined
|
|
82
|
+
readonly options?: readonly string[] | undefined
|
|
83
|
+
readonly sortOrder?: number | undefined
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface CustomFieldDefinitionsService {
|
|
87
|
+
list(
|
|
88
|
+
actor: Actor,
|
|
89
|
+
filters: CustomFieldDefinitionFilters,
|
|
90
|
+
query: ListQueryParameters,
|
|
91
|
+
): Promise<Page<CustomFieldDefinitionView>>
|
|
92
|
+
get(actor: Actor, id: string): Promise<CustomFieldDefinitionView>
|
|
93
|
+
create(
|
|
94
|
+
actor: Actor,
|
|
95
|
+
input: CreateCustomFieldDefinitionInput,
|
|
96
|
+
): Promise<CustomFieldDefinitionView>
|
|
97
|
+
update(
|
|
98
|
+
actor: Actor,
|
|
99
|
+
id: string,
|
|
100
|
+
changes: UpdateCustomFieldDefinitionInput,
|
|
101
|
+
): Promise<CustomFieldDefinitionView>
|
|
102
|
+
remove(actor: Actor, id: string): Promise<void>
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function toView(record: CustomFieldDefinitionRecord): CustomFieldDefinitionView {
|
|
106
|
+
const { workspaceId: _workspaceId, ...view } = record
|
|
107
|
+
return view
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function duplicateKey(): AppError {
|
|
111
|
+
return AppError.conflict(
|
|
112
|
+
'Another custom field on this object type already has that key',
|
|
113
|
+
[{ field: 'key', message: 'Already in use' }],
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function fieldError(field: string, message: string): AppError {
|
|
118
|
+
return AppError.validationFailed('That custom field is not valid', [{ field, message }])
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function validateKey(key: string): void {
|
|
122
|
+
if (key.length === 0 || key.length > MAX_KEY_LENGTH) {
|
|
123
|
+
throw fieldError('key', `1 to ${String(MAX_KEY_LENGTH)} characters`)
|
|
124
|
+
}
|
|
125
|
+
if (!KEY_PATTERN.test(key)) {
|
|
126
|
+
throw fieldError(
|
|
127
|
+
'key',
|
|
128
|
+
'Lowercase letters, digits and underscores; must start with a letter',
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function validateLabel(label: string): void {
|
|
134
|
+
if (label.length < MIN_LABEL_LENGTH || label.length > MAX_LABEL_LENGTH) {
|
|
135
|
+
throw fieldError('label', `${String(MIN_LABEL_LENGTH)} to ${String(MAX_LABEL_LENGTH)} characters`)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function validateDescription(description: string): void {
|
|
140
|
+
if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
141
|
+
throw fieldError('description', `At most ${String(MAX_DESCRIPTION_LENGTH)} characters`)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function validateOptionsFor(type: CustomFieldType, options: readonly string[]): void {
|
|
146
|
+
const requiresOptions = TYPES_WITH_OPTIONS.has(type)
|
|
147
|
+
if (!requiresOptions) {
|
|
148
|
+
if (options.length > 0) {
|
|
149
|
+
throw fieldError('options', 'Only select and multi_select fields carry options')
|
|
150
|
+
}
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
if (options.length === 0) {
|
|
154
|
+
throw fieldError('options', 'Select fields need at least one option')
|
|
155
|
+
}
|
|
156
|
+
if (options.length > MAX_OPTIONS) {
|
|
157
|
+
throw fieldError('options', `At most ${String(MAX_OPTIONS)} options`)
|
|
158
|
+
}
|
|
159
|
+
const seen = new Set<string>()
|
|
160
|
+
for (const option of options) {
|
|
161
|
+
if (option.length < MIN_OPTION_LENGTH || option.length > MAX_OPTION_LENGTH) {
|
|
162
|
+
throw fieldError(
|
|
163
|
+
'options',
|
|
164
|
+
`Each option is ${String(MIN_OPTION_LENGTH)} to ${String(MAX_OPTION_LENGTH)} characters`,
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
if (seen.has(option)) {
|
|
168
|
+
throw fieldError('options', `"${option}" appears more than once`)
|
|
169
|
+
}
|
|
170
|
+
seen.add(option)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function assertObjectType(objectType: string): asserts objectType is CustomFieldObjectType {
|
|
175
|
+
if (!CUSTOM_FIELD_OBJECT_TYPES.includes(objectType as CustomFieldObjectType)) {
|
|
176
|
+
throw fieldError('object_type', `Unknown object type "${objectType}"`)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function createCustomFieldDefinitionsService(
|
|
181
|
+
dependencies: CustomFieldDefinitionsDependencies,
|
|
182
|
+
): CustomFieldDefinitionsService {
|
|
183
|
+
function requireAdminWorkspace(actor: Actor): string {
|
|
184
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
185
|
+
if (actor.role === null || !roleAllows(actor.role, 'admin')) {
|
|
186
|
+
throw new AppError('forbidden', 'This action needs the admin role')
|
|
187
|
+
}
|
|
188
|
+
return workspaceId
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function require(
|
|
192
|
+
workspaceId: string,
|
|
193
|
+
id: string,
|
|
194
|
+
): Promise<CustomFieldDefinitionRecord> {
|
|
195
|
+
const definition = await repository.findDefinition(dependencies.db, workspaceId, id)
|
|
196
|
+
if (definition === undefined) {
|
|
197
|
+
throw AppError.notFound('Custom field not found')
|
|
198
|
+
}
|
|
199
|
+
return definition
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Renumbers the sort_order of one object type's definitions to 0..N-1 in
|
|
204
|
+
* `order`, writing only the rows whose position moved. Mirrors the pipeline
|
|
205
|
+
* stage renumber pattern.
|
|
206
|
+
*/
|
|
207
|
+
async function renumber(
|
|
208
|
+
tx: Transaction,
|
|
209
|
+
workspaceId: string,
|
|
210
|
+
order: readonly CustomFieldDefinitionRecord[],
|
|
211
|
+
): Promise<void> {
|
|
212
|
+
for (const [index, definition] of order.entries()) {
|
|
213
|
+
if (definition.sortOrder !== index) {
|
|
214
|
+
await repository.updateDefinition(tx, workspaceId, definition.id, {
|
|
215
|
+
sortOrder: index,
|
|
216
|
+
updatedAt: dependencies.now(),
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function moveToPosition(
|
|
223
|
+
tx: Transaction,
|
|
224
|
+
workspaceId: string,
|
|
225
|
+
definition: CustomFieldDefinitionRecord,
|
|
226
|
+
position: number,
|
|
227
|
+
): Promise<void> {
|
|
228
|
+
const rows = await repository.definitionsForObject(
|
|
229
|
+
tx,
|
|
230
|
+
workspaceId,
|
|
231
|
+
definition.objectType as CustomFieldObjectType,
|
|
232
|
+
)
|
|
233
|
+
const target = rows.find((row) => row.id === definition.id)
|
|
234
|
+
if (target === undefined) {
|
|
235
|
+
throw AppError.notFound('Custom field not found')
|
|
236
|
+
}
|
|
237
|
+
if (position < 0 || position >= rows.length) {
|
|
238
|
+
throw fieldError('sort_order', `Use 0 to ${String(rows.length - 1)}`)
|
|
239
|
+
}
|
|
240
|
+
const reordered = rows.filter((row) => row.id !== definition.id)
|
|
241
|
+
reordered.splice(position, 0, target)
|
|
242
|
+
await renumber(tx, workspaceId, reordered)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
async list(actor, filters, query) {
|
|
247
|
+
const workspaceId = requireWorkspaceId(actor)
|
|
248
|
+
const window = readListWindow(
|
|
249
|
+
query,
|
|
250
|
+
CUSTOM_FIELD_DEFINITION_SORTS,
|
|
251
|
+
DEFAULT_CUSTOM_FIELD_DEFINITION_SORT,
|
|
252
|
+
)
|
|
253
|
+
const rows = await repository.listDefinitions(
|
|
254
|
+
dependencies.db,
|
|
255
|
+
workspaceId,
|
|
256
|
+
filters,
|
|
257
|
+
window,
|
|
258
|
+
)
|
|
259
|
+
return mapPage(toPage(rows, window, (row) => row.id), toView)
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
async get(actor, id) {
|
|
263
|
+
return toView(await require(requireWorkspaceId(actor), id))
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
async create(actor, input) {
|
|
267
|
+
const workspaceId = requireAdminWorkspace(actor)
|
|
268
|
+
assertObjectType(input.objectType)
|
|
269
|
+
validateKey(input.key)
|
|
270
|
+
validateLabel(input.label)
|
|
271
|
+
validateDescription(input.description)
|
|
272
|
+
validateOptionsFor(input.type, input.options)
|
|
273
|
+
|
|
274
|
+
const limit = await limitFor(dependencies.entitlements, workspaceId, CUSTOM_FIELDS_LIMIT.name)
|
|
275
|
+
if (limit !== null) {
|
|
276
|
+
const total = await repository.countDefinitions(dependencies.db, workspaceId)
|
|
277
|
+
if (total >= limit) {
|
|
278
|
+
throw new AppError(
|
|
279
|
+
'entitlement_required',
|
|
280
|
+
`Your plan allows ${String(limit)} custom field${limit === 1 ? '' : 's'}`,
|
|
281
|
+
)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const id = dependencies.createId('customFieldDefinition')
|
|
286
|
+
|
|
287
|
+
return dependencies.transaction(
|
|
288
|
+
async ({ tx, events }) => {
|
|
289
|
+
const existing = await repository.definitionsForObject(tx, workspaceId, input.objectType)
|
|
290
|
+
if (existing.length >= CUSTOM_FIELDS_PER_OBJECT_HARD_CAP) {
|
|
291
|
+
throw AppError.conflict(
|
|
292
|
+
`A record type may carry at most ${String(CUSTOM_FIELDS_PER_OBJECT_HARD_CAP)} custom fields`,
|
|
293
|
+
[{ field: 'object_type', message: 'Limit reached' }],
|
|
294
|
+
)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let created: CustomFieldDefinitionRecord
|
|
298
|
+
try {
|
|
299
|
+
created = await repository.insertDefinition(tx, {
|
|
300
|
+
id,
|
|
301
|
+
workspaceId,
|
|
302
|
+
objectType: input.objectType,
|
|
303
|
+
key: input.key,
|
|
304
|
+
label: input.label,
|
|
305
|
+
type: input.type,
|
|
306
|
+
options: input.options,
|
|
307
|
+
description: input.description,
|
|
308
|
+
sortOrder: (existing.at(-1)?.sortOrder ?? -1) + 1,
|
|
309
|
+
})
|
|
310
|
+
} catch (error: unknown) {
|
|
311
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
312
|
+
throw duplicateKey()
|
|
313
|
+
}
|
|
314
|
+
throw error
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
events.emit(
|
|
318
|
+
'custom_fields.field.created',
|
|
319
|
+
{ type: 'custom_field', id: created.id },
|
|
320
|
+
{ objectType: created.objectType, key: created.key },
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
return toView(created)
|
|
324
|
+
},
|
|
325
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
326
|
+
)
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
async update(actor, id, changes) {
|
|
330
|
+
const workspaceId = requireAdminWorkspace(actor)
|
|
331
|
+
const existing = await require(workspaceId, id)
|
|
332
|
+
|
|
333
|
+
if (changes.label !== undefined) {
|
|
334
|
+
validateLabel(changes.label)
|
|
335
|
+
}
|
|
336
|
+
if (changes.description !== undefined) {
|
|
337
|
+
validateDescription(changes.description)
|
|
338
|
+
}
|
|
339
|
+
if (changes.options !== undefined) {
|
|
340
|
+
validateOptionsFor(existing.type as CustomFieldType, changes.options)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const columns: Partial<repository.CustomFieldDefinitionColumns> = {
|
|
344
|
+
...(changes.label === undefined ? {} : { label: changes.label }),
|
|
345
|
+
...(changes.description === undefined ? {} : { description: changes.description }),
|
|
346
|
+
...(changes.options === undefined ? {} : { options: changes.options }),
|
|
347
|
+
}
|
|
348
|
+
const changed = changedKeys(existing, columns)
|
|
349
|
+
const position = changes.sortOrder
|
|
350
|
+
|
|
351
|
+
if (changed.length === 0 && position === undefined) {
|
|
352
|
+
return toView(existing)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return dependencies.transaction(
|
|
356
|
+
async ({ tx, events }) => {
|
|
357
|
+
if (position !== undefined) {
|
|
358
|
+
await moveToPosition(tx, workspaceId, existing, position)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
let updated: CustomFieldDefinitionRecord | undefined
|
|
362
|
+
if (changed.length > 0) {
|
|
363
|
+
updated = await repository.updateDefinition(tx, workspaceId, id, {
|
|
364
|
+
...columns,
|
|
365
|
+
updatedAt: dependencies.now(),
|
|
366
|
+
})
|
|
367
|
+
if (updated === undefined) {
|
|
368
|
+
throw AppError.notFound('Custom field not found')
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
updated = await repository.findDefinition(tx, workspaceId, id)
|
|
372
|
+
if (updated === undefined) {
|
|
373
|
+
throw AppError.notFound('Custom field not found')
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (changed.length > 0 || position !== undefined) {
|
|
378
|
+
const changedPaths = [
|
|
379
|
+
...changed,
|
|
380
|
+
...(position !== undefined && position !== existing.sortOrder ? ['sortOrder'] : []),
|
|
381
|
+
]
|
|
382
|
+
events.emit(
|
|
383
|
+
'custom_fields.field.updated',
|
|
384
|
+
{ type: 'custom_field', id },
|
|
385
|
+
{
|
|
386
|
+
objectType: updated.objectType,
|
|
387
|
+
key: updated.key,
|
|
388
|
+
changed: changedPaths,
|
|
389
|
+
},
|
|
390
|
+
)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return toView(updated)
|
|
394
|
+
},
|
|
395
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
396
|
+
)
|
|
397
|
+
},
|
|
398
|
+
|
|
399
|
+
async remove(actor, id) {
|
|
400
|
+
const workspaceId = requireAdminWorkspace(actor)
|
|
401
|
+
const existing = await require(workspaceId, id)
|
|
402
|
+
|
|
403
|
+
await dependencies.transaction(
|
|
404
|
+
async ({ tx, events }) => {
|
|
405
|
+
const stripped = await repository.stripKeyFromRecords(
|
|
406
|
+
tx,
|
|
407
|
+
workspaceId,
|
|
408
|
+
existing.objectType as CustomFieldObjectType,
|
|
409
|
+
existing.key,
|
|
410
|
+
)
|
|
411
|
+
await repository.deleteDefinition(tx, workspaceId, id)
|
|
412
|
+
// Renumber survivors so `sort_order` stays contiguous, same as the
|
|
413
|
+
// pipelines remove path.
|
|
414
|
+
const survivors = await repository.definitionsForObject(
|
|
415
|
+
tx,
|
|
416
|
+
workspaceId,
|
|
417
|
+
existing.objectType as CustomFieldObjectType,
|
|
418
|
+
)
|
|
419
|
+
await renumber(tx, workspaceId, survivors)
|
|
420
|
+
|
|
421
|
+
// No per-record `<object>.updated` events for the strip: a definition
|
|
422
|
+
// delete may touch thousands of rows and would flood every webhook
|
|
423
|
+
// subscriber. The `custom_fields.field.deleted` event carries the
|
|
424
|
+
// count for a consumer that wants to know how many rows were touched.
|
|
425
|
+
events.emit(
|
|
426
|
+
'custom_fields.field.deleted',
|
|
427
|
+
{ type: 'custom_field', id },
|
|
428
|
+
{
|
|
429
|
+
objectType: existing.objectType,
|
|
430
|
+
key: existing.key,
|
|
431
|
+
strippedRecordCount: stripped,
|
|
432
|
+
},
|
|
433
|
+
)
|
|
434
|
+
},
|
|
435
|
+
{ workspaceId, actor: toEventActor(actor) },
|
|
436
|
+
)
|
|
437
|
+
},
|
|
438
|
+
}
|
|
439
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { McpToolRegistry } from '../../runtime/module.ts'
|
|
4
|
+
import { idArg, listWindowShape, registerCrudTools, termArg } from '../crudTools.ts'
|
|
5
|
+
import {
|
|
6
|
+
createBody,
|
|
7
|
+
customFieldDefinitionResponse,
|
|
8
|
+
toCreateInput,
|
|
9
|
+
toUpdateInput,
|
|
10
|
+
updateBody,
|
|
11
|
+
} from './routes.ts'
|
|
12
|
+
import { CUSTOM_FIELD_OBJECT_TYPES } from './schema.ts'
|
|
13
|
+
import type { CustomFieldDefinitionsService } from './service.ts'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* `custom_fields_*`. Same schemas and mappers as `/v1/custom_fields`, so the
|
|
17
|
+
* REST surface and the MCP one cannot drift.
|
|
18
|
+
*
|
|
19
|
+
* The record-side tools (`deals_update`, `people_update`, …) pick up
|
|
20
|
+
* `custom_fields` automatically through `registerCrudTools` reusing each
|
|
21
|
+
* module's route bodies — see the `custom_fields` field on those bodies. The
|
|
22
|
+
* schema's `.describe()` tells an agent to list definitions first.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const listArgs = z.strictObject({
|
|
26
|
+
...listWindowShape,
|
|
27
|
+
q: termArg,
|
|
28
|
+
object_type: z
|
|
29
|
+
.enum(CUSTOM_FIELD_OBJECT_TYPES)
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Only definitions for this record type.'),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
export function registerCustomFieldsTools(
|
|
35
|
+
mcp: McpToolRegistry,
|
|
36
|
+
service: CustomFieldDefinitionsService,
|
|
37
|
+
): void {
|
|
38
|
+
registerCrudTools(mcp, {
|
|
39
|
+
resource: 'custom_fields',
|
|
40
|
+
subject: 'custom field',
|
|
41
|
+
about:
|
|
42
|
+
'A workspace-defined field on a record type. Read these before writing values in a ' +
|
|
43
|
+
'record create or update: a value is only accepted if it matches a definition here.',
|
|
44
|
+
service,
|
|
45
|
+
render: customFieldDefinitionResponse,
|
|
46
|
+
listArgs,
|
|
47
|
+
toFilters: (args) => ({ term: args.q, objectType: args.object_type }),
|
|
48
|
+
createArgs: createBody,
|
|
49
|
+
toCreateInput,
|
|
50
|
+
updateArgs: updateBody.extend({ id: idArg }),
|
|
51
|
+
toUpdateInput,
|
|
52
|
+
})
|
|
53
|
+
}
|