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:
nitin
2025-07-23 18:41:53 +05:30
committed by GitHub
parent 05a09d7a73
commit 0e561e4ef4
17 changed files with 302 additions and 68 deletions
@@ -1,6 +1,6 @@
import { Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
export type GateContext = 'database' | 'graphql';
export type GateContext = 'database' | 'workspaceApi';
export const isGatedAndNotEnabled = (
gate: Gate | undefined,
@@ -19,9 +19,9 @@ export const isGatedAndNotEnabled = (
return false; // Not gated for database
}
break;
case 'graphql':
if (gate.excludeFromGraphQL === false) {
return false; // Not gated for GraphQL
case 'workspaceApi':
if (gate.excludeFromWorkspaceApi === false) {
return false; // Not gated for workspace API
}
break;
}
@@ -0,0 +1,23 @@
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
export const shouldExcludeFromWorkspaceApi = (
objectMetadataItem: { standardId?: string | null | undefined },
standardObjectMetadataDefinitions: (typeof BaseWorkspaceEntity)[],
workspaceFeatureFlagsMap: Record<string, boolean>,
): boolean => {
const entityMetadata = standardObjectMetadataDefinitions
.map((entity) => metadataArgsStorage.filterEntities(entity))
.find((meta) => meta?.standardId === objectMetadataItem.standardId);
if (!entityMetadata) {
return false; // Don't exclude non-workspace entities
}
return isGatedAndNotEnabled(
entityMetadata?.gate,
workspaceFeatureFlagsMap,
'workspaceApi',
);
};