Remove logic function layer (#17697)
## Remove logic function layer Package.json and yarn.lock are now on the application entity, so the logic function layer is no longer used except as a legacy source for the 1.17 backfill. This PR removes all layer usage outside of that migration and keeps only the entity for backfill. ### Summary - **Kept:** `LogicFunctionLayerEntity` and its table, only used by the 1.17 backfill command to read legacy layer data and backfill application package files. - **Removed:** All other layer logic: CRUD, cache, resolvers, services, DTOs, and frontend types. Logic functions now depend only on the application for package/dependency context. ### Why Dependencies instead of Source for package files Package.json and yarn.lock are the application’s dependency set and are stored under the application in **FileFolder.Dependencies**. The build service and drivers now read them only from Dependencies; nothing is written to Source for these files.
This commit is contained in:
-1
@@ -267,7 +267,6 @@ export const ALL_METADATA_RELATIONS = {
|
||||
manyToOne: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
logicFunctionLayer: null,
|
||||
},
|
||||
oneToMany: {},
|
||||
},
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
|
||||
import { IsString } from 'class-validator';
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
|
||||
@ArgsType()
|
||||
export class CreateLogicFunctionLayerInput {
|
||||
@Field(() => GraphQLJSON, { nullable: false })
|
||||
packageJsonChecksum: string;
|
||||
|
||||
@IsString()
|
||||
@Field(() => String, { nullable: false })
|
||||
yarnLockChecksum: string;
|
||||
|
||||
@Field(() => String)
|
||||
applicationUniversalIdentifier: string;
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
import { Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { IsDateString } from 'class-validator';
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@ObjectType('LogicFunctionLayer')
|
||||
export class LogicFunctionLayerDTO {
|
||||
@IDField(() => UUIDScalarType)
|
||||
id: string;
|
||||
|
||||
@IDField(() => UUIDScalarType, { nullable: true })
|
||||
applicationId?: string;
|
||||
|
||||
@IsDateString()
|
||||
@Field()
|
||||
createdAt: Date;
|
||||
|
||||
@IsDateString()
|
||||
@Field()
|
||||
updatedAt: Date;
|
||||
}
|
||||
-12
@@ -3,13 +3,10 @@ import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
OneToMany,
|
||||
PrimaryGeneratedColumn,
|
||||
Relation,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity('logicFunctionLayer')
|
||||
@@ -32,15 +29,6 @@ export class LogicFunctionLayerEntity extends WorkspaceRelatedEntity {
|
||||
@Column({ type: 'jsonb', nullable: false, default: {} })
|
||||
availablePackages: Record<string, string>;
|
||||
|
||||
@OneToMany(
|
||||
() => LogicFunctionEntity,
|
||||
(logicFunction) => logicFunction.logicFunctionLayer,
|
||||
{
|
||||
onDelete: 'RESTRICT',
|
||||
},
|
||||
)
|
||||
logicFunctions: Relation<LogicFunctionEntity[]>;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+2
-12
@@ -1,20 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { LogicFunctionLayerEntity } from 'src/engine/metadata-modules/logic-function-layer/logic-function-layer.entity';
|
||||
import { LogicFunctionLayerResolver } from 'src/engine/metadata-modules/logic-function-layer/logic-function-layer.resolver';
|
||||
import { WorkspaceLogicFunctionLayerMapCacheService } from 'src/engine/metadata-modules/logic-function-layer/services/workspace-logic-function-layer-map-cache.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([LogicFunctionLayerEntity]),
|
||||
PermissionsModule,
|
||||
],
|
||||
providers: [
|
||||
LogicFunctionLayerResolver,
|
||||
WorkspaceLogicFunctionLayerMapCacheService,
|
||||
],
|
||||
exports: [WorkspaceLogicFunctionLayerMapCacheService],
|
||||
imports: [TypeOrmModule.forFeature([LogicFunctionLayerEntity])],
|
||||
exports: [TypeOrmModule],
|
||||
})
|
||||
export class LogicFunctionLayerModule {}
|
||||
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { CreateLogicFunctionLayerInput } from 'src/engine/metadata-modules/logic-function-layer/dtos/create-logic-function-layer.input';
|
||||
import { LogicFunctionLayerDTO } from 'src/engine/metadata-modules/logic-function-layer/dtos/logic-function-layer.dto';
|
||||
import { LogicFunctionLayerService } from 'src/engine/core-modules/logic-function/logic-function-layer/services/logic-function-layer.service';
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@Resolver()
|
||||
export class LogicFunctionLayerResolver {
|
||||
constructor(
|
||||
private readonly logicFunctionLayerService: LogicFunctionLayerService,
|
||||
) {}
|
||||
|
||||
@Mutation(() => LogicFunctionLayerDTO)
|
||||
@UseGuards(SettingsPermissionGuard(PermissionFlagType.WORKFLOWS))
|
||||
async createOneLogicFunctionLayer(
|
||||
@Args()
|
||||
createLogicFunctionLayerInput: CreateLogicFunctionLayerInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
) {
|
||||
return this.logicFunctionLayerService.create(
|
||||
createLogicFunctionLayerInput,
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { LogicFunctionLayerEntity } from 'src/engine/metadata-modules/logic-function-layer/logic-function-layer.entity';
|
||||
import { type LogicFunctionLayerCacheMaps } from 'src/engine/metadata-modules/logic-function-layer/types/logic-function-layer-cache-maps.type';
|
||||
import { fromLogicFunctionLayerEntityToFlatLogicFunctionLayer } from 'src/engine/metadata-modules/logic-function-layer/utils/from-logic-function-layer-entity-to-flat-logic-function-layer.util';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceCache('logicFunctionLayerMaps')
|
||||
export class WorkspaceLogicFunctionLayerMapCacheService extends WorkspaceCacheProvider<LogicFunctionLayerCacheMaps> {
|
||||
constructor(
|
||||
@InjectRepository(LogicFunctionLayerEntity)
|
||||
private readonly logicFunctionLayerRepository: Repository<LogicFunctionLayerEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(
|
||||
workspaceId: string,
|
||||
): Promise<LogicFunctionLayerCacheMaps> {
|
||||
const logicFunctionLayerEntities =
|
||||
await this.logicFunctionLayerRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
const logicFunctionLayerMaps: LogicFunctionLayerCacheMaps = {
|
||||
byId: {},
|
||||
};
|
||||
|
||||
for (const entity of logicFunctionLayerEntities) {
|
||||
const flatLogicFunctionLayer =
|
||||
fromLogicFunctionLayerEntityToFlatLogicFunctionLayer(entity);
|
||||
|
||||
logicFunctionLayerMaps.byId[flatLogicFunctionLayer.id] =
|
||||
flatLogicFunctionLayer;
|
||||
}
|
||||
|
||||
return logicFunctionLayerMaps;
|
||||
}
|
||||
}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
|
||||
import { type LogicFunctionLayerEntity } from 'src/engine/metadata-modules/logic-function-layer/logic-function-layer.entity';
|
||||
|
||||
export type FlatLogicFunctionLayer = FlatEntityFrom<LogicFunctionLayerEntity>;
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { type FlatLogicFunctionLayer } from 'src/engine/metadata-modules/logic-function-layer/types/flat-logic-function-layer.type';
|
||||
|
||||
export type LogicFunctionLayerCacheMaps = {
|
||||
byId: Partial<Record<string, FlatLogicFunctionLayer>>;
|
||||
};
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
import { type LogicFunctionLayerEntity } from 'src/engine/metadata-modules/logic-function-layer/logic-function-layer.entity';
|
||||
import { type FlatLogicFunctionLayer } from 'src/engine/metadata-modules/logic-function-layer/types/flat-logic-function-layer.type';
|
||||
|
||||
export const fromLogicFunctionLayerEntityToFlatLogicFunctionLayer = (
|
||||
entity: LogicFunctionLayerEntity,
|
||||
): FlatLogicFunctionLayer => ({
|
||||
id: entity.id,
|
||||
packageJson: entity.packageJson,
|
||||
packageJsonChecksum: entity.packageJsonChecksum,
|
||||
yarnLock: entity.yarnLock,
|
||||
yarnLockChecksum: entity.yarnLockChecksum,
|
||||
workspaceId: entity.workspaceId,
|
||||
createdAt: entity.createdAt.toISOString(),
|
||||
updatedAt: entity.updatedAt.toISOString(),
|
||||
logicFunctionIds: entity.logicFunctions?.map((lf) => lf.id) ?? [],
|
||||
availablePackages: entity.availablePackages ?? {},
|
||||
});
|
||||
-3
@@ -38,9 +38,6 @@ export class CreateLogicFunctionInput {
|
||||
@HideField()
|
||||
universalIdentifier?: string;
|
||||
|
||||
@HideField()
|
||||
logicFunctionLayerId?: string;
|
||||
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
|
||||
+1
-17
@@ -6,16 +6,12 @@ import {
|
||||
DeleteDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
Relation,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type';
|
||||
import { LogicFunctionLayerEntity } from 'src/engine/metadata-modules/logic-function-layer/logic-function-layer.entity';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type';
|
||||
|
||||
export type CronTriggerSettings = {
|
||||
pattern: string;
|
||||
@@ -46,7 +42,6 @@ export const DEFAULT_HANDLER_NAME = 'main';
|
||||
|
||||
@Entity('logicFunction')
|
||||
@Index('IDX_LOGIC_FUNCTION_ID_DELETED_AT', ['id', 'deletedAt'])
|
||||
@Index('IDX_LOGIC_FUNCTION_LAYER_ID', ['logicFunctionLayerId'])
|
||||
export class LogicFunctionEntity
|
||||
extends SyncableEntity
|
||||
implements Required<LogicFunctionEntity>
|
||||
@@ -85,17 +80,6 @@ export class LogicFunctionEntity
|
||||
@Column({ nullable: false, default: false })
|
||||
isTool: boolean;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
logicFunctionLayerId: string;
|
||||
|
||||
@ManyToOne(
|
||||
() => LogicFunctionLayerEntity,
|
||||
(logicFunctionLayer) => logicFunctionLayer.logicFunctions,
|
||||
{ nullable: false },
|
||||
)
|
||||
@JoinColumn({ name: 'logicFunctionLayerId' })
|
||||
logicFunctionLayer: Relation<LogicFunctionLayerEntity>;
|
||||
|
||||
@Column({ nullable: true, type: 'jsonb' })
|
||||
cronTriggerSettings: JsonbProperty<CronTriggerSettings> | null;
|
||||
|
||||
|
||||
-2
@@ -12,7 +12,6 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-
|
||||
import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module';
|
||||
import { FileModule } from 'src/engine/core-modules/file/file.module';
|
||||
import { LogicFunctionExecutorModule } from 'src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.module';
|
||||
import { CoreLogicFunctionLayerModule } from 'src/engine/core-modules/logic-function/logic-function-layer/logic-function-layer.module';
|
||||
import { SecretEncryptionModule } from 'src/engine/core-modules/secret-encryption/secret-encryption.module';
|
||||
import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
@@ -40,7 +39,6 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
WorkspaceMigrationModule,
|
||||
LogicFunctionLayerModule,
|
||||
CoreLogicFunctionLayerModule,
|
||||
LogicFunctionExecutorModule,
|
||||
SubscriptionsModule,
|
||||
WorkspaceCacheModule,
|
||||
|
||||
+3
-31
@@ -7,10 +7,9 @@ import { ApplicationService } from 'src/engine/core-modules/application/services
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import { getLogicFunctionBaseFolderPath } from 'src/engine/core-modules/logic-function/logic-function-build/utils/get-logic-function-base-folder-path.util';
|
||||
import { LogicFunctionLayerService } from 'src/engine/core-modules/logic-function/logic-function-layer/services/logic-function-layer.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import type { CreateLogicFunctionInput } from 'src/engine/metadata-modules/logic-function/dtos/create-logic-function.input';
|
||||
import type { UpdateLogicFunctionInput } from 'src/engine/metadata-modules/logic-function/dtos/update-logic-function.input';
|
||||
import {
|
||||
@@ -31,7 +30,6 @@ export class LogicFunctionService {
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly logicFunctionLayerService: LogicFunctionLayerService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
private readonly fileStorageService: FileStorageService,
|
||||
) {}
|
||||
@@ -41,9 +39,7 @@ export class LogicFunctionService {
|
||||
workspaceId,
|
||||
ownerFlatApplication,
|
||||
}: {
|
||||
input: Omit<CreateLogicFunctionInput, 'applicationId'> & {
|
||||
logicFunctionLayerId?: string;
|
||||
};
|
||||
input: Omit<CreateLogicFunctionInput, 'applicationId'>;
|
||||
ownerFlatApplication?: FlatApplication;
|
||||
workspaceId: string;
|
||||
applicationId?: string;
|
||||
@@ -56,32 +52,9 @@ export class LogicFunctionService {
|
||||
)
|
||||
).workspaceCustomFlatApplication;
|
||||
|
||||
let logicFunctionToCreateLayerId = input.logicFunctionLayerId;
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (!isDefined(logicFunctionToCreateLayerId)) {
|
||||
const { id: commonLogicFunctionLayerId } =
|
||||
await this.logicFunctionLayerService.createCommonLayer({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier:
|
||||
workspaceCustomFlatApplication.universalIdentifier,
|
||||
});
|
||||
|
||||
logicFunctionToCreateLayerId = commonLogicFunctionLayerId;
|
||||
}
|
||||
|
||||
const flatLogicFunctionToCreate =
|
||||
fromCreateLogicFunctionInputToFlatLogicFunction({
|
||||
createLogicFunctionInput: {
|
||||
...input,
|
||||
logicFunctionLayerId: logicFunctionToCreateLayerId,
|
||||
},
|
||||
createLogicFunctionInput: input,
|
||||
workspaceId,
|
||||
ownerFlatApplication: resolvedOwnerFlatApplication,
|
||||
});
|
||||
@@ -333,7 +306,6 @@ export class LogicFunctionService {
|
||||
name: existingLogicFunction.name,
|
||||
description: existingLogicFunction.description ?? undefined,
|
||||
timeoutSeconds: existingLogicFunction.timeoutSeconds,
|
||||
logicFunctionLayerId: existingLogicFunction.logicFunctionLayerId,
|
||||
},
|
||||
workspaceId,
|
||||
applicationId: existingLogicFunction.applicationId ?? undefined,
|
||||
|
||||
+1
-4
@@ -16,9 +16,7 @@ import { logicFunctionCreateHash } from 'src/engine/metadata-modules/logic-funct
|
||||
const WORKFLOW_BASE_FOLDER_PREFIX = 'workflow';
|
||||
|
||||
export type FromCreateLogicFunctionInputToFlatLogicFunctionArgs = {
|
||||
createLogicFunctionInput: CreateLogicFunctionInput & {
|
||||
logicFunctionLayerId: string;
|
||||
};
|
||||
createLogicFunctionInput: CreateLogicFunctionInput;
|
||||
workspaceId: string;
|
||||
ownerFlatApplication: FlatApplication;
|
||||
};
|
||||
@@ -61,7 +59,6 @@ export const fromCreateLogicFunctionInputToFlatLogicFunction = ({
|
||||
applicationId: ownerFlatApplication.id,
|
||||
runtime: LogicFunctionRuntime.NODE22,
|
||||
timeoutSeconds: rawCreateLogicFunctionInput.timeoutSeconds ?? 300,
|
||||
logicFunctionLayerId: rawCreateLogicFunctionInput.logicFunctionLayerId,
|
||||
workspaceId,
|
||||
code: rawCreateLogicFunctionInput?.code,
|
||||
checksum: rawCreateLogicFunctionInput?.code
|
||||
|
||||
Reference in New Issue
Block a user