@kelpie/server 0.10.0 → 0.12.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/app.d.ts.map +1 -1
- package/dist/app.js +2 -0
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/actor.d.ts +3 -1
- package/dist/lib/actor.d.ts.map +1 -1
- package/dist/lib/actor.js.map +1 -1
- package/dist/lib/apiKeyScopes.d.ts +8 -0
- package/dist/lib/apiKeyScopes.d.ts.map +1 -0
- package/dist/lib/apiKeyScopes.js +166 -0
- package/dist/lib/apiKeyScopes.js.map +1 -0
- package/dist/lib/errors.d.ts +18 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +17 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/modules/activities/repository.d.ts +2 -0
- package/dist/modules/activities/repository.d.ts.map +1 -1
- package/dist/modules/activities/repository.js +9 -0
- package/dist/modules/activities/repository.js.map +1 -1
- package/dist/modules/agent-tasks/repository.d.ts +2 -0
- package/dist/modules/agent-tasks/repository.d.ts.map +1 -1
- package/dist/modules/agent-tasks/repository.js +9 -0
- package/dist/modules/agent-tasks/repository.js.map +1 -1
- package/dist/modules/api-keys/routes.d.ts.map +1 -1
- package/dist/modules/api-keys/routes.js +4 -1
- package/dist/modules/api-keys/routes.js.map +1 -1
- package/dist/modules/api-keys/schema.d.ts +43 -0
- package/dist/modules/api-keys/schema.d.ts.map +1 -1
- package/dist/modules/api-keys/schema.js +2 -0
- package/dist/modules/api-keys/schema.js.map +1 -1
- package/dist/modules/api-keys/scopeMiddleware.d.ts +8 -0
- package/dist/modules/api-keys/scopeMiddleware.d.ts.map +1 -0
- package/dist/modules/api-keys/scopeMiddleware.js +21 -0
- package/dist/modules/api-keys/scopeMiddleware.js.map +1 -0
- package/dist/modules/api-keys/service.d.ts +3 -1
- package/dist/modules/api-keys/service.d.ts.map +1 -1
- package/dist/modules/api-keys/service.js +26 -1
- package/dist/modules/api-keys/service.js.map +1 -1
- package/dist/modules/auth/credentials.d.ts.map +1 -1
- package/dist/modules/auth/credentials.js +2 -0
- package/dist/modules/auth/credentials.js.map +1 -1
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/auth/index.js +21 -4
- package/dist/modules/auth/index.js.map +1 -1
- package/dist/modules/auth/repository.d.ts +2 -1
- package/dist/modules/auth/repository.d.ts.map +1 -1
- package/dist/modules/auth/repository.js +1 -0
- package/dist/modules/auth/repository.js.map +1 -1
- package/dist/modules/auth/routes.d.ts.map +1 -1
- package/dist/modules/auth/routes.js +2 -6
- package/dist/modules/auth/routes.js.map +1 -1
- package/dist/modules/auth/schema.d.ts +18 -1
- package/dist/modules/auth/schema.d.ts.map +1 -1
- package/dist/modules/auth/schema.js +12 -1
- package/dist/modules/auth/schema.js.map +1 -1
- package/dist/modules/auth/service.d.ts +18 -0
- package/dist/modules/auth/service.d.ts.map +1 -1
- package/dist/modules/auth/service.js +95 -6
- package/dist/modules/auth/service.js.map +1 -1
- package/dist/modules/auth/session.d.ts +12 -0
- package/dist/modules/auth/session.d.ts.map +1 -1
- package/dist/modules/auth/session.js +12 -0
- package/dist/modules/auth/session.js.map +1 -1
- package/dist/modules/consent-purposes/index.d.ts +1 -1
- package/dist/modules/consent-purposes/index.js +1 -1
- package/dist/modules/consent-purposes/schema.d.ts +3 -3
- package/dist/modules/consent-purposes/schema.js +3 -3
- package/dist/modules/consent-purposes/service.d.ts +1 -1
- package/dist/modules/consent-purposes/service.d.ts.map +1 -1
- package/dist/modules/consent-purposes/service.js +7 -16
- package/dist/modules/consent-purposes/service.js.map +1 -1
- package/dist/modules/consent-purposes/starters.d.ts +1 -1
- package/dist/modules/consent-purposes/tools.js +1 -1
- package/dist/modules/consent-purposes/tools.js.map +1 -1
- package/dist/modules/conversions/clearPointers.d.ts +10 -0
- package/dist/modules/conversions/clearPointers.d.ts.map +1 -0
- package/dist/modules/conversions/clearPointers.js +40 -0
- package/dist/modules/conversions/clearPointers.js.map +1 -0
- package/dist/modules/conversions/factory.d.ts +5 -0
- package/dist/modules/conversions/factory.d.ts.map +1 -0
- package/dist/modules/conversions/factory.js +18 -0
- package/dist/modules/conversions/factory.js.map +1 -0
- package/dist/modules/conversions/fieldMap.d.ts +55 -0
- package/dist/modules/conversions/fieldMap.d.ts.map +1 -0
- package/dist/modules/conversions/fieldMap.js +398 -0
- package/dist/modules/conversions/fieldMap.js.map +1 -0
- package/dist/modules/conversions/index.d.ts +7 -0
- package/dist/modules/conversions/index.d.ts.map +1 -0
- package/dist/modules/conversions/index.js +6 -0
- package/dist/modules/conversions/index.js.map +1 -0
- package/dist/modules/conversions/mcp.d.ts +7 -0
- package/dist/modules/conversions/mcp.d.ts.map +1 -0
- package/dist/modules/conversions/mcp.js +47 -0
- package/dist/modules/conversions/mcp.js.map +1 -0
- package/dist/modules/conversions/repoint.d.ts +19 -0
- package/dist/modules/conversions/repoint.d.ts.map +1 -0
- package/dist/modules/conversions/repoint.js +51 -0
- package/dist/modules/conversions/repoint.js.map +1 -0
- package/dist/modules/conversions/routes.d.ts +26 -0
- package/dist/modules/conversions/routes.d.ts.map +1 -0
- package/dist/modules/conversions/routes.js +23 -0
- package/dist/modules/conversions/routes.js.map +1 -0
- package/dist/modules/conversions/service.d.ts +28 -0
- package/dist/modules/conversions/service.d.ts.map +1 -0
- package/dist/modules/conversions/service.js +170 -0
- package/dist/modules/conversions/service.js.map +1 -0
- package/dist/modules/conversions/wire.d.ts +4 -0
- package/dist/modules/conversions/wire.d.ts.map +1 -0
- package/dist/modules/conversions/wire.js +28 -0
- package/dist/modules/conversions/wire.js.map +1 -0
- package/dist/modules/deals/events.d.ts +9 -0
- package/dist/modules/deals/events.d.ts.map +1 -1
- package/dist/modules/deals/events.js +4 -0
- package/dist/modules/deals/events.js.map +1 -1
- package/dist/modules/deals/index.d.ts.map +1 -1
- package/dist/modules/deals/index.js +4 -2
- package/dist/modules/deals/index.js.map +1 -1
- package/dist/modules/deals/routes.d.ts +2 -0
- package/dist/modules/deals/routes.d.ts.map +1 -1
- package/dist/modules/deals/routes.js +8 -1
- package/dist/modules/deals/routes.js.map +1 -1
- package/dist/modules/deals/schema.d.ts +34 -0
- package/dist/modules/deals/schema.d.ts.map +1 -1
- package/dist/modules/deals/schema.js +7 -2
- package/dist/modules/deals/schema.js.map +1 -1
- package/dist/modules/deals/service.d.ts.map +1 -1
- package/dist/modules/deals/service.js +2 -0
- package/dist/modules/deals/service.js.map +1 -1
- package/dist/modules/deals/tools.d.ts +2 -1
- package/dist/modules/deals/tools.d.ts.map +1 -1
- package/dist/modules/deals/tools.js +3 -1
- package/dist/modules/deals/tools.js.map +1 -1
- package/dist/modules/decisions/repository.d.ts +2 -1
- package/dist/modules/decisions/repository.d.ts.map +1 -1
- package/dist/modules/decisions/repository.js +9 -1
- package/dist/modules/decisions/repository.js.map +1 -1
- package/dist/modules/enquiries/events.d.ts +6 -2
- package/dist/modules/enquiries/events.d.ts.map +1 -1
- package/dist/modules/enquiries/events.js +5 -1
- package/dist/modules/enquiries/events.js.map +1 -1
- package/dist/modules/enquiries/index.d.ts.map +1 -1
- package/dist/modules/enquiries/index.js +4 -2
- package/dist/modules/enquiries/index.js.map +1 -1
- package/dist/modules/enquiries/routes.d.ts +2 -0
- package/dist/modules/enquiries/routes.d.ts.map +1 -1
- package/dist/modules/enquiries/routes.js +9 -9
- package/dist/modules/enquiries/routes.js.map +1 -1
- package/dist/modules/enquiries/schema.d.ts +36 -1
- package/dist/modules/enquiries/schema.d.ts.map +1 -1
- package/dist/modules/enquiries/schema.js +9 -3
- package/dist/modules/enquiries/schema.js.map +1 -1
- package/dist/modules/enquiries/service.d.ts +0 -8
- package/dist/modules/enquiries/service.d.ts.map +1 -1
- package/dist/modules/enquiries/service.js +3 -95
- package/dist/modules/enquiries/service.js.map +1 -1
- package/dist/modules/enquiries/tools.d.ts +2 -1
- package/dist/modules/enquiries/tools.d.ts.map +1 -1
- package/dist/modules/enquiries/tools.js +4 -16
- package/dist/modules/enquiries/tools.js.map +1 -1
- package/dist/modules/forms/applyMappedFields.d.ts +20 -0
- package/dist/modules/forms/applyMappedFields.d.ts.map +1 -0
- package/dist/modules/forms/applyMappedFields.js +169 -0
- package/dist/modules/forms/applyMappedFields.js.map +1 -0
- package/dist/modules/forms/applySubmissionFields.d.ts +18 -0
- package/dist/modules/forms/applySubmissionFields.d.ts.map +1 -0
- package/dist/modules/forms/applySubmissionFields.js +230 -0
- package/dist/modules/forms/applySubmissionFields.js.map +1 -0
- package/dist/modules/forms/fields.d.ts +7 -2
- package/dist/modules/forms/fields.d.ts.map +1 -1
- package/dist/modules/forms/fields.js +17 -6
- package/dist/modules/forms/fields.js.map +1 -1
- package/dist/modules/forms/mapping.d.ts +8 -2
- package/dist/modules/forms/mapping.d.ts.map +1 -1
- package/dist/modules/forms/mapping.js +11 -0
- package/dist/modules/forms/mapping.js.map +1 -1
- package/dist/modules/forms/repository.d.ts +0 -5
- package/dist/modules/forms/repository.d.ts.map +1 -1
- package/dist/modules/forms/repository.js +0 -2
- package/dist/modules/forms/repository.js.map +1 -1
- package/dist/modules/forms/routes.d.ts +2 -30
- package/dist/modules/forms/routes.d.ts.map +1 -1
- package/dist/modules/forms/routes.js +2 -2
- package/dist/modules/forms/routes.js.map +1 -1
- package/dist/modules/forms/schema.d.ts.map +1 -1
- package/dist/modules/forms/schema.js +1 -2
- package/dist/modules/forms/schema.js.map +1 -1
- package/dist/modules/forms/service.d.ts.map +1 -1
- package/dist/modules/forms/service.js +18 -3
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/starters.d.ts +31 -0
- package/dist/modules/forms/starters.d.ts.map +1 -0
- package/dist/modules/forms/starters.js +94 -0
- package/dist/modules/forms/starters.js.map +1 -0
- package/dist/modules/forms/submission.d.ts +1 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +58 -37
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/import-export/customFieldCsv.d.ts +9 -0
- package/dist/modules/import-export/customFieldCsv.d.ts.map +1 -0
- package/dist/modules/import-export/customFieldCsv.js +39 -0
- package/dist/modules/import-export/customFieldCsv.js.map +1 -0
- package/dist/modules/import-export/customFieldImport.d.ts +19 -0
- package/dist/modules/import-export/customFieldImport.d.ts.map +1 -0
- package/dist/modules/import-export/customFieldImport.js +76 -0
- package/dist/modules/import-export/customFieldImport.js.map +1 -0
- package/dist/modules/import-export/drafts.d.ts +57 -3
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +65 -3
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/exportRows.d.ts +15 -13
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +99 -26
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts +42 -11
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +198 -56
- package/dist/modules/import-export/plan.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +58 -2
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +201 -12
- 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 +5 -5
- package/dist/modules/import-export/routes.js.map +1 -1
- package/dist/modules/import-export/service.d.ts +8 -3
- package/dist/modules/import-export/service.d.ts.map +1 -1
- package/dist/modules/import-export/service.js +133 -40
- package/dist/modules/import-export/service.js.map +1 -1
- package/dist/modules/import-export/streams.d.ts +2 -2
- package/dist/modules/import-export/streams.d.ts.map +1 -1
- package/dist/modules/import-export/streams.js +50 -9
- 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 +13 -7
- package/dist/modules/import-export/tools.js.map +1 -1
- package/dist/modules/import-export/validation.d.ts +5 -1
- package/dist/modules/import-export/validation.d.ts.map +1 -1
- package/dist/modules/import-export/validation.js +89 -2
- package/dist/modules/import-export/validation.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts +2 -1
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +358 -25
- package/dist/modules/import-export/writes.js.map +1 -1
- package/dist/modules/lists/repository.d.ts +0 -1
- package/dist/modules/lists/repository.d.ts.map +1 -1
- package/dist/modules/lists/repository.js +0 -1
- package/dist/modules/lists/repository.js.map +1 -1
- package/dist/modules/lists/routes.d.ts +0 -2
- package/dist/modules/lists/routes.d.ts.map +1 -1
- package/dist/modules/lists/routes.js +0 -8
- package/dist/modules/lists/routes.js.map +1 -1
- package/dist/modules/lists/schema.d.ts +0 -17
- package/dist/modules/lists/schema.d.ts.map +1 -1
- package/dist/modules/lists/schema.js +0 -10
- package/dist/modules/lists/schema.js.map +1 -1
- package/dist/modules/lists/service.d.ts +2 -14
- package/dist/modules/lists/service.d.ts.map +1 -1
- package/dist/modules/lists/service.js +7 -53
- package/dist/modules/lists/service.js.map +1 -1
- package/dist/modules/lists/starters.d.ts +12 -0
- package/dist/modules/lists/starters.d.ts.map +1 -0
- package/dist/modules/lists/starters.js +4 -0
- package/dist/modules/lists/starters.js.map +1 -0
- package/dist/modules/mcp/protocol.d.ts.map +1 -1
- package/dist/modules/mcp/protocol.js +13 -0
- package/dist/modules/mcp/protocol.js.map +1 -1
- package/dist/modules/notes/repository.d.ts +2 -0
- package/dist/modules/notes/repository.d.ts.map +1 -1
- package/dist/modules/notes/repository.js +9 -0
- package/dist/modules/notes/repository.js.map +1 -1
- package/dist/modules/opportunities/events.d.ts +9 -0
- package/dist/modules/opportunities/events.d.ts.map +1 -1
- package/dist/modules/opportunities/events.js +4 -0
- package/dist/modules/opportunities/events.js.map +1 -1
- package/dist/modules/opportunities/index.d.ts.map +1 -1
- package/dist/modules/opportunities/index.js +4 -2
- package/dist/modules/opportunities/index.js.map +1 -1
- package/dist/modules/opportunities/routes.d.ts +2 -0
- package/dist/modules/opportunities/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/routes.js +8 -1
- package/dist/modules/opportunities/routes.js.map +1 -1
- package/dist/modules/opportunities/schema.d.ts +34 -0
- package/dist/modules/opportunities/schema.d.ts.map +1 -1
- package/dist/modules/opportunities/schema.js +7 -2
- package/dist/modules/opportunities/schema.js.map +1 -1
- package/dist/modules/opportunities/service.d.ts.map +1 -1
- package/dist/modules/opportunities/service.js +2 -0
- package/dist/modules/opportunities/service.js.map +1 -1
- package/dist/modules/opportunities/tools.d.ts +2 -1
- package/dist/modules/opportunities/tools.d.ts.map +1 -1
- package/dist/modules/opportunities/tools.js +3 -1
- package/dist/modules/opportunities/tools.js.map +1 -1
- package/dist/modules/partnerships/events.d.ts +9 -0
- package/dist/modules/partnerships/events.d.ts.map +1 -1
- package/dist/modules/partnerships/events.js +4 -0
- package/dist/modules/partnerships/events.js.map +1 -1
- package/dist/modules/partnerships/index.d.ts.map +1 -1
- package/dist/modules/partnerships/index.js +4 -2
- package/dist/modules/partnerships/index.js.map +1 -1
- package/dist/modules/partnerships/routes.d.ts +2 -0
- package/dist/modules/partnerships/routes.d.ts.map +1 -1
- package/dist/modules/partnerships/routes.js +8 -1
- package/dist/modules/partnerships/routes.js.map +1 -1
- package/dist/modules/partnerships/schema.d.ts +34 -0
- package/dist/modules/partnerships/schema.d.ts.map +1 -1
- package/dist/modules/partnerships/schema.js +7 -2
- package/dist/modules/partnerships/schema.js.map +1 -1
- package/dist/modules/partnerships/service.d.ts.map +1 -1
- package/dist/modules/partnerships/service.js +2 -0
- package/dist/modules/partnerships/service.js.map +1 -1
- package/dist/modules/partnerships/tools.d.ts +2 -1
- package/dist/modules/partnerships/tools.d.ts.map +1 -1
- package/dist/modules/partnerships/tools.js +3 -1
- package/dist/modules/partnerships/tools.js.map +1 -1
- package/dist/modules/people/personConsentWrites.d.ts +1 -1
- package/dist/modules/people/schema.js +1 -1
- package/dist/modules/people/schema.js.map +1 -1
- package/dist/modules/plans/repository.d.ts +2 -0
- package/dist/modules/plans/repository.d.ts.map +1 -1
- package/dist/modules/plans/repository.js +9 -0
- package/dist/modules/plans/repository.js.map +1 -1
- package/dist/modules/raises/events.d.ts +9 -0
- package/dist/modules/raises/events.d.ts.map +1 -1
- package/dist/modules/raises/events.js +4 -0
- package/dist/modules/raises/events.js.map +1 -1
- package/dist/modules/raises/index.d.ts.map +1 -1
- package/dist/modules/raises/index.js +4 -2
- package/dist/modules/raises/index.js.map +1 -1
- package/dist/modules/raises/routes.d.ts +2 -0
- package/dist/modules/raises/routes.d.ts.map +1 -1
- package/dist/modules/raises/routes.js +8 -1
- package/dist/modules/raises/routes.js.map +1 -1
- package/dist/modules/raises/schema.d.ts +34 -0
- package/dist/modules/raises/schema.d.ts.map +1 -1
- package/dist/modules/raises/schema.js +7 -2
- package/dist/modules/raises/schema.js.map +1 -1
- package/dist/modules/raises/service.d.ts.map +1 -1
- package/dist/modules/raises/service.js +2 -0
- package/dist/modules/raises/service.js.map +1 -1
- package/dist/modules/raises/tools.d.ts +2 -1
- package/dist/modules/raises/tools.d.ts.map +1 -1
- package/dist/modules/raises/tools.js +3 -1
- package/dist/modules/raises/tools.js.map +1 -1
- package/dist/modules/workspace/routes.d.ts +0 -2
- package/dist/modules/workspace/routes.d.ts.map +1 -1
- package/dist/modules/workspace/routes.js +0 -6
- package/dist/modules/workspace/routes.js.map +1 -1
- package/dist/modules/workspace/schema.d.ts +0 -34
- package/dist/modules/workspace/schema.d.ts.map +1 -1
- package/dist/modules/workspace/schema.js +0 -2
- package/dist/modules/workspace/schema.js.map +1 -1
- package/dist/modules/workspace/seedStarterForms.d.ts +17 -0
- package/dist/modules/workspace/seedStarterForms.d.ts.map +1 -0
- package/dist/modules/workspace/seedStarterForms.js +71 -0
- package/dist/modules/workspace/seedStarterForms.js.map +1 -0
- package/dist/modules/workspace/service.d.ts +0 -4
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +20 -10
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/modules/workspace/tools.js +1 -1
- package/dist/modules/workspace/tools.js.map +1 -1
- package/dist/runtime/module.d.ts +63 -1
- package/dist/runtime/module.d.ts.map +1 -1
- package/dist/runtime/registry.d.ts.map +1 -1
- package/dist/runtime/registry.js +40 -2
- package/dist/runtime/registry.js.map +1 -1
- package/dist/testing/fixtures.d.ts.map +1 -1
- package/dist/testing/fixtures.js +1 -0
- package/dist/testing/fixtures.js.map +1 -1
- package/migrations/0037_drop_lists_consent_purpose_id.sql +2 -0
- package/migrations/0038_smart_white_queen.sql +2 -0
- package/migrations/0039_form_map_to_open.sql +1 -0
- package/migrations/0040_pipeline_converted_to.sql +20 -0
- package/migrations/0041_api_key_scopes.sql +1 -0
- package/migrations/0042_drop_workspace_identity.sql +2 -0
- package/migrations/0043_external_sign_in.sql +2 -0
- package/migrations/meta/0038_snapshot.json +6554 -0
- package/migrations/meta/_journal.json +49 -0
- package/package.json +2 -2
- package/src/app.ts +3 -0
- package/src/index.ts +13 -1
- package/src/lib/actor.ts +3 -1
- package/src/lib/apiKeyScopes.ts +213 -0
- package/src/lib/errors.ts +30 -0
- package/src/modules/activities/repository.ts +24 -0
- package/src/modules/agent-tasks/repository.ts +24 -0
- package/src/modules/api-keys/routes.ts +5 -0
- package/src/modules/api-keys/schema.ts +2 -0
- package/src/modules/api-keys/scopeMiddleware.ts +30 -0
- package/src/modules/api-keys/service.ts +36 -2
- package/src/modules/auth/credentials.ts +4 -0
- package/src/modules/auth/index.ts +25 -4
- package/src/modules/auth/repository.ts +2 -1
- package/src/modules/auth/routes.ts +2 -8
- package/src/modules/auth/schema.ts +12 -1
- package/src/modules/auth/service.ts +143 -6
- package/src/modules/auth/session.ts +14 -0
- package/src/modules/consent-purposes/index.ts +1 -1
- package/src/modules/consent-purposes/schema.ts +3 -3
- package/src/modules/consent-purposes/service.ts +7 -16
- package/src/modules/consent-purposes/starters.ts +1 -1
- package/src/modules/consent-purposes/tools.ts +1 -1
- package/src/modules/conversions/clearPointers.ts +81 -0
- package/src/modules/conversions/factory.ts +20 -0
- package/src/modules/conversions/fieldMap.ts +548 -0
- package/src/modules/conversions/index.ts +6 -0
- package/src/modules/conversions/mcp.ts +71 -0
- package/src/modules/conversions/repoint.ts +146 -0
- package/src/modules/conversions/routes.ts +68 -0
- package/src/modules/conversions/service.ts +310 -0
- package/src/modules/conversions/wire.ts +42 -0
- package/src/modules/deals/events.ts +9 -0
- package/src/modules/deals/index.ts +4 -2
- package/src/modules/deals/routes.ts +11 -1
- package/src/modules/deals/schema.ts +10 -2
- package/src/modules/deals/service.ts +3 -0
- package/src/modules/deals/tools.ts +9 -1
- package/src/modules/decisions/repository.ts +23 -1
- package/src/modules/enquiries/events.ts +8 -2
- package/src/modules/enquiries/index.ts +4 -2
- package/src/modules/enquiries/routes.ts +11 -13
- package/src/modules/enquiries/schema.ts +12 -3
- package/src/modules/enquiries/service.ts +3 -150
- package/src/modules/enquiries/tools.ts +9 -18
- package/src/modules/forms/applyMappedFields.ts +248 -0
- package/src/modules/forms/applySubmissionFields.ts +435 -0
- package/src/modules/forms/fields.ts +31 -7
- package/src/modules/forms/mapping.ts +20 -3
- package/src/modules/forms/repository.ts +0 -7
- package/src/modules/forms/routes.ts +1 -2
- package/src/modules/forms/schema.ts +0 -2
- package/src/modules/forms/service.ts +31 -4
- package/src/modules/forms/starters.ts +129 -0
- package/src/modules/forms/submission.ts +135 -69
- package/src/modules/import-export/customFieldCsv.ts +55 -0
- package/src/modules/import-export/customFieldImport.ts +111 -0
- package/src/modules/import-export/drafts.ts +151 -3
- package/src/modules/import-export/exportRows.ts +222 -68
- package/src/modules/import-export/plan.ts +321 -67
- package/src/modules/import-export/repository.ts +356 -14
- package/src/modules/import-export/routes.ts +8 -8
- package/src/modules/import-export/service.ts +208 -45
- package/src/modules/import-export/streams.ts +95 -13
- package/src/modules/import-export/tools.ts +14 -6
- package/src/modules/import-export/validation.ts +128 -0
- package/src/modules/import-export/writes.ts +559 -27
- package/src/modules/lists/repository.ts +0 -2
- package/src/modules/lists/routes.ts +0 -8
- package/src/modules/lists/schema.ts +0 -10
- package/src/modules/lists/service.ts +9 -107
- package/src/modules/lists/starters.ts +16 -0
- package/src/modules/mcp/protocol.ts +18 -0
- package/src/modules/notes/repository.ts +24 -0
- package/src/modules/opportunities/events.ts +9 -0
- package/src/modules/opportunities/index.ts +4 -2
- package/src/modules/opportunities/routes.ts +11 -1
- package/src/modules/opportunities/schema.ts +10 -2
- package/src/modules/opportunities/service.ts +3 -0
- package/src/modules/opportunities/tools.ts +9 -1
- package/src/modules/partnerships/events.ts +9 -0
- package/src/modules/partnerships/index.ts +4 -2
- package/src/modules/partnerships/routes.ts +11 -1
- package/src/modules/partnerships/schema.ts +10 -2
- package/src/modules/partnerships/service.ts +3 -0
- package/src/modules/partnerships/tools.ts +9 -1
- package/src/modules/people/personConsentWrites.ts +1 -1
- package/src/modules/people/schema.ts +1 -1
- package/src/modules/plans/repository.ts +24 -0
- package/src/modules/raises/events.ts +9 -0
- package/src/modules/raises/index.ts +4 -2
- package/src/modules/raises/routes.ts +11 -1
- package/src/modules/raises/schema.ts +10 -2
- package/src/modules/raises/service.ts +3 -0
- package/src/modules/raises/tools.ts +9 -1
- package/src/modules/workspace/routes.ts +0 -6
- package/src/modules/workspace/schema.ts +0 -2
- package/src/modules/workspace/seedStarterForms.ts +98 -0
- package/src/modules/workspace/service.ts +23 -15
- package/src/modules/workspace/tools.ts +1 -1
- package/src/runtime/module.ts +70 -1
- package/src/runtime/registry.ts +54 -0
- package/src/testing/fixtures.ts +1 -0
|
@@ -111,7 +111,6 @@ export async function findList(
|
|
|
111
111
|
export interface ListIdRow {
|
|
112
112
|
readonly id: string
|
|
113
113
|
readonly targetType: string
|
|
114
|
-
readonly consentPurposeId: string | null
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
export async function listListsById(
|
|
@@ -127,7 +126,6 @@ export async function listListsById(
|
|
|
127
126
|
.select({
|
|
128
127
|
id: lists.id,
|
|
129
128
|
targetType: lists.targetType,
|
|
130
|
-
consentPurposeId: lists.consentPurposeId,
|
|
131
129
|
})
|
|
132
130
|
.from(lists)
|
|
133
131
|
.where(and(eq(lists.workspaceId, workspaceId), inArray(lists.id, ids)))
|
|
@@ -31,14 +31,12 @@ export const createBody = z.strictObject({
|
|
|
31
31
|
name: z.string().min(1),
|
|
32
32
|
target_type: z.enum(RECORD_TARGET_TYPES),
|
|
33
33
|
description: z.string().nullable().default(null),
|
|
34
|
-
consent_purpose_id: z.string().min(1).nullable().default(null),
|
|
35
34
|
})
|
|
36
35
|
|
|
37
36
|
export const updateBody = z
|
|
38
37
|
.strictObject({
|
|
39
38
|
name: z.string().min(1),
|
|
40
39
|
description: z.string().nullable(),
|
|
41
|
-
consent_purpose_id: z.string().min(1).nullable(),
|
|
42
40
|
})
|
|
43
41
|
.partial()
|
|
44
42
|
|
|
@@ -56,7 +54,6 @@ export function toCreateInput(body: z.infer<typeof createBody>): CreateListInput
|
|
|
56
54
|
name: body.name,
|
|
57
55
|
targetType: body.target_type,
|
|
58
56
|
description: body.description,
|
|
59
|
-
consentPurposeId: body.consent_purpose_id,
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
|
|
@@ -64,9 +61,6 @@ export function toUpdateInput(body: z.infer<typeof updateBody>): UpdateListInput
|
|
|
64
61
|
return {
|
|
65
62
|
...(body.name === undefined ? {} : { name: body.name }),
|
|
66
63
|
...(body.description === undefined ? {} : { description: body.description }),
|
|
67
|
-
...(body.consent_purpose_id === undefined
|
|
68
|
-
? {}
|
|
69
|
-
: { consentPurposeId: body.consent_purpose_id }),
|
|
70
64
|
}
|
|
71
65
|
}
|
|
72
66
|
|
|
@@ -84,8 +78,6 @@ export function listResponse(list: ListView): Record<string, unknown> {
|
|
|
84
78
|
description: list.description,
|
|
85
79
|
target_type: list.targetType,
|
|
86
80
|
member_count: list.memberCount,
|
|
87
|
-
consent_purpose_id: list.consentPurposeId,
|
|
88
|
-
consent_purpose_slug: list.consentPurposeSlug,
|
|
89
81
|
created_at: list.createdAt.toISOString(),
|
|
90
82
|
updated_at: list.updatedAt.toISOString(),
|
|
91
83
|
}
|
|
@@ -2,7 +2,6 @@ import { RECORD_TARGET_TYPES } from '@kelpie/schemas'
|
|
|
2
2
|
import { foreignKey, index, pgTable, text, timestamp, unique } from 'drizzle-orm/pg-core'
|
|
3
3
|
|
|
4
4
|
import { checkOneOf, createdAt, primaryId, updatedAt } from '../../lib/columns.ts'
|
|
5
|
-
import { consentPurposes } from '../consent-purposes/schema.ts'
|
|
6
5
|
import { workspaces } from '../workspace/schema.ts'
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -35,15 +34,6 @@ export const lists = pgTable(
|
|
|
35
34
|
name: text('name').notNull(),
|
|
36
35
|
description: text('description'),
|
|
37
36
|
targetType: text('target_type').notNull(),
|
|
38
|
-
/**
|
|
39
|
-
* The consent purpose captured when a form submit adds a person to this
|
|
40
|
-
* list. Person lists only — the service refuses a non-null value on any
|
|
41
|
-
* other target type. `restrict` on delete so a purpose in use is not
|
|
42
|
-
* silently unset behind the list's back.
|
|
43
|
-
*/
|
|
44
|
-
consentPurposeId: text('consent_purpose_id').references(() => consentPurposes.id, {
|
|
45
|
-
onDelete: 'restrict',
|
|
46
|
-
}),
|
|
47
37
|
createdAt: createdAt(),
|
|
48
38
|
updatedAt: updatedAt(),
|
|
49
39
|
},
|
|
@@ -9,7 +9,6 @@ import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
|
9
9
|
import { toEventActor } from '../../lib/actor.ts'
|
|
10
10
|
import type { Actor } from '../auth/actor.ts'
|
|
11
11
|
import { requireWorkspaceId } from '../auth/actor.ts'
|
|
12
|
-
import * as consentPurposesRepository from '../consent-purposes/repository.ts'
|
|
13
12
|
import { missingTargets, resolveTargetNames, targetKey } from '../recordTargets.ts'
|
|
14
13
|
import type { RecordTargetType } from '../recordTargets.ts'
|
|
15
14
|
import './events.ts'
|
|
@@ -44,14 +43,8 @@ export interface ListsDependencies {
|
|
|
44
43
|
readonly now: () => Date
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
* plus the denormalised slug of the consent purpose (when set) so a reader
|
|
50
|
-
* needs no second call.
|
|
51
|
-
*/
|
|
52
|
-
export type ListView = Omit<ListWithCount, 'workspaceId'> & {
|
|
53
|
-
readonly consentPurposeSlug: string | null
|
|
54
|
-
}
|
|
46
|
+
/** A list as the API returns one: the stored row minus the tenancy column. */
|
|
47
|
+
export type ListView = Omit<ListWithCount, 'workspaceId'>
|
|
55
48
|
|
|
56
49
|
/** A membership plus the list it points at, as `/v1/list-memberships` returns one. */
|
|
57
50
|
export interface ListMembershipView {
|
|
@@ -78,18 +71,12 @@ export interface CreateListInput {
|
|
|
78
71
|
readonly name: string
|
|
79
72
|
readonly targetType: RecordTargetType
|
|
80
73
|
readonly description: string | null
|
|
81
|
-
/**
|
|
82
|
-
* Optional consent purpose captured on form-driven adds. Person lists only.
|
|
83
|
-
* A non-null value on any other target type is refused at 422.
|
|
84
|
-
*/
|
|
85
|
-
readonly consentPurposeId: string | null
|
|
86
74
|
}
|
|
87
75
|
|
|
88
76
|
/** PATCH semantics: an absent field is left alone. The type never moves. */
|
|
89
77
|
export interface UpdateListInput {
|
|
90
78
|
readonly name?: string | undefined
|
|
91
79
|
readonly description?: string | null | undefined
|
|
92
|
-
readonly consentPurposeId?: string | null | undefined
|
|
93
80
|
}
|
|
94
81
|
|
|
95
82
|
export interface AddListMemberInput {
|
|
@@ -117,10 +104,10 @@ export interface ListsService {
|
|
|
117
104
|
): Promise<readonly ListMembershipView[]>
|
|
118
105
|
}
|
|
119
106
|
|
|
120
|
-
function toView(record: ListWithCount
|
|
107
|
+
function toView(record: ListWithCount): ListView {
|
|
121
108
|
const { workspaceId: _workspaceId, ...view } = record
|
|
122
109
|
|
|
123
|
-
return
|
|
110
|
+
return view
|
|
124
111
|
}
|
|
125
112
|
|
|
126
113
|
function toMembershipView(row: MembershipWithList): ListMembershipView {
|
|
@@ -170,13 +157,6 @@ function alreadyMember(): AppError {
|
|
|
170
157
|
])
|
|
171
158
|
}
|
|
172
159
|
|
|
173
|
-
function purposeNotPersonList(): AppError {
|
|
174
|
-
return AppError.validationFailed(
|
|
175
|
-
'Only person lists capture consent — remove consent_purpose_id or change the list type',
|
|
176
|
-
[{ field: 'consent_purpose_id', message: 'Person lists only' }],
|
|
177
|
-
)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
160
|
export function createListsService(dependencies: ListsDependencies): ListsService {
|
|
181
161
|
async function require(workspaceId: string, id: string): Promise<ListWithCount> {
|
|
182
162
|
const list = await repository.findList(dependencies.db, workspaceId, id)
|
|
@@ -200,77 +180,25 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
200
180
|
}
|
|
201
181
|
}
|
|
202
182
|
|
|
203
|
-
async function resolveConsentPurposeSlug(
|
|
204
|
-
workspaceId: string,
|
|
205
|
-
purposeId: string | null,
|
|
206
|
-
): Promise<string | null> {
|
|
207
|
-
if (purposeId === null) return null
|
|
208
|
-
const [row] = await consentPurposesRepository.listPurposesByIds(
|
|
209
|
-
dependencies.db,
|
|
210
|
-
workspaceId,
|
|
211
|
-
[purposeId],
|
|
212
|
-
)
|
|
213
|
-
return row?.slug ?? null
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
async function requireConsentPurposeExists(
|
|
217
|
-
workspaceId: string,
|
|
218
|
-
purposeId: string,
|
|
219
|
-
): Promise<void> {
|
|
220
|
-
const rows = await consentPurposesRepository.listPurposesByIds(
|
|
221
|
-
dependencies.db,
|
|
222
|
-
workspaceId,
|
|
223
|
-
[purposeId],
|
|
224
|
-
)
|
|
225
|
-
if (rows.length === 0) {
|
|
226
|
-
throw AppError.validationFailed('That consent purpose was not found', [
|
|
227
|
-
{ field: 'consent_purpose_id', message: `No purpose ${purposeId} here` },
|
|
228
|
-
])
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
183
|
return {
|
|
233
184
|
async list(actor, filters, query) {
|
|
234
185
|
const workspaceId = requireWorkspaceId(actor)
|
|
235
186
|
const window = readListWindow(query, LIST_SORTS, DEFAULT_LIST_SORT)
|
|
236
187
|
const rows = await repository.listLists(dependencies.db, workspaceId, filters, window)
|
|
237
|
-
const purposeIds = Array.from(
|
|
238
|
-
new Set(
|
|
239
|
-
rows
|
|
240
|
-
.map((row) => row.consentPurposeId)
|
|
241
|
-
.filter((id): id is string => id !== null),
|
|
242
|
-
),
|
|
243
|
-
)
|
|
244
|
-
const purposes = await consentPurposesRepository.listPurposesByIds(
|
|
245
|
-
dependencies.db,
|
|
246
|
-
workspaceId,
|
|
247
|
-
purposeIds,
|
|
248
|
-
)
|
|
249
|
-
const slugByPurpose = new Map(purposes.map((purpose) => [purpose.id, purpose.slug]))
|
|
250
188
|
|
|
251
|
-
return mapPage(toPage(rows, window, (row) => row.id), (row) =>
|
|
252
|
-
toView(row, row.consentPurposeId === null ? null : (slugByPurpose.get(row.consentPurposeId) ?? null)),
|
|
253
|
-
)
|
|
189
|
+
return mapPage(toPage(rows, window, (row) => row.id), (row) => toView(row))
|
|
254
190
|
},
|
|
255
191
|
|
|
256
192
|
async get(actor, id) {
|
|
257
193
|
const workspaceId = requireWorkspaceId(actor)
|
|
258
194
|
const record = await require(workspaceId, id)
|
|
259
|
-
|
|
260
|
-
return toView(record, slug)
|
|
195
|
+
return toView(record)
|
|
261
196
|
},
|
|
262
197
|
|
|
263
198
|
async create(actor, input) {
|
|
264
199
|
const workspaceId = requireWorkspaceId(actor)
|
|
265
200
|
const id = dependencies.createId('list')
|
|
266
201
|
|
|
267
|
-
if (input.consentPurposeId !== null) {
|
|
268
|
-
if (input.targetType !== 'person') {
|
|
269
|
-
throw purposeNotPersonList()
|
|
270
|
-
}
|
|
271
|
-
await requireConsentPurposeExists(workspaceId, input.consentPurposeId)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
202
|
return dependencies.transaction(
|
|
275
203
|
async ({ tx, events }) => {
|
|
276
204
|
let created
|
|
@@ -281,7 +209,6 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
281
209
|
name: input.name,
|
|
282
210
|
description: input.description,
|
|
283
211
|
targetType: input.targetType,
|
|
284
|
-
consentPurposeId: input.consentPurposeId,
|
|
285
212
|
})
|
|
286
213
|
} catch (error: unknown) {
|
|
287
214
|
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
@@ -293,12 +220,7 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
293
220
|
|
|
294
221
|
events.emit('lists.list.created', { type: 'list', id: created.id }, {})
|
|
295
222
|
|
|
296
|
-
|
|
297
|
-
workspaceId,
|
|
298
|
-
created.consentPurposeId,
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
return toView({ ...created, memberCount: 0 }, slug)
|
|
223
|
+
return toView({ ...created, memberCount: 0 })
|
|
302
224
|
},
|
|
303
225
|
{ workspaceId, actor: toEventActor(actor) },
|
|
304
226
|
)
|
|
@@ -308,32 +230,14 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
308
230
|
const workspaceId = requireWorkspaceId(actor)
|
|
309
231
|
const existing = await require(workspaceId, id)
|
|
310
232
|
|
|
311
|
-
if (
|
|
312
|
-
changes.consentPurposeId !== undefined &&
|
|
313
|
-
changes.consentPurposeId !== null &&
|
|
314
|
-
existing.targetType !== 'person'
|
|
315
|
-
) {
|
|
316
|
-
throw purposeNotPersonList()
|
|
317
|
-
}
|
|
318
|
-
if (
|
|
319
|
-
changes.consentPurposeId !== undefined &&
|
|
320
|
-
changes.consentPurposeId !== null
|
|
321
|
-
) {
|
|
322
|
-
await requireConsentPurposeExists(workspaceId, changes.consentPurposeId)
|
|
323
|
-
}
|
|
324
|
-
|
|
325
233
|
const columns: Partial<repository.ListColumns> = {
|
|
326
234
|
...(changes.name === undefined ? {} : { name: changes.name }),
|
|
327
235
|
...(changes.description === undefined ? {} : { description: changes.description }),
|
|
328
|
-
...(changes.consentPurposeId === undefined
|
|
329
|
-
? {}
|
|
330
|
-
: { consentPurposeId: changes.consentPurposeId }),
|
|
331
236
|
}
|
|
332
237
|
const changed = changedKeys(existing, columns)
|
|
333
238
|
|
|
334
239
|
if (changed.length === 0) {
|
|
335
|
-
|
|
336
|
-
return toView(existing, slug)
|
|
240
|
+
return toView(existing)
|
|
337
241
|
}
|
|
338
242
|
|
|
339
243
|
return dependencies.transaction(
|
|
@@ -358,9 +262,7 @@ export function createListsService(dependencies: ListsDependencies): ListsServic
|
|
|
358
262
|
|
|
359
263
|
events.emit('lists.list.updated', { type: 'list', id }, { changed })
|
|
360
264
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return toView({ ...updated, memberCount: existing.memberCount }, slug)
|
|
265
|
+
return toView({ ...updated, memberCount: existing.memberCount })
|
|
364
266
|
},
|
|
365
267
|
{ workspaceId, actor: toEventActor(actor) },
|
|
366
268
|
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RecordTargetType } from '@kelpie/schemas'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The lists a new workspace starts with. Data, not migrations: a workspace
|
|
5
|
+
* owner may rename or delete them, and add any others they need.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface StarterList {
|
|
9
|
+
readonly slug: string
|
|
10
|
+
readonly name: string
|
|
11
|
+
readonly targetType: RecordTargetType
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const STARTER_LISTS: readonly StarterList[] = [
|
|
15
|
+
{ slug: 'newsletter', name: 'Newsletter', targetType: 'person' },
|
|
16
|
+
]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
|
|
3
3
|
import type { Actor } from '../../lib/actor.ts'
|
|
4
|
+
import { requireApiKeyScope, resolveMcpScope } from '../../lib/apiKeyScopes.ts'
|
|
4
5
|
import { AppError, describeThrown, internalErrorBody, toErrorBody } from '../../lib/errors.ts'
|
|
5
6
|
import type { Logger } from '../../lib/logger.ts'
|
|
6
7
|
import type { McpTool } from '../../runtime/module.ts'
|
|
@@ -317,6 +318,23 @@ async function callTool(
|
|
|
317
318
|
return failure(id, INVALID_PARAMS, `Unknown tool "${parsed.data.name}"`)
|
|
318
319
|
}
|
|
319
320
|
|
|
321
|
+
const requiredScope = resolveMcpScope(parsed.data.name)
|
|
322
|
+
|
|
323
|
+
if (requiredScope !== null) {
|
|
324
|
+
try {
|
|
325
|
+
requireApiKeyScope(actor, requiredScope)
|
|
326
|
+
} catch (error: unknown) {
|
|
327
|
+
if (error instanceof AppError && error.code === 'forbidden') {
|
|
328
|
+
return success(
|
|
329
|
+
id,
|
|
330
|
+
completeResult(dependencies, era, toolFailure(dependencies.logger, tool.name, error)),
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
throw error
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
320
338
|
try {
|
|
321
339
|
// `arguments` is optional on the wire and every tool schema is an object, so
|
|
322
340
|
// an absent one is an empty object rather than a validation failure the
|
|
@@ -128,3 +128,27 @@ export async function deleteForTarget(
|
|
|
128
128
|
|
|
129
129
|
return deleted.length
|
|
130
130
|
}
|
|
131
|
+
|
|
132
|
+
/** Moves every note from one target to another inside a conversion transaction. */
|
|
133
|
+
export async function repointForTarget(
|
|
134
|
+
db: Queryable,
|
|
135
|
+
workspaceId: string,
|
|
136
|
+
fromType: string,
|
|
137
|
+
fromId: string,
|
|
138
|
+
toType: string,
|
|
139
|
+
toId: string,
|
|
140
|
+
): Promise<number> {
|
|
141
|
+
const updated = await db
|
|
142
|
+
.update(notes)
|
|
143
|
+
.set({ targetType: toType, targetId: toId })
|
|
144
|
+
.where(
|
|
145
|
+
and(
|
|
146
|
+
eq(notes.workspaceId, workspaceId),
|
|
147
|
+
eq(notes.targetType, fromType),
|
|
148
|
+
eq(notes.targetId, fromId),
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
.returning({ id: notes.id })
|
|
152
|
+
|
|
153
|
+
return updated.length
|
|
154
|
+
}
|
|
@@ -12,6 +12,10 @@ export const opportunitiesEvents = {
|
|
|
12
12
|
fromStageId: z.string().nullable(),
|
|
13
13
|
toStageId: z.string(),
|
|
14
14
|
}),
|
|
15
|
+
'opportunities.opportunity.converted': z.object({
|
|
16
|
+
targetType: z.string(),
|
|
17
|
+
targetId: z.string(),
|
|
18
|
+
}),
|
|
15
19
|
} satisfies ModuleEventCatalog
|
|
16
20
|
|
|
17
21
|
export type OpportunityCreatedData = Record<string, never>
|
|
@@ -23,6 +27,10 @@ export interface OpportunityStageChangedData {
|
|
|
23
27
|
readonly fromStageId: string | null
|
|
24
28
|
readonly toStageId: string
|
|
25
29
|
}
|
|
30
|
+
export interface OpportunityConvertedData {
|
|
31
|
+
readonly targetType: string
|
|
32
|
+
readonly targetId: string
|
|
33
|
+
}
|
|
26
34
|
|
|
27
35
|
declare module '../../runtime/events.ts' {
|
|
28
36
|
interface KelpieEventMap {
|
|
@@ -30,5 +38,6 @@ declare module '../../runtime/events.ts' {
|
|
|
30
38
|
'opportunities.opportunity.updated': OpportunityUpdatedData
|
|
31
39
|
'opportunities.opportunity.deleted': OpportunityDeletedData
|
|
32
40
|
'opportunities.opportunity.stage_changed': OpportunityStageChangedData
|
|
41
|
+
'opportunities.opportunity.converted': OpportunityConvertedData
|
|
33
42
|
}
|
|
34
43
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
2
|
import { createActivityRecorder } from '../activities/index.ts'
|
|
3
|
+
import { createConversionsFromContext } from '../conversions/index.ts'
|
|
3
4
|
import { createCustomFieldValues } from '../custom-fields/index.ts'
|
|
4
5
|
import { opportunitiesEvents } from './events.ts'
|
|
5
6
|
import { mountOpportunitiesRoutes } from './routes.ts'
|
|
@@ -22,6 +23,7 @@ export function createOpportunitiesModule(migrationsDirectory: string): KelpieMo
|
|
|
22
23
|
events: opportunitiesEvents,
|
|
23
24
|
|
|
24
25
|
register(context) {
|
|
26
|
+
const conversions = createConversionsFromContext(context)
|
|
25
27
|
const service = createOpportunitiesService({
|
|
26
28
|
db: context.db,
|
|
27
29
|
transaction: context.transaction,
|
|
@@ -37,10 +39,10 @@ export function createOpportunitiesModule(migrationsDirectory: string): KelpieMo
|
|
|
37
39
|
context.schema(schema, migrationsDirectory)
|
|
38
40
|
|
|
39
41
|
context.routes((router) => {
|
|
40
|
-
mountOpportunitiesRoutes(router, { db: context.db, now: context.now, service })
|
|
42
|
+
mountOpportunitiesRoutes(router, { db: context.db, now: context.now, service, conversions })
|
|
41
43
|
})
|
|
42
44
|
|
|
43
|
-
registerOpportunitiesTools(context.mcp, service)
|
|
45
|
+
registerOpportunitiesTools(context.mcp, service, conversions)
|
|
44
46
|
|
|
45
47
|
return Promise.resolve()
|
|
46
48
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { customFieldsPatchShape } from '@kelpie/schemas'
|
|
1
|
+
import { convertPipelineRecordBody, convertedToResponse, customFieldsPatchShape } from '@kelpie/schemas'
|
|
2
2
|
import type { Context, Hono } from 'hono'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
@@ -8,6 +8,8 @@ import type { Actor } from '../auth/actor.ts'
|
|
|
8
8
|
import { resolveActorFrom } from '../auth/credentials.ts'
|
|
9
9
|
import type { CredentialDependencies } from '../auth/credentials.ts'
|
|
10
10
|
import { renderCustomFieldsForWire } from '../custom-fields/wire.ts'
|
|
11
|
+
import { mountPipelineConvertRoute } from '../conversions/routes.ts'
|
|
12
|
+
import type { ConversionsService } from '../conversions/index.ts'
|
|
11
13
|
import type {
|
|
12
14
|
CreateOpportunityInput,
|
|
13
15
|
OpportunitiesService,
|
|
@@ -55,6 +57,7 @@ export const updateBody = z.strictObject(opportunityShape).partial()
|
|
|
55
57
|
|
|
56
58
|
export interface OpportunitiesRoutesDependencies extends CredentialDependencies {
|
|
57
59
|
readonly service: OpportunitiesService
|
|
60
|
+
readonly conversions: ConversionsService
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
export function toCreateInput(body: z.infer<typeof createBody>): CreateOpportunityInput {
|
|
@@ -99,6 +102,7 @@ export function opportunityResponse(opportunity: OpportunityView): Record<string
|
|
|
99
102
|
person_ids: opportunity.personIds,
|
|
100
103
|
summary: opportunity.summary,
|
|
101
104
|
tags: opportunity.tags,
|
|
105
|
+
converted_to: convertedToResponse(opportunity.convertedTargetType, opportunity.convertedTargetId),
|
|
102
106
|
custom_fields: renderCustomFieldsForWire(opportunity.customFields),
|
|
103
107
|
created_at: opportunity.createdAt.toISOString(),
|
|
104
108
|
updated_at: opportunity.updatedAt.toISOString(),
|
|
@@ -162,4 +166,10 @@ export function mountOpportunitiesRoutes(
|
|
|
162
166
|
|
|
163
167
|
return context.body(null, 204)
|
|
164
168
|
})
|
|
169
|
+
|
|
170
|
+
mountPipelineConvertRoute(router, '/opportunities/:id/convert', {
|
|
171
|
+
...dependencies,
|
|
172
|
+
sourceKind: 'opportunity',
|
|
173
|
+
bodySchema: convertPipelineRecordBody,
|
|
174
|
+
})
|
|
165
175
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm'
|
|
2
|
+
import { check, date, index, jsonb, pgTable, text } from 'drizzle-orm/pg-core'
|
|
3
|
+
import { PIPELINE_KINDS } from '@kelpie/schemas'
|
|
1
4
|
import type { CustomFieldValue } from '@kelpie/schemas'
|
|
2
|
-
import { date, index, jsonb, pgTable, text } from 'drizzle-orm/pg-core'
|
|
3
5
|
|
|
4
|
-
import { createdAt, primaryId, searchVector, updatedAt } from '../../lib/columns.ts'
|
|
6
|
+
import { createdAt, oneOf, primaryId, searchVector, updatedAt } from '../../lib/columns.ts'
|
|
5
7
|
import type { SearchVectorPart } from '../../lib/columns.ts'
|
|
6
8
|
import { companies } from '../companies/schema.ts'
|
|
7
9
|
import { pipelineStages } from '../pipelines/schema.ts'
|
|
@@ -31,6 +33,8 @@ export const opportunities = pgTable(
|
|
|
31
33
|
expectedClose: date('expected_close'),
|
|
32
34
|
summary: text('summary').notNull().default(''),
|
|
33
35
|
tags: text('tags').array().notNull().default([]),
|
|
36
|
+
convertedTargetType: text('converted_target_type'),
|
|
37
|
+
convertedTargetId: text('converted_target_id'),
|
|
34
38
|
// Workspace-defined fields, keyed by definition key. See people/schema.ts.
|
|
35
39
|
customFields: jsonb('custom_fields')
|
|
36
40
|
.$type<Readonly<Record<string, CustomFieldValue>>>()
|
|
@@ -49,5 +53,9 @@ export const opportunities = pgTable(
|
|
|
49
53
|
index('opportunities_workspace_idx').on(table.workspaceId),
|
|
50
54
|
index('opportunities_stage_idx').on(table.stageId),
|
|
51
55
|
index('opportunities_search_idx').using('gin', table.searchVector),
|
|
56
|
+
check(
|
|
57
|
+
'opportunities_converted_target_type_check',
|
|
58
|
+
sql`${table.convertedTargetType} is null or ${oneOf('opportunities_converted_target_type_check', table.convertedTargetType, PIPELINE_KINDS)}`,
|
|
59
|
+
),
|
|
52
60
|
],
|
|
53
61
|
)
|
|
@@ -21,6 +21,7 @@ import type { Actor } from '../auth/actor.ts'
|
|
|
21
21
|
import { actorMemberId, requireWorkspaceId } from '../auth/actor.ts'
|
|
22
22
|
import './events.ts'
|
|
23
23
|
import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
|
|
24
|
+
import { clearConversionPointersToTarget } from '../conversions/clearPointers.ts'
|
|
24
25
|
import * as companyRepository from '../companies/repository.ts'
|
|
25
26
|
import type { CustomFieldValuesValidator } from '../custom-fields/values.ts'
|
|
26
27
|
import * as personLinks from '../personLinks.ts'
|
|
@@ -494,6 +495,8 @@ export function createOpportunitiesService(
|
|
|
494
495
|
await dependencies.transaction(async ({ tx, events }) => {
|
|
495
496
|
await require(workspaceId, id)
|
|
496
497
|
|
|
498
|
+
await clearConversionPointersToTarget(tx, workspaceId, 'opportunity', id)
|
|
499
|
+
|
|
497
500
|
// Notes, activities, decisions, plan items, and person_links have no
|
|
498
501
|
// foreign key to their target, so the deleting service removes them
|
|
499
502
|
// here, in the same transaction. Nothing else references an opportunity.
|
|
@@ -2,6 +2,8 @@ import { z } from 'zod'
|
|
|
2
2
|
|
|
3
3
|
import type { McpToolRegistry } from '../../runtime/module.ts'
|
|
4
4
|
import { idArg, idSetArg, listWindowShape, registerCrudTools, termArg, toSet } from '../crudTools.ts'
|
|
5
|
+
import type { ConversionsService } from '../conversions/index.ts'
|
|
6
|
+
import { registerPipelineConvertTool } from '../conversions/mcp.ts'
|
|
5
7
|
import { createBody, opportunityResponse, toCreateInput, toUpdateInput, updateBody } from './routes.ts'
|
|
6
8
|
import type { OpportunitiesService } from './service.ts'
|
|
7
9
|
|
|
@@ -16,7 +18,11 @@ const listArgs = z.strictObject({
|
|
|
16
18
|
person_id: idSetArg.optional().describe('Only opportunities any of these people are on.'),
|
|
17
19
|
})
|
|
18
20
|
|
|
19
|
-
export function registerOpportunitiesTools(
|
|
21
|
+
export function registerOpportunitiesTools(
|
|
22
|
+
mcp: McpToolRegistry,
|
|
23
|
+
service: OpportunitiesService,
|
|
24
|
+
conversions: ConversionsService,
|
|
25
|
+
): void {
|
|
20
26
|
registerCrudTools(mcp, {
|
|
21
27
|
resource: 'opportunities',
|
|
22
28
|
subject: 'opportunity',
|
|
@@ -38,4 +44,6 @@ export function registerOpportunitiesTools(mcp: McpToolRegistry, service: Opport
|
|
|
38
44
|
updateArgs: updateBody.extend({ id: idArg }),
|
|
39
45
|
toUpdateInput,
|
|
40
46
|
})
|
|
47
|
+
|
|
48
|
+
registerPipelineConvertTool(mcp, conversions, 'opportunity')
|
|
41
49
|
}
|
|
@@ -12,6 +12,10 @@ export const partnershipsEvents = {
|
|
|
12
12
|
fromStageId: z.string().nullable(),
|
|
13
13
|
toStageId: z.string(),
|
|
14
14
|
}),
|
|
15
|
+
'partnerships.partnership.converted': z.object({
|
|
16
|
+
targetType: z.string(),
|
|
17
|
+
targetId: z.string(),
|
|
18
|
+
}),
|
|
15
19
|
} satisfies ModuleEventCatalog
|
|
16
20
|
|
|
17
21
|
export type PartnershipCreatedData = Record<string, never>
|
|
@@ -23,6 +27,10 @@ export interface PartnershipStageChangedData {
|
|
|
23
27
|
readonly fromStageId: string | null
|
|
24
28
|
readonly toStageId: string
|
|
25
29
|
}
|
|
30
|
+
export interface PartnershipConvertedData {
|
|
31
|
+
readonly targetType: string
|
|
32
|
+
readonly targetId: string
|
|
33
|
+
}
|
|
26
34
|
|
|
27
35
|
declare module '../../runtime/events.ts' {
|
|
28
36
|
interface KelpieEventMap {
|
|
@@ -30,5 +38,6 @@ declare module '../../runtime/events.ts' {
|
|
|
30
38
|
'partnerships.partnership.updated': PartnershipUpdatedData
|
|
31
39
|
'partnerships.partnership.deleted': PartnershipDeletedData
|
|
32
40
|
'partnerships.partnership.stage_changed': PartnershipStageChangedData
|
|
41
|
+
'partnerships.partnership.converted': PartnershipConvertedData
|
|
33
42
|
}
|
|
34
43
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
2
|
import { createActivityRecorder } from '../activities/index.ts'
|
|
3
|
+
import { createConversionsFromContext } from '../conversions/index.ts'
|
|
3
4
|
import { createCustomFieldValues } from '../custom-fields/index.ts'
|
|
4
5
|
import { partnershipsEvents } from './events.ts'
|
|
5
6
|
import { mountPartnershipsRoutes } from './routes.ts'
|
|
@@ -22,6 +23,7 @@ export function createPartnershipsModule(migrationsDirectory: string): KelpieMod
|
|
|
22
23
|
events: partnershipsEvents,
|
|
23
24
|
|
|
24
25
|
register(context) {
|
|
26
|
+
const conversions = createConversionsFromContext(context)
|
|
25
27
|
const service = createPartnershipsService({
|
|
26
28
|
db: context.db,
|
|
27
29
|
transaction: context.transaction,
|
|
@@ -37,10 +39,10 @@ export function createPartnershipsModule(migrationsDirectory: string): KelpieMod
|
|
|
37
39
|
context.schema(schema, migrationsDirectory)
|
|
38
40
|
|
|
39
41
|
context.routes((router) => {
|
|
40
|
-
mountPartnershipsRoutes(router, { db: context.db, now: context.now, service })
|
|
42
|
+
mountPartnershipsRoutes(router, { db: context.db, now: context.now, service, conversions })
|
|
41
43
|
})
|
|
42
44
|
|
|
43
|
-
registerPartnershipsTools(context.mcp, service)
|
|
45
|
+
registerPartnershipsTools(context.mcp, service, conversions)
|
|
44
46
|
|
|
45
47
|
return Promise.resolve()
|
|
46
48
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { customFieldsPatchShape } from '@kelpie/schemas'
|
|
1
|
+
import { convertPipelineRecordBody, convertedToResponse, customFieldsPatchShape } from '@kelpie/schemas'
|
|
2
2
|
import type { Context, Hono } from 'hono'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
@@ -8,6 +8,8 @@ import type { Actor } from '../auth/actor.ts'
|
|
|
8
8
|
import { resolveActorFrom } from '../auth/credentials.ts'
|
|
9
9
|
import type { CredentialDependencies } from '../auth/credentials.ts'
|
|
10
10
|
import { renderCustomFieldsForWire } from '../custom-fields/wire.ts'
|
|
11
|
+
import { mountPipelineConvertRoute } from '../conversions/routes.ts'
|
|
12
|
+
import type { ConversionsService } from '../conversions/index.ts'
|
|
11
13
|
import type {
|
|
12
14
|
CreatePartnershipInput,
|
|
13
15
|
PartnershipView,
|
|
@@ -59,6 +61,7 @@ export const updateBody = z.strictObject(partnershipShape).partial()
|
|
|
59
61
|
|
|
60
62
|
export interface PartnershipsRoutesDependencies extends CredentialDependencies {
|
|
61
63
|
readonly service: PartnershipsService
|
|
64
|
+
readonly conversions: ConversionsService
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
export function toCreateInput(body: z.infer<typeof createBody>): CreatePartnershipInput {
|
|
@@ -111,6 +114,7 @@ export function partnershipResponse(partnership: PartnershipView): Record<string
|
|
|
111
114
|
person_ids: partnership.personIds,
|
|
112
115
|
summary: partnership.summary,
|
|
113
116
|
tags: partnership.tags,
|
|
117
|
+
converted_to: convertedToResponse(partnership.convertedTargetType, partnership.convertedTargetId),
|
|
114
118
|
custom_fields: renderCustomFieldsForWire(partnership.customFields),
|
|
115
119
|
created_at: partnership.createdAt.toISOString(),
|
|
116
120
|
updated_at: partnership.updatedAt.toISOString(),
|
|
@@ -174,4 +178,10 @@ export function mountPartnershipsRoutes(
|
|
|
174
178
|
|
|
175
179
|
return context.body(null, 204)
|
|
176
180
|
})
|
|
181
|
+
|
|
182
|
+
mountPipelineConvertRoute(router, '/partnerships/:id/convert', {
|
|
183
|
+
...dependencies,
|
|
184
|
+
sourceKind: 'partnership',
|
|
185
|
+
bodySchema: convertPipelineRecordBody,
|
|
186
|
+
})
|
|
177
187
|
}
|