Deprecate FieldMetadataInterface (#13264)

# Introduction

From the moment replaced the FieldMetadataInterface definition to:
```ts
import { FieldMetadataType } from 'twenty-shared/types';

import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';

export type FieldMetadataInterface<
  T extends FieldMetadataType = FieldMetadataType,
> = FieldMetadataEntity<T>;
```
After this PR merge will create a new one removing the type and
replacing it to `FieldMetadataEntity`.
Did not renamed it here to avoid conflicts on naming + type issues fixs
within the same PR

## Field metadata entity RELATION or MORPH
Relations fields cannot be null for those field metadata entity instance
anymore, but are never for the others see
`packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts`
( introduced TypeScript tests )

## Concerns
- TS_VECTOR is the most at risk with the `generatedType` and
`asExpression` removal from interface

## What's next
- `FielMetadataInterface` removal and rename ( see introduction )
- Depcrecating `ObjectMetadataInterface`
- Refactor `FieldMetadataEntity` optional fiels to be nullable only
- TO DIG `never` occurences on settings, defaultValue etc
- Some interfaces will be replaced by the `FlatFieldMetadata` when
deprecating the current sync and comparators tools
This commit is contained in:
Paul Rastoin
2025-07-21 11:30:18 +02:00
committed by GitHub
parent c2a5f95675
commit 47b60bd49f
67 changed files with 1780 additions and 769 deletions
@@ -13,17 +13,27 @@ export class TimelineActivityRepository {
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {}
async upsertOne(
name: string,
properties: Partial<ObjectRecord>,
objectName: string,
recordId: string,
workspaceId: string,
workspaceMemberId?: string,
linkedRecordCachedName?: string,
linkedRecordId?: string,
linkedObjectMetadataId?: string,
) {
async upsertOne({
name,
objectName,
properties,
recordId,
workspaceId,
linkedObjectMetadataId,
linkedRecordCachedName,
linkedRecordId,
workspaceMemberId,
}: {
name: string;
properties: Partial<ObjectRecord>;
objectName: string;
recordId: string;
workspaceId: string;
workspaceMemberId?: string;
linkedRecordCachedName?: string;
linkedRecordId?: string;
linkedObjectMetadataId: string | null;
}) {
const recentTimelineActivity = await this.findRecentTimelineActivity(
name,
objectName,
@@ -58,17 +68,17 @@ export class TimelineActivityRepository {
);
}
return this.insertTimelineActivity(
return this.insertTimelineActivity({
name,
properties,
objectName,
recordId,
workspaceMemberId,
linkedRecordCachedName ?? '',
linkedRecordCachedName: linkedRecordCachedName ?? '',
linkedRecordId,
linkedObjectMetadataId,
workspaceId,
);
});
}
private async findRecentTimelineActivity(
@@ -131,17 +141,27 @@ export class TimelineActivityRepository {
});
}
private async insertTimelineActivity(
name: string,
properties: Partial<ObjectRecord>,
objectName: string,
recordId: string,
workspaceMemberId: string | undefined,
linkedRecordCachedName: string,
linkedRecordId: string | undefined,
linkedObjectMetadataId: string | undefined,
workspaceId: string,
) {
private async insertTimelineActivity({
linkedObjectMetadataId,
linkedRecordCachedName,
linkedRecordId,
name,
objectName,
properties,
recordId,
workspaceId,
workspaceMemberId,
}: {
name: string;
properties: Partial<ObjectRecord>;
objectName: string;
recordId: string;
workspaceMemberId: string | undefined;
linkedRecordCachedName: string;
linkedRecordId: string | undefined;
linkedObjectMetadataId: string | null;
workspaceId: string;
}) {
const timelineActivityTypeORMRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
workspaceId,
@@ -14,7 +14,7 @@ type TimelineActivity = Omit<ObjectRecordNonDestructiveEvent, 'properties'> & {
objectName?: string;
linkedRecordCachedName?: string;
linkedRecordId?: string;
linkedObjectMetadataId?: string;
linkedObjectMetadataId?: string | null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
properties: Record<string, any>; // more relaxed conditions than for internal events
};
@@ -50,17 +50,28 @@ export class TimelineActivityService {
if (!timelineActivities || timelineActivities.length === 0) return;
for (const timelineActivity of timelineActivities) {
await this.timelineActivityRepository.upsertOne(
timelineActivity.name,
timelineActivity.properties,
timelineActivity.objectName ?? event.objectMetadata.nameSingular,
timelineActivity.recordId,
const {
name,
properties,
recordId,
linkedObjectMetadataId,
linkedRecordCachedName,
linkedRecordId,
objectName,
workspaceMemberId,
} = timelineActivity;
await this.timelineActivityRepository.upsertOne({
linkedObjectMetadataId: linkedObjectMetadataId ?? null,
name,
objectName: objectName ?? event.objectMetadata.nameSingular,
properties,
recordId,
workspaceId,
timelineActivity.workspaceMemberId,
timelineActivity.linkedRecordCachedName,
timelineActivity.linkedRecordId,
timelineActivity.linkedObjectMetadataId,
);
linkedRecordCachedName,
linkedRecordId,
workspaceMemberId,
});
}
}