feat(server): run server-exposed logic functions in the owner workspace (#22002)
## Summary Implements the server-level logic-function tier in the simplest shape: a logic function is "server-exposed" iff its manifest entry carries `serverWebhookTriggerSettings`. Execution delegates to the owner-workspace copy of that function — billing, throttling, env vars, and the existing executor all apply uniformly against that workspace. Supersedes #21971 with the simplified design from that discussion (no `applicationRegistrationLogicFunction` registry, no dedicated manifest type, no separate SDK helper, no special throttling). ## Design - **Manifest**: `LogicFunctionManifest` gains `serverWebhookTriggerSettings?`. The declarative `workspaceIdResolver` shape is dropped. - **Materialization**: those settings become two new jsonb columns on `LogicFunctionEntity`. The manifest → flat converter and the create-from-source DTO/util forward them; the property-config map and editable-properties list are extended. - **Lookup**: a single QB query joins `logicFunction → application → applicationRegistration` and filters on `lf.workspaceId = reg.workspaceId` to get only the owner workspace's copy. - **Webhook**: `POST /webhooks/server/:logicFunctionUniversalIdentifier` → `ServerWebhookTriggerService.handle` → join lookup → `LogicFunctionTriggerService.run`. No registry table, no `:applicationRegistrationUniversalIdentifier` segment, no resolver. - **Gate**: `IS_SERVER_LOGIC_FUNCTION_ENABLED` config var (disabled by default). ## Test plan - [x] `npx jest server-webhook-trigger` — 9 unit tests across the webhook service. - [x] `npx jest logic-function` — 88 existing tests stay green. - [x] `npx nx typecheck twenty-server`. - [x] `npx nx lint:diff-with-main twenty-server`. - [x] Reset DB → init → run `database:migrate:prod` → run `database:migrate:generate --name pending-migration-check` → no drift. - [ ] Manual: hit `/webhooks/server/<uid>` end-to-end against a manifest carrying `serverWebhookTriggerSettings`. https://claude.ai/code/session_01GgsnCGmYJ26xRirx8va1Yh --- _Generated by [Claude Code](https://claude.ai/code/session_01GgsnCGmYJ26xRirx8va1Yh)_ <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22002?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -107,10 +107,7 @@ export type {
|
||||
} from './roleManifestType';
|
||||
export type { RunAgentInput, RunAgentResult } from './runAgentType';
|
||||
export type { ServerVariables } from './server-variables.type';
|
||||
export type {
|
||||
WebhookWorkspaceIdSource,
|
||||
ServerWebhookTriggerSettings,
|
||||
} from './serverWebhookTriggerSettingsType';
|
||||
export type { ServerRouteTriggerSettings } from './serverRouteTriggerSettingsType';
|
||||
export type { SkillManifest } from './skillManifestType';
|
||||
export type { StoredOAuthConnectionProviderConfig } from './storedOAuthConnectionProviderConfigType';
|
||||
export type { SyncableEntityOptions } from './syncableEntityOptionsType';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type ServerWebhookTriggerSettings } from '@/application/serverWebhookTriggerSettingsType';
|
||||
import { type ServerRouteTriggerSettings } from '@/application/serverRouteTriggerSettingsType';
|
||||
import { type SyncableEntityOptions } from '@/application/syncableEntityOptionsType';
|
||||
import { type ToolTriggerSettings } from '@/application/toolTriggerSettingsType';
|
||||
import { type WorkflowActionTriggerSettings } from '@/application/workflowActionTriggerSettingsType';
|
||||
@@ -11,7 +11,7 @@ export type LogicFunctionManifest = SyncableEntityOptions & {
|
||||
cronTriggerSettings?: CronTriggerSettings;
|
||||
databaseEventTriggerSettings?: DatabaseEventTriggerSettings;
|
||||
httpRouteTriggerSettings?: HttpRouteTriggerSettings;
|
||||
serverWebhookTriggerSettings?: ServerWebhookTriggerSettings;
|
||||
serverRouteTriggerSettings?: ServerRouteTriggerSettings;
|
||||
toolTriggerSettings?: ToolTriggerSettings;
|
||||
workflowActionTriggerSettings?: WorkflowActionTriggerSettings;
|
||||
sourceHandlerPath: string;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export type ServerRouteTriggerSettings = {
|
||||
forwardedRequestHeaders?: string[];
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
export type WebhookWorkspaceIdSource = 'body' | 'query' | 'header';
|
||||
|
||||
export type ServerWebhookTriggerSettings = {
|
||||
workspaceIdResolver: {
|
||||
source: WebhookWorkspaceIdSource;
|
||||
path: string;
|
||||
};
|
||||
forwardedRequestHeaders?: string[];
|
||||
};
|
||||
Reference in New Issue
Block a user