fix: migrate webhook and API key REST endpoints to core schema (#13318)
## Problem
After migrating webhooks and API keys from workspace to core level, REST
API endpoints were still creating entities in workspace schema
(`workspace_*`) instead of core schema, causing webhooks to not fire.
## Solution
- Added dedicated REST controllers for webhooks (`/rest/webhooks`) and
API keys (`/rest/apiKeys`)
- Updated dynamic controller to block workspace-gated entities from
being processed
- Fixed OpenAPI documentation to exclude these endpoints from playground
- Ensured return formats match GraphQL resolvers exactly
## Testing
✅ All endpoints tested with provided auth token - webhooks and API keys
now correctly stored in `core` schema
This commit is contained in:
@ -17,10 +17,9 @@ import {
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
|
||||
import { getResolverName } from 'src/engine/utils/get-resolver-name.util';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
|
||||
import { shouldExcludeFromWorkspaceApi } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/should-exclude-from-workspace-api.util';
|
||||
|
||||
import { CreateManyResolverFactory } from './factories/create-many-resolver.factory';
|
||||
import { CreateOneResolverFactory } from './factories/create-one-resolver.factory';
|
||||
@ -100,27 +99,14 @@ export class WorkspaceResolverFactory {
|
||||
for (const objectMetadata of Object.values(objectMetadataMaps.byId).filter(
|
||||
isDefined,
|
||||
)) {
|
||||
const workspaceEntity = standardObjectMetadataDefinitions.find(
|
||||
(entity) => {
|
||||
const entityMetadata = metadataArgsStorage.filterEntities(entity);
|
||||
|
||||
return entityMetadata?.standardId === objectMetadata.standardId;
|
||||
},
|
||||
);
|
||||
|
||||
if (workspaceEntity) {
|
||||
const entityMetadata =
|
||||
metadataArgsStorage.filterEntities(workspaceEntity);
|
||||
|
||||
if (
|
||||
isGatedAndNotEnabled(
|
||||
entityMetadata?.gate,
|
||||
workspaceFeatureFlagsMap,
|
||||
'graphql',
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
shouldExcludeFromWorkspaceApi(
|
||||
objectMetadata,
|
||||
standardObjectMetadataDefinitions,
|
||||
workspaceFeatureFlagsMap,
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate query resolvers
|
||||
|
||||
@ -21,10 +21,9 @@ import {
|
||||
WorkspaceMetadataCacheExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-metadata-cache/exceptions/workspace-metadata-cache.exception';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
|
||||
import { shouldExcludeFromWorkspaceApi } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/should-exclude-from-workspace-api.util';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceSchemaFactory {
|
||||
@ -86,27 +85,10 @@ export class WorkspaceSchemaFactory {
|
||||
indexes: objectMetadataItem.indexMetadatas,
|
||||
}))
|
||||
.filter((objectMetadata) => {
|
||||
// Find the corresponding workspace entity for this object metadata
|
||||
const workspaceEntity = standardObjectMetadataDefinitions.find(
|
||||
(entity) => {
|
||||
const entityMetadata = metadataArgsStorage.filterEntities(entity);
|
||||
|
||||
return entityMetadata?.standardId === objectMetadata.standardId;
|
||||
},
|
||||
);
|
||||
|
||||
if (!workspaceEntity) {
|
||||
return true; // Include non-workspace entities (custom objects, etc.)
|
||||
}
|
||||
|
||||
const entityMetadata =
|
||||
metadataArgsStorage.filterEntities(workspaceEntity);
|
||||
|
||||
// Filter out entities that are GraphQL-gated and not enabled
|
||||
return !isGatedAndNotEnabled(
|
||||
entityMetadata?.gate,
|
||||
return !shouldExcludeFromWorkspaceApi(
|
||||
objectMetadata,
|
||||
standardObjectMetadataDefinitions,
|
||||
workspaceFeatureFlagsMap,
|
||||
'graphql',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user