Rename serverlessFunction to logicFunction (#17494)

## Summary

Rename "Serverless Function" to "Logic Function" across the codebase for
clearer naming.

### Environment Variable Changes

| Old | New |
|-----|-----|
| `SERVERLESS_TYPE` | `LOGIC_FUNCTION_TYPE` |
| `SERVERLESS_LAMBDA_REGION` | `LOGIC_FUNCTION_LAMBDA_REGION` |
| `SERVERLESS_LAMBDA_ROLE` | `LOGIC_FUNCTION_LAMBDA_ROLE` |
| `SERVERLESS_LAMBDA_SUBHOSTING_URL` |
`LOGIC_FUNCTION_LAMBDA_SUBHOSTING_URL` |
| `SERVERLESS_LAMBDA_ACCESS_KEY_ID` |
`LOGIC_FUNCTION_LAMBDA_ACCESS_KEY_ID` |
| `SERVERLESS_LAMBDA_SECRET_ACCESS_KEY` |
`LOGIC_FUNCTION_LAMBDA_SECRET_ACCESS_KEY` |

### Breaking Changes

- Environment variables must be updated in production deployments
- Database migration renames `serverlessFunction` → `logicFunction`
tables
This commit is contained in:
Charles Bochet
2026-01-28 01:42:19 +01:00
committed by GitHub
parent 59d123d2b1
commit da6f1bbef3
351 changed files with 5054 additions and 5139 deletions
@@ -0,0 +1,9 @@
import { ID, InputType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
@InputType()
export class BuildDraftLogicFunctionInput {
@IDField(() => ID, { description: 'The id of the function.' })
id!: string;
}
@@ -0,0 +1,73 @@
import { Field, HideField, InputType } from '@nestjs/graphql';
import {
IsBoolean,
IsNotEmpty,
IsNumber,
IsObject,
IsOptional,
IsString,
Max,
Min,
} from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
import { Sources } from 'twenty-shared/types';
@InputType()
export class CreateLogicFunctionInput {
@IsString()
@IsNotEmpty()
@Field()
name: string;
@IsString()
@IsOptional()
@Field({ nullable: true })
description?: string;
@IsNumber()
@Field({ nullable: true })
@Min(1)
@Max(900)
@IsOptional()
timeoutSeconds?: number;
@HideField()
applicationId?: string;
@HideField()
universalIdentifier?: string;
@HideField()
logicFunctionLayerId?: string;
@Field(() => graphqlTypeJson, { nullable: true })
@IsObject()
@IsOptional()
code?: Sources;
@IsString()
@Field({ nullable: true })
@IsOptional()
handlerName?: string;
@IsString()
@Field({ nullable: true })
@IsOptional()
sourceHandlerPath?: string;
@IsString()
@Field({ nullable: true })
@IsOptional()
builtHandlerPath?: string;
@Field(() => graphqlTypeJson, { nullable: true })
@IsObject()
@IsOptional()
toolInputSchema?: object;
@IsBoolean()
@Field({ nullable: true })
@IsOptional()
isTool?: boolean;
}
@@ -0,0 +1,29 @@
import { Field, InputType } from '@nestjs/graphql';
import { IsNotEmpty, IsObject, IsUUID } from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType()
export class ExecuteLogicFunctionInput {
@Field(() => UUIDScalarType, {
description: 'Id of the logic function to execute',
})
@IsNotEmpty()
@IsUUID()
id: string;
@Field(() => graphqlTypeJson, {
description: 'Payload in JSON format',
})
@IsObject()
payload: JSON;
@Field(() => String, {
nullable: false,
description: 'Version of the logic function to execute',
defaultValue: 'latest',
})
version: string;
}
@@ -0,0 +1,16 @@
import { Field, ID, InputType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
@InputType()
export class GetLogicFunctionSourceCodeInput {
@IDField(() => ID, { description: 'The id of the function.' })
id!: string;
@Field(() => String, {
nullable: false,
description: 'The version of the function',
defaultValue: 'draft',
})
version: string;
}
@@ -0,0 +1,48 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { IsObject, IsOptional } from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
export enum LogicFunctionExecutionStatus {
IDLE = 'IDLE',
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
}
registerEnumType(LogicFunctionExecutionStatus, {
name: 'LogicFunctionExecutionStatus',
description: 'Status of the logic function execution',
});
@ObjectType('LogicFunctionExecutionResult')
export class LogicFunctionExecutionResultDTO {
@IsObject()
@Field(() => graphqlTypeJson, {
description: 'Execution result in JSON format',
nullable: true,
})
data?: JSON;
@Field({ description: 'Execution Logs' })
logs: string;
@Field({ description: 'Execution duration in milliseconds' })
duration: number;
@Field(() => LogicFunctionExecutionStatus, {
description: 'Execution status',
})
status: LogicFunctionExecutionStatus;
@IsObject()
@IsOptional()
@Field(() => graphqlTypeJson, {
description: 'Execution error in JSON format',
nullable: true,
})
error?: {
errorType: string;
errorMessage: string;
stackTrace: string;
};
}
@@ -0,0 +1,9 @@
import { ID, InputType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
@InputType()
export class LogicFunctionIdInput {
@IDField(() => ID, { description: 'The id of the function.' })
id!: string;
}
@@ -0,0 +1,22 @@
import { Field, HideField, ObjectType } from '@nestjs/graphql';
@ObjectType('LogicFunctionLogs')
export class LogicFunctionLogsDTO {
@Field({ description: 'Execution Logs' })
logs: string;
@HideField()
applicationUniversalIdentifier?: string;
@HideField()
applicationId?: string;
@HideField()
name?: string;
@HideField()
id?: string;
@HideField()
universalIdentifier?: string;
}
@@ -0,0 +1,21 @@
import { Field, InputType } from '@nestjs/graphql';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType('LogicFunctionLogsInput')
export class LogicFunctionLogsInput {
@Field(() => UUIDScalarType, { nullable: true })
applicationId?: string;
@Field(() => UUIDScalarType, { nullable: true })
applicationUniversalIdentifier?: string;
@Field(() => String, { nullable: true })
name?: string;
@Field(() => UUIDScalarType, { nullable: true })
id?: string;
@Field(() => UUIDScalarType, { nullable: true })
universalIdentifier?: string;
}
@@ -0,0 +1,126 @@
import { Field, HideField, ObjectType } from '@nestjs/graphql';
import {
Authorize,
IDField,
QueryOptions,
} from '@ptc-org/nestjs-query-graphql';
import {
IsArray,
IsBoolean,
IsDateString,
IsNotEmpty,
IsNumber,
IsObject,
IsOptional,
IsString,
IsUUID,
} from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import {
CronTriggerSettings,
DatabaseEventTriggerSettings,
HttpRouteTriggerSettings,
} from 'src/engine/metadata-modules/logic-function/logic-function.entity';
@ObjectType('LogicFunction')
@Authorize({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
authorize: (context: any) => ({
workspaceId: { eq: context?.req?.workspace?.id },
}),
})
@QueryOptions({
defaultResultSize: 10,
maxResultsSize: 1000,
})
export class LogicFunctionDTO {
@IsUUID()
@IsNotEmpty()
@IDField(() => UUIDScalarType)
id: string;
@IsString()
@Field()
name: string;
@IsString()
@Field({ nullable: true })
description?: string;
@IsString()
@IsNotEmpty()
@Field()
runtime: string;
@IsNumber()
@Field()
timeoutSeconds: number;
@IsString()
@Field({ nullable: true })
latestVersion?: string;
@IsString()
@Field()
sourceHandlerPath: string;
@IsString()
@Field()
builtHandlerPath: string;
@IsString()
@Field()
handlerName: string;
@IsArray()
@Field(() => [String], { nullable: false })
publishedVersions: string[];
@IsObject()
@IsOptional()
@Field(() => graphqlTypeJson, { nullable: true })
toolInputSchema?: object;
@IsBoolean()
@Field()
isTool: boolean;
@IsObject()
@IsOptional()
@Field(() => graphqlTypeJson, { nullable: true })
cronTriggerSettings?: CronTriggerSettings;
@IsObject()
@IsOptional()
@Field(() => graphqlTypeJson, { nullable: true })
databaseEventTriggerSettings?: DatabaseEventTriggerSettings;
@IsObject()
@IsOptional()
@Field(() => graphqlTypeJson, { nullable: true })
httpRouteTriggerSettings?: HttpRouteTriggerSettings;
@IsUUID()
@IsOptional()
@Field(() => UUIDScalarType, { nullable: true })
applicationId?: string;
@IsUUID()
@IsOptional()
@Field(() => UUIDScalarType, { nullable: true })
universalIdentifier?: string;
@HideField()
workspaceId: string;
@IsDateString()
@Field()
createdAt: Date;
@IsDateString()
@Field()
updatedAt: Date;
}
@@ -0,0 +1,9 @@
import { ID, InputType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
@InputType()
export class PublishLogicFunctionInput {
@IDField(() => ID, { description: 'The id of the function.' })
id!: string;
}
@@ -0,0 +1,81 @@
import { Field, InputType } from '@nestjs/graphql';
import { Type } from 'class-transformer';
import {
IsBoolean,
IsNotEmpty,
IsNumber,
IsObject,
IsOptional,
IsString,
IsUUID,
Max,
Min,
ValidateNested,
} from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
import type { Sources } from 'twenty-shared/types';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType()
class UpdateLogicFunctionInputUpdates {
@IsString()
@Field()
@IsOptional()
name?: string;
@IsString()
@Field({ nullable: true })
@IsOptional()
description?: string;
@IsNumber()
@Field({ nullable: true })
@Min(1)
@Max(900)
@IsOptional()
timeoutSeconds?: number;
@Field(() => graphqlTypeJson)
@IsObject()
code: Sources;
@IsString()
@Field({ nullable: true })
@IsOptional()
handlerName?: string;
@IsString()
@Field({ nullable: true })
@IsOptional()
sourceHandlerPath?: string;
@Field(() => graphqlTypeJson, { nullable: true })
@IsObject()
@IsOptional()
toolInputSchema?: object;
@IsBoolean()
@Field({ nullable: true })
@IsOptional()
isTool?: boolean;
}
@InputType()
export class UpdateLogicFunctionInput {
@Field(() => UUIDScalarType, {
description: 'Id of the logic function to update',
})
@IsNotEmpty()
@IsUUID()
id: string;
@Type(() => UpdateLogicFunctionInputUpdates)
@ValidateNested()
@Field(() => UpdateLogicFunctionInputUpdates, {
description: 'The logic function updates',
})
update: UpdateLogicFunctionInputUpdates;
}