refactor: Migrate CRUD services to use Common API (#16869)

This PR migrates the workflow CRUD services to use the Common API
(CommonQueryRunners) instead of directly accessing TwentyORM.

## Changes

- Created CommonApiContextBuilderService to build context for Common API
- Migrated CreateRecordService to use CommonCreateOneQueryRunnerService
- Migrated UpdateRecordService to use CommonUpdateOneQueryRunnerService
- Migrated DeleteRecordService to use CommonDeleteOneQueryRunnerService
- Migrated FindRecordsService to use CommonFindManyQueryRunnerService
- Migrated UpsertRecordService to use Common API with upsert flag
- Removed unused get-selected-columns-from-restricted-fields.util.ts
- Updated module dependencies

## Benefits

- Consistent permission checking via Common API
- Query hooks (before/after execution)
- Automatic input transformation
- Same behavior as REST/GraphQL APIs
- Reduced code duplication
This commit is contained in:
Félix Malfait
2025-12-31 10:24:50 +01:00
committed by GitHub
parent 009e7e05f2
commit f8fa709abf
39 changed files with 567 additions and 821 deletions
@@ -7,7 +7,9 @@ import { type WorkspaceAuthContext } from 'src/engine/api/common/interfaces/work
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { ADMIN_ROLE } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role';
import { type WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
import { type WorkflowExecutionContext } from 'src/modules/workflow/workflow-executor/types/workflow-execution-context.type';
import { WorkflowRunWorkspaceService as WorkflowRunService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service';
@@ -20,6 +22,7 @@ export class WorkflowExecutionContextService {
private readonly userWorkspaceService: UserWorkspaceService,
private readonly userRoleService: UserRoleService,
private readonly applicationService: ApplicationService,
private readonly roleService: RoleService,
) {}
async getExecutionContext(runInfo: {
@@ -93,16 +96,31 @@ export class WorkflowExecutionContextService {
workspaceId,
);
const rolePermissionConfig = isDefined(
application.defaultServerlessFunctionRoleId,
)
? { unionOf: [application.defaultServerlessFunctionRoleId] }
// Use the application's role if set, otherwise fall back to admin role
// In the future we should probably assign the Admin role to the Standard Application
let roleId = application.defaultServerlessFunctionRoleId;
if (!isDefined(roleId)) {
// Fallback: Look up admin role for existing workspaces without defaultServerlessFunctionRoleId
const adminRole = await this.roleService.getRoleByUniversalIdentifier({
universalIdentifier: ADMIN_ROLE.standardId,
workspaceId,
});
roleId = adminRole?.id ?? null;
}
const rolePermissionConfig = isDefined(roleId)
? { unionOf: [roleId] }
: { shouldBypassPermissionChecks: true as const };
const authContext = {
user: null,
apiKey: null,
application,
application: {
...application,
defaultServerlessFunctionRoleId: roleId,
},
workspace,
workspaceMemberId: undefined,
userWorkspaceId: undefined,
@@ -6,6 +6,7 @@ import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user
import { AiAgentExecutionModule } from 'src/engine/metadata-modules/ai/ai-agent-execution/ai-agent-execution.module';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { AiBillingModule } from 'src/engine/metadata-modules/ai/ai-billing/ai-billing.module';
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkflowExecutionContextService } from 'src/modules/workflow/workflow-executor/services/workflow-execution-context.service';
import { WorkflowRunModule } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.module';
@@ -21,6 +22,7 @@ import { AiAgentWorkflowAction } from './ai-agent.workflow-action';
WorkflowRunModule,
UserWorkspaceModule,
UserRoleModule,
RoleModule,
],
providers: [WorkflowExecutionContextService, AiAgentWorkflowAction],
exports: [AiAgentWorkflowAction],
@@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
import { RecordCrudModule } from 'src/engine/core-modules/record-crud/record-crud.module';
import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module';
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
import { WorkflowExecutionContextService } from 'src/modules/workflow/workflow-executor/services/workflow-execution-context.service';
@@ -20,6 +21,7 @@ import { WorkflowRunModule } from 'src/modules/workflow/workflow-runner/workflow
WorkflowRunModule,
UserWorkspaceModule,
UserRoleModule,
RoleModule,
WorkflowCommonModule,
],
providers: [
@@ -24,7 +24,7 @@ import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-module
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type';
import { type WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type';
import {
AutomatedTriggerType,
type WorkflowAutomatedTriggerWorkspaceEntity,