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,6 +7,7 @@ import {
} from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
import {
type ToolProvider,
type ToolProviderContext,
@@ -45,6 +46,23 @@ export class DatabaseToolProvider implements ToolProvider {
async generateTools(context: ToolProviderContext): Promise<ToolSet> {
const tools: ToolSet = {};
// Build authContext from available context info
// userWorkspaceId is required for user-based tool generation
if (!context.userWorkspaceId) {
return tools;
}
const authContext: WorkspaceAuthContext = {
user: context.userId ? { id: context.userId } : null,
workspace: {
id: context.workspaceId,
} as WorkspaceAuthContext['workspace'],
workspaceMemberId: undefined,
userWorkspaceId: context.userWorkspaceId,
apiKey: null,
application: null,
} as WorkspaceAuthContext;
const { rolesPermissions } =
await this.workspaceCacheService.getOrRecompute(context.workspaceId, [
'rolesPermissions',
@@ -108,6 +126,7 @@ export class DatabaseToolProvider implements ToolProvider {
},
{
workspaceId: context.workspaceId,
authContext,
rolePermissionConfig: context.rolePermissionConfig,
actorContext: context.actorContext,
},
@@ -59,8 +59,15 @@ export class ToolRegistryService {
async buildToolIndex(
workspaceId: string,
roleId: string,
options?: { userId?: string; userWorkspaceId?: string },
): Promise<ToolIndexEntry[]> {
const context = this.buildContext(workspaceId, roleId);
const context = this.buildContext(
workspaceId,
roleId,
undefined,
options?.userId,
options?.userWorkspaceId,
);
const entries: ToolIndexEntry[] = [];
for (const provider of this.providers) {
@@ -82,10 +89,16 @@ export class ToolRegistryService {
query: string,
workspaceId: string,
roleId: string,
options: ToolSearchOptions = {},
options: ToolSearchOptions & {
userId?: string;
userWorkspaceId?: string;
} = {},
): Promise<ToolIndexEntry[]> {
const { limit = 5, category } = options;
const index = await this.buildToolIndex(workspaceId, roleId);
const { limit = 5, category, userId, userWorkspaceId } = options;
const index = await this.buildToolIndex(workspaceId, roleId, {
userId,
userWorkspaceId,
});
const queryLower = query.toLowerCase();
const queryTerms = queryLower