Deprecate object metadata maps in favor of flat entities (#16080)

## Context
Deprecating the old objectMetadataMap type in favour of split flat
entities to match with our new caching.
In the long run, trying to achieve:
- Better performance through caching
- Consistent data access patterns across the codebase
- Reduced database queries

Now that everything is based on flat entities, which are cached, we can
finish the refactoring of workspace context cache which should already
improve performances.
Then the last step will be to consume that new cache in the new global
datasource to get rid of the many workspace datasources stored in the
server
This commit is contained in:
Weiko
2025-11-27 13:43:34 +01:00
committed by GitHub
parent 978c0acb90
commit 1607aebcc6
281 changed files with 6510 additions and 6627 deletions
@@ -4,10 +4,16 @@ import { AuthModule } from 'src/engine/core-modules/auth/auth.module';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { OpenApiController } from 'src/engine/core-modules/open-api/open-api.controller';
import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
@Module({
imports: [ObjectMetadataModule, AuthModule, FeatureFlagModule],
imports: [
ObjectMetadataModule,
AuthModule,
FeatureFlagModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
],
controllers: [OpenApiController],
providers: [OpenApiService],
})
@@ -4,6 +4,7 @@ import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
describe('OpenApiService', () => {
@@ -29,6 +30,12 @@ describe('OpenApiService', () => {
provide: FeatureFlagService,
useValue: {},
},
{
provide: WorkspaceManyOrAllFlatEntityMapsCacheService,
useValue: {
getOrRecomputeManyOrAllFlatEntityMaps: jest.fn(),
},
},
],
}).compile();
@@ -45,10 +45,9 @@ import {
getUpdateOneResponse200,
} from 'src/engine/core-modules/open-api/utils/responses.utils';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
import { shouldExcludeFromWorkspaceApi } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/should-exclude-from-workspace-api.util';
import { getServerUrl } from 'src/utils/get-server-url';
@@ -58,7 +57,7 @@ export class OpenApiService {
constructor(
private readonly accessTokenService: AccessTokenService,
private readonly twentyConfigService: TwentyConfigService,
private readonly objectMetadataService: ObjectMetadataServiceV2,
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
private readonly featureFlagService: FeatureFlagService,
) {}
@@ -75,15 +74,28 @@ export class OpenApiService {
}
}
private async getObjectMetadataItems(workspace: WorkspaceEntity) {
return await this.objectMetadataService.findManyWithinWorkspace(
workspace.id,
{
order: {
namePlural: 'ASC',
private async getFlatObjectMetadataArray(workspaceId: string) {
const { flatObjectMetadataMaps, flatFieldMetadataMaps } =
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
{
workspaceId,
flatMapsKeys: ['flatObjectMetadataMaps', 'flatFieldMetadataMaps'],
},
},
);
const flatObjectMetadataArray = Object.values(
flatObjectMetadataMaps.byId,
).filter(isDefined);
flatObjectMetadataArray.sort((a, b) =>
a.namePlural.localeCompare(b.namePlural),
);
return {
flatObjectMetadataArray,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
};
}
async generateCoreSchema(request: Request): Promise<OpenAPIV3_1.Document> {
@@ -105,33 +117,65 @@ export class OpenApiService {
return schema;
}
const objectMetadataItems = await this.getObjectMetadataItems(workspace);
const {
flatObjectMetadataArray,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
} = await this.getFlatObjectMetadataArray(workspace.id);
if (!objectMetadataItems.length) {
if (!flatObjectMetadataArray.length) {
return schema;
}
const workspaceFeatureFlagsMap =
await this.featureFlagService.getWorkspaceFeatureFlagsMap(workspace.id);
const filteredObjectMetadataItems = objectMetadataItems.filter((item) => {
return !shouldExcludeFromWorkspaceApi(
item,
standardObjectMetadataDefinitions,
workspaceFeatureFlagsMap,
);
});
const filteredObjectMetadataItems = flatObjectMetadataArray.filter(
(item) => {
return !shouldExcludeFromWorkspaceApi(
item,
standardObjectMetadataDefinitions,
workspaceFeatureFlagsMap,
);
},
);
schema.paths = filteredObjectMetadataItems.reduce((paths, item) => {
paths[`/${item.namePlural}`] = computeManyResultPath(item);
paths[`/batch/${item.namePlural}`] = computeBatchPath(item);
paths[`/${item.namePlural}/{id}`] = computeSingleResultPath(item);
paths[`/${item.namePlural}/duplicates`] =
computeDuplicatesResultPath(item);
paths[`/restore/${item.namePlural}/{id}`] =
computeRestoreOneResultPath(item);
paths[`/restore/${item.namePlural}`] = computeRestoreManyResultPath(item);
paths[`/${item.namePlural}/merge`] = computeMergeManyResultPath(item);
paths[`/${item.namePlural}`] = computeManyResultPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[`/batch/${item.namePlural}`] = computeBatchPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[`/${item.namePlural}/{id}`] = computeSingleResultPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[`/${item.namePlural}/duplicates`] = computeDuplicatesResultPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[`/restore/${item.namePlural}/{id}`] = computeRestoreOneResultPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[`/restore/${item.namePlural}`] = computeRestoreManyResultPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[`/${item.namePlural}/merge`] = computeMergeManyResultPath(
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
return paths;
}, schema.paths as OpenAPIV3_1.PathsObject);
@@ -143,19 +187,34 @@ export class OpenApiService {
DatabaseEventAction.CREATED,
item.nameSingular,
)
] = computeWebhooks(DatabaseEventAction.CREATED, item);
] = computeWebhooks(
DatabaseEventAction.CREATED,
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[
this.createWebhookEventName(
DatabaseEventAction.UPDATED,
item.nameSingular,
)
] = computeWebhooks(DatabaseEventAction.UPDATED, item);
] = computeWebhooks(
DatabaseEventAction.UPDATED,
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
paths[
this.createWebhookEventName(
DatabaseEventAction.DELETED,
item.nameSingular,
)
] = computeWebhooks(DatabaseEventAction.DELETED, item);
] = computeWebhooks(
DatabaseEventAction.DELETED,
item,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
);
return paths;
},
@@ -167,7 +226,11 @@ export class OpenApiService {
schema.components = {
...schema.components, // components.securitySchemes is defined in base Schema
schemas: computeSchemaComponents(filteredObjectMetadataItems),
schemas: computeSchemaComponents(
filteredObjectMetadataItems,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
),
parameters: computeParameterComponents(),
responses: {
'400': get400ErrorResponses(),
@@ -347,7 +410,7 @@ export class OpenApiService {
metadata.map((item) => ({
nameSingular: item.nameSingular,
namePlural: item.namePlural,
})) as ObjectMetadataEntity[],
})) as FlatObjectMetadata[],
);
return schema;
@@ -5,15 +5,48 @@ import { FieldMetadataType, NumberDataType } from 'twenty-shared/types';
import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock';
import { computeSchemaComponents } from 'src/engine/core-modules/open-api/utils/components.utils';
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
describe('computeSchemaComponents', () => {
faker.seed(1);
it('should compute schema components', () => {
const flatObjectMetadata: FlatObjectMetadata = {
...objectMetadataItemMock,
universalIdentifier: 'objectName',
fieldMetadataIds: objectMetadataItemMock.fields.map((f) => f.id),
} as any;
const flatFieldMetadataMaps = {
byId: Object.fromEntries(
objectMetadataItemMock.fields.map((f) => [f.id, f as any]),
),
idByUniversalIdentifier: {},
universalIdentifiersByApplicationId: {},
};
const relationTargetObjectMetadata: FlatObjectMetadata = {
id: 'relationTargetObjectId',
nameSingular: 'relationTargetObject',
namePlural: 'relationTargetObjects',
universalIdentifier: 'relationTargetObject',
fieldMetadataIds: [],
} as any;
const flatObjectMetadataMaps = {
byId: {
[flatObjectMetadata.id]: flatObjectMetadata,
[relationTargetObjectMetadata.id]: relationTargetObjectMetadata,
},
idByUniversalIdentifier: {},
universalIdentifiersByApplicationId: {},
};
expect(
computeSchemaComponents([
objectMetadataItemMock,
] as ObjectMetadataEntity[]),
computeSchemaComponents(
[flatObjectMetadata],
flatObjectMetadataMaps,
flatFieldMetadataMaps,
),
).toMatchInlineSnapshot(`
{
"ObjectName": {
@@ -819,17 +852,37 @@ describe('computeSchemaComponents', () => {
];
it.each(testsCases)('$title', ({ context: field }) => {
const flatObjectMetadata: FlatObjectMetadata = {
targetTableName: 'testingObject',
id: 'mockObjectId',
nameSingular: 'objectName',
namePlural: 'objectsName',
universalIdentifier: 'objectName',
fieldMetadataIds: [field.id],
} as any;
const flatFieldMetadataMaps = {
byId: {
[field.id]: field as any,
},
idByUniversalIdentifier: {},
universalIdentifiersByApplicationId: {},
};
const flatObjectMetadataMaps = {
byId: {
[flatObjectMetadata.id]: flatObjectMetadata,
},
idByUniversalIdentifier: {},
universalIdentifiersByApplicationId: {},
};
expect(
computeSchemaComponents([
{
targetTableName: 'testingObject',
id: 'mockObjectId',
nameSingular: 'objectName',
namePlural: 'objectsName',
//@ts-expect-error Passing partial FieldMetadataEntity array
fields: [field],
},
]),
computeSchemaComponents(
[flatObjectMetadata],
flatObjectMetadataMaps,
flatFieldMetadataMaps,
),
).toMatchSnapshot();
});
});
@@ -17,6 +17,10 @@ import {
computeStartingAfterParameters,
computeUpsertParameters,
} from 'src/engine/core-modules/open-api/utils/parameters.utils';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { convertObjectMetadataToSchemaProperties } from 'src/engine/utils/convert-object-metadata-to-schema-properties.util';
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
@@ -31,12 +35,18 @@ type Properties = {
type OpenApiExample = Record<string, FieldMetadataDefaultValue>;
const getSchemaComponentsExample = (
item: ObjectMetadataEntity,
item: FlatObjectMetadata,
flatFieldMetadatas: FlatFieldMetadata[],
): OpenApiExample => {
return item.fields.reduce((node, field) => {
return flatFieldMetadatas.reduce((node, field) => {
// If field is required
if (!field.isNullable && field.defaultValue === null) {
return { ...node, [field.name]: generateRandomFieldValue({ field }) };
return {
...node,
[field.name]: generateRandomFieldValue({
field,
}),
};
}
switch (field.type) {
@@ -60,7 +70,9 @@ const getSchemaComponentsExample = (
case FieldMetadataType.PHONES: {
return {
...node,
[field.name]: generateRandomFieldValue({ field }),
[field.name]: generateRandomFieldValue({
field,
}),
};
}
@@ -72,9 +84,13 @@ const getSchemaComponentsExample = (
};
const getSchemaComponentsRelationProperties = (
item: ObjectMetadataEntity,
flatFieldMetadatas: FlatFieldMetadata[],
flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
): Properties => {
return item.fields.reduce((node, field) => {
return flatFieldMetadatas.reduce((node, field) => {
if (field.type !== FieldMetadataType.RELATION) {
return node;
}
@@ -82,13 +98,20 @@ const getSchemaComponentsRelationProperties = (
let itemProperty = {} as Property;
if (isFieldMetadataEntityOfType(field, FieldMetadataType.RELATION)) {
const targetObjectMetadata =
flatObjectMetadataMaps.byId[field.relationTargetObjectMetadataId];
if (!targetObjectMetadata) {
return node;
}
if (field.settings?.relationType === RelationType.MANY_TO_ONE) {
itemProperty = {
type: 'object',
oneOf: [
{
$ref: `#/components/schemas/${capitalize(
field.relationTargetObjectMetadata.nameSingular,
targetObjectMetadata.nameSingular,
)}ForResponse`,
},
],
@@ -98,7 +121,7 @@ const getSchemaComponentsRelationProperties = (
type: 'array',
items: {
$ref: `#/components/schemas/${capitalize(
field.relationTargetObjectMetadata.nameSingular,
targetObjectMetadata.nameSingular,
)}ForResponse`,
},
};
@@ -117,8 +140,10 @@ const getSchemaComponentsRelationProperties = (
}, {} as Properties);
};
const getRequiredFields = (item: ObjectMetadataEntity): string[] => {
return item.fields.reduce((required, field) => {
const getRequiredFields = (
flatFieldMetadatas: FlatFieldMetadata[],
): string[] => {
return flatFieldMetadatas.reduce((required, field) => {
if (!field.isNullable && field.defaultValue === null) {
required.push(field.name);
@@ -131,10 +156,17 @@ const getRequiredFields = (item: ObjectMetadataEntity): string[] => {
const computeSchemaComponent = ({
item,
flatFieldMetadatas,
flatObjectMetadataMaps,
forResponse,
forUpdate,
}: {
item: ObjectMetadataEntity;
item: FlatObjectMetadata;
flatFieldMetadatas: FlatFieldMetadata[];
flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'];
forResponse: boolean;
forUpdate: boolean;
}): OpenAPIV3_1.SchemaObject => {
@@ -142,20 +174,31 @@ const computeSchemaComponent = ({
const withRequiredFields = !forResponse && !forUpdate;
// Create a temporary object that looks like ObjectMetadataEntity for the converter
const tempItem = {
...item,
fields: flatFieldMetadatas,
} as unknown as ObjectMetadataEntity;
const result: OpenAPIV3_1.SchemaObject = {
type: 'object',
description: item.description ?? undefined,
properties: convertObjectMetadataToSchemaProperties({
item,
item: tempItem,
forResponse,
}) as Properties,
...(!forResponse ? { example: getSchemaComponentsExample(item) } : {}),
...(!forResponse
? { example: getSchemaComponentsExample(item, flatFieldMetadatas) }
: {}),
};
if (withRelations) {
result.properties = {
...result.properties,
...getSchemaComponentsRelationProperties(item),
...getSchemaComponentsRelationProperties(
flatFieldMetadatas,
flatObjectMetadataMaps,
),
};
}
@@ -163,7 +206,7 @@ const computeSchemaComponent = ({
return result;
}
const requiredFields = getRequiredFields(item);
const requiredFields = getRequiredFields(flatFieldMetadatas);
if (requiredFields?.length) {
result.required = requiredFields;
@@ -173,24 +216,44 @@ const computeSchemaComponent = ({
};
export const computeSchemaComponents = (
objectMetadataItems: ObjectMetadataEntity[],
flatObjectMetadataItems: FlatObjectMetadata[],
flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): Record<string, OpenAPIV3_1.SchemaObject> => {
return objectMetadataItems.reduce(
return flatObjectMetadataItems.reduce(
(schemas, item) => {
const flatFieldMetadatas =
findManyFlatEntityByIdInFlatEntityMapsOrThrow<FlatFieldMetadata>({
flatEntityMaps: flatFieldMetadataMaps,
flatEntityIds: item.fieldMetadataIds,
});
schemas[capitalize(item.nameSingular)] = computeSchemaComponent({
item,
flatFieldMetadatas,
flatObjectMetadataMaps,
forResponse: false,
forUpdate: false,
});
schemas[capitalize(item.nameSingular) + 'ForUpdate'] =
computeSchemaComponent({
item,
flatFieldMetadatas,
flatObjectMetadataMaps,
forResponse: false,
forUpdate: true,
});
schemas[capitalize(item.nameSingular) + 'ForResponse'] =
computeSchemaComponent({
item,
flatFieldMetadatas,
flatObjectMetadataMaps,
forResponse: true,
forUpdate: false,
});
@@ -1,10 +1,10 @@
import { type OpenAPIV3_1 } from 'openapi-types';
import { capitalize } from 'twenty-shared/utils';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
export const computeSchemaTags = (
items: ObjectMetadataEntity[],
items: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>[],
): OpenAPIV3_1.TagObject[] => {
const results = [{ name: 'General', description: 'General requests' }];
@@ -2,11 +2,20 @@ import { type OpenAPIV3_1 } from 'openapi-types';
import { capitalize } from 'twenty-shared/utils';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
export const computeWebhooks = (
type: DatabaseEventAction,
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
const updatedFields = {
type: 'array',
@@ -6,11 +6,12 @@ import { v4 } from 'uuid';
import { type FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface';
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
export const generateRandomFieldValue = ({
field,
}: {
field: FieldMetadataEntity;
field: FieldMetadataEntity | FlatFieldMetadata;
}): FieldMetadataDefaultValue => {
switch (field.type) {
case FieldMetadataType.UUID: {
@@ -23,10 +23,19 @@ import {
getUpdateManyResponse200,
getUpdateOneResponse200,
} from 'src/engine/core-modules/open-api/utils/responses.utils';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
export const computeBatchPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
post: {
@@ -48,7 +57,15 @@ export const computeBatchPath = (
};
export const computeManyResultPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
get: {
@@ -118,7 +135,15 @@ export const computeManyResultPath = (
};
export const computeSingleResultPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
get: {
@@ -189,7 +214,15 @@ export const computeOpenApiPath = (
};
export const computeDuplicatesResultPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
post: {
@@ -209,7 +242,15 @@ export const computeDuplicatesResultPath = (
};
export const computeRestoreOneResultPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
patch: {
@@ -230,7 +271,15 @@ export const computeRestoreOneResultPath = (
};
export const computeRestoreManyResultPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
patch: {
@@ -251,7 +300,15 @@ export const computeRestoreManyResultPath = (
};
export const computeMergeManyResultPath = (
item: ObjectMetadataEntity,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
_flatObjectMetadataMaps: Pick<
AllFlatEntityMaps,
'flatObjectMetadataMaps'
>['flatObjectMetadataMaps'],
_flatFieldMetadataMaps: Pick<
AllFlatEntityMaps,
'flatFieldMetadataMaps'
>['flatFieldMetadataMaps'],
): OpenAPIV3_1.PathItemObject => {
return {
patch: {
@@ -1,9 +1,9 @@
import { capitalize } from 'twenty-shared/utils';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
export const getFindManyResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
fromMetadata = false,
) => {
const schemaRef = `#/components/schemas/${capitalize(
@@ -55,7 +55,7 @@ export const getFindManyResponse200 = (
};
export const getFindOneResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(item.nameSingular)}ForResponse`;
@@ -82,7 +82,7 @@ export const getFindOneResponse200 = (
};
export const getRestoreOneResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(item.nameSingular)}ForResponse`;
@@ -109,7 +109,7 @@ export const getRestoreOneResponse200 = (
};
export const getRestoreManyResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(
item.nameSingular,
@@ -141,7 +141,7 @@ export const getRestoreManyResponse200 = (
};
export const getCreateOneResponse201 = (
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
fromMetadata = false,
) => {
const one = fromMetadata ? 'One' : '';
@@ -173,7 +173,7 @@ export const getCreateOneResponse201 = (
};
export const getCreateManyResponse201 = (
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(
item.nameSingular,
@@ -205,7 +205,7 @@ export const getCreateManyResponse201 = (
};
export const getUpdateOneResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
fromMetadata = false,
) => {
const one = fromMetadata ? 'One' : '';
@@ -234,7 +234,7 @@ export const getUpdateOneResponse200 = (
};
export const getDeleteManyResponse200 = (
item: Pick<ObjectMetadataEntity, 'namePlural'>,
item: Pick<FlatObjectMetadata, 'namePlural'>,
) => {
return {
description: 'Successful operation',
@@ -268,7 +268,7 @@ export const getDeleteManyResponse200 = (
};
export const getUpdateManyResponse200 = (
item: Pick<ObjectMetadataEntity, 'namePlural' | 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'namePlural' | 'nameSingular'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(item.nameSingular)}ForResponse`;
@@ -298,7 +298,7 @@ export const getUpdateManyResponse200 = (
};
export const getDeleteResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
fromMetadata = false,
) => {
const one = fromMetadata ? 'One' : '';
@@ -391,7 +391,7 @@ export const getJsonResponse = () => {
};
export const getFindDuplicatesResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
item: Pick<FlatObjectMetadata, 'nameSingular'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(
item.nameSingular,
@@ -441,7 +441,7 @@ export const getFindDuplicatesResponse200 = (
};
export const getMergeManyResponse200 = (
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
item: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>,
) => {
const schemaRef = `#/components/schemas/${capitalize(
item.nameSingular,