Fix flat entity maps date serialization (#16420)

Changes:
- as we store date in redis as serialized, let's make all flatEntity
dates as string. This requires changing FlatEntity types and making sure
that entity are converted to flatEntity and flatEntity to dtos
This commit is contained in:
Charles Bochet
2025-12-09 16:41:50 +01:00
committed by GitHub
parent 608e5751a9
commit a18203934c
94 changed files with 357 additions and 204 deletions
@@ -78,7 +78,7 @@ export const createStandardIndexFlatMetadata = <
return generateFlatIndexMetadataWithNameOrThrow({
flatIndex: {
createdAt: now,
createdAt: now.toISOString(),
applicationId: twentyStandardApplicationId,
indexType,
indexWhereClause,
@@ -86,17 +86,17 @@ export const createStandardIndexFlatMetadata = <
isUnique,
objectMetadataId,
universalIdentifier: indexDefinition.universalIdentifier,
updatedAt: now,
updatedAt: now.toISOString(),
workspaceId,
id: indexId,
flatIndexFieldMetadatas: flatFieldMetadatas.map<FlatIndexFieldMetadata>(
({ id: fieldMetadataId }, index) => ({
createdAt: now,
createdAt: now.toISOString(),
fieldMetadataId,
id: v4(),
indexMetadataId: indexId,
order: index,
updatedAt: now,
updatedAt: now.toISOString(),
}),
),
},
@@ -81,7 +81,7 @@ export const createStandardObjectFlatMetadata = <
fieldMetadataIds: [],
indexMetadataIds: [],
viewIds: [],
createdAt: now,
updatedAt: now,
createdAt: now.toISOString(),
updatedAt: now.toISOString(),
id: standardFieldMetadataIdByObjectAndFieldName[nameSingular].id,
});
@@ -0,0 +1,5 @@
export type ExtractRecordTypeOrmNonNullableDateProperties<T> = NonNullable<
{
[P in keyof T]: null extends T[P] ? never : T[P] extends Date ? P : never;
}[keyof T]
>;
@@ -0,0 +1,9 @@
export type ExtractRecordTypeOrmNullableDateProperties<T> = NonNullable<
{
[P in keyof T]: null extends T[P]
? NonNullable<T[P]> extends Date
? P
: never
: never;
}[keyof T]
>;
@@ -5,17 +5,17 @@ import {
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
type AddFlatEntityToFlatEntityMapsThroughMutationOrThrowArgs<
T extends FlatEntity,
T extends SyncableFlatEntity,
> = {
flatEntity: T;
flatEntityMapsToMutate: FlatEntityMaps<T>;
};
export const addFlatEntityToFlatEntityMapsThroughMutationOrThrow = <
T extends FlatEntity,
T extends SyncableFlatEntity,
>({
flatEntity,
flatEntityMapsToMutate,
@@ -5,17 +5,17 @@ import {
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
export type DeleteFlatEntityFromFlatEntityMapsThroughMutationOrThrowArgs<
T extends FlatEntity,
T extends SyncableFlatEntity,
> = {
entityToDeleteId: string;
flatEntityMapsToMutate: FlatEntityMaps<T>;
};
export const deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow = <
T extends FlatEntity,
T extends SyncableFlatEntity,
>({
flatEntityMapsToMutate,
entityToDeleteId,
@@ -1,17 +1,17 @@
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
export type ReplaceFlatEntityInFlatEntityMapsThroughMutationOrThrowArgs<
T extends FlatEntity,
T extends SyncableFlatEntity,
> = {
flatEntity: T;
flatEntityMapsToMutate: FlatEntityMaps<T>;
};
export const replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow = <
T extends FlatEntity,
T extends SyncableFlatEntity,
>({
flatEntity,
flatEntityMapsToMutate,
@@ -1,6 +1,6 @@
import { type MessageDescriptor } from '@lingui/core';
import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { type WorkspaceMigrationActionTypeV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-action-common-v2';
export type FlatEntityValidationError<TCode extends string = string> = {
@@ -10,7 +10,7 @@ export type FlatEntityValidationError<TCode extends string = string> = {
value?: unknown;
};
export type FailedFlatEntityValidation<T extends FlatEntity> = {
export type FailedFlatEntityValidation<T extends SyncableFlatEntity> = {
type: WorkspaceMigrationActionTypeV2;
errors: FlatEntityValidationError[];
flatEntityMinimalInformation: Partial<T>;
@@ -35,7 +35,7 @@ export class WorkspaceAgentComparator {
}: WorkspaceAgentComparatorArgs): AgentComparatorResult[] {
const results: AgentComparatorResult[] = [];
const keyFactory = (agent: FlatAgent) => agent.universalIdentifier;
const keyFactory = (agent: FlatAgent) => agent.universalIdentifier ?? '';
const fromAgentMap = transformMetadataForComparison(fromFlatAgents, {
shouldIgnoreProperty: (property) =>
@@ -31,7 +31,7 @@ export class StandardRoleFactory {
...flatRole,
id: existingRole.id,
universalIdentifier: roleDefinition.standardId || existingRole.id,
createdAt: existingRole.createdAt,
createdAt: existingRole.createdAt.toISOString(),
});
} else {
computedRoles.push({
@@ -7,7 +7,8 @@ import type { ApplicationEntity } from 'src/engine/core-modules/application/appl
})
export abstract class SyncableEntity {
@Column({ nullable: true, type: 'uuid' })
universalIdentifier: string | null;
// TODO should not be nullable
universalIdentifier: string;
@Column({ nullable: true, type: 'uuid' })
applicationId: string | null;