ObjectMetadata and FieldMetadata agnostic workspace migration runner (#17572)

# Introduction
Important note: This PR officially deprecates the `standardId`, about to
drop col and entity property after this has been merged

Important note2: Haven't updated the optimistic tool to also update the
universal identifier aggregators only the ids one, they should not be
consumed in the runner context -> need to improve typing or either the
optimistic tooling

In this PR we're introducing all the devxp allowing future metadata
incremental universal migration -> this has an impact on all existing
metadata actions handler ( explaining its size )
This PR also introduce workspace agnostic create update actions runner
for both field and object metadata in order to battle test the described
above devxp

Noting that these two metadata are the most complex to handle

Notes:
- A workspace migration is now highly bind to a
`applicationUniversalIdentifier`. Though we don't strictly validate
application scope for the moment

## Next
Migrate both object and field builder to universal comparison

## Universal Actions vs Flat Actions Architecture

### Concept

The migration system uses a two-phase action model:

1. **Universal Actions** - Actions defined using `universalIdentifier`
(stable, portable identifiers like `standardId` + `applicationId`)
2. **Flat Actions** - Actions defined using database `entityId` (UUIDs
specific to a workspace)

### Why This Separation?

- **Universal actions are portable**: They can be serialized, stored,
and replayed across different workspaces
- **Flat actions are executable**: They contain the actual database IDs
needed to perform operations
- **Decoupling**: The builder produces universal actions; the runner
transpiles them to flat actions at execution time

### Transpiler Pattern

Each action handler must implement
`transpileUniversalActionToFlatAction()`:

```typescript
@Injectable()
export class CreateFieldActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
  'create',
  'fieldMetadata',
) {
  override async transpileUniversalActionToFlatAction(
    context: WorkspaceMigrationActionRunnerArgs<UniversalCreateFieldAction>,
  ): Promise<FlatCreateFieldAction> {
    // Resolve universal identifiers to database IDs
    const flatObjectMetadata = findFlatEntityByUniversalIdentifierOrThrow({
      flatEntityMaps: allFlatEntityMaps.flatObjectMetadataMaps,
      universalIdentifier: action.objectMetadataUniversalIdentifier,
    });
    
    return {
      type: action.type,
      metadataName: action.metadataName,
      objectMetadataId: flatObjectMetadata.id, // Resolved ID
      flatFieldMetadatas: /* ... transpiled entities ... */,
    };
  }
}
```

### Action Handler Base Class

`BaseWorkspaceMigrationRunnerActionHandlerService<TActionType,
TMetadataName>` provides:

- **`transpileUniversalActionToFlatAction()`** - Abstract method each
handler must implement
- **`transpileUniversalDeleteActionToFlatDeleteAction()`** - Shared
helper for delete actions

## FlatEntityMaps custom properties
Introduced a `TWithCustomMapsProperties` generic parameter to control
whether custom indexing structures are included:

- **`false` (default)**: Returns `FlatEntityMaps<MetadataFlatEntity<T>>`
- used in builder/runner contexts
- **`true`**: Returns the full maps type with custom properties (e.g.,
`byUserWorkspaceIdAndFolderId`) - used in cache contexts

## Create Field Actions Refactor

Refactored create-field actions to support relation field pairs
bundling.

**Problem:** Relation fields (e.g., `Attachment.targetTask` ↔
`Task.attachments`) couldn't resolve each other's IDs during
transpilation because they were in separate actions with independent
`fieldIdByUniversalIdentifier` maps.

**Solution:** 
- Removed `objectMetadataUniversalIdentifier` from
`UniversalCreateFieldAction` and `objectMetadataId` from
`FlatCreateFieldAction` - each field now carries its own
- Runner groups fields by object internally and processes each table
separately
- Split aggregator into two focused utilities:
- `aggregateNonRelationFieldsIntoObjectActions` - merges non-relation
fields into object actions
- `aggregateRelationFieldPairs` - bundles relation pairs with shared
`fieldIdByUniversalIdentifier`
This commit is contained in:
Paul Rastoin
2026-02-02 13:22:38 +01:00
committed by GitHub
parent f0bc9fcb43
commit bd9688421f
235 changed files with 4536 additions and 2739 deletions
@@ -88,7 +88,7 @@ export class DevSeederPermissionsService {
const guestRole = await this.roleService.createGuestRole({
workspaceId,
applicationId: twentyStandardFlatApplication.id,
ownerFlatApplication: twentyStandardFlatApplication,
});
await this.userRoleService.assignRoleToManyUserWorkspace({
@@ -99,7 +99,7 @@ export class DevSeederPermissionsService {
const limitedRole = await this.createLimitedRoleForSeedWorkspace({
workspaceId,
applicationId: twentyStandardFlatApplication.id,
ownerFlatApplication: twentyStandardFlatApplication,
});
await this.userRoleService.assignRoleToManyUserWorkspace({
@@ -130,7 +130,7 @@ export class DevSeederPermissionsService {
const memberRole = await this.roleService.createMemberRole({
workspaceId,
applicationId: twentyStandardFlatApplication.id,
ownerFlatApplication: twentyStandardFlatApplication,
});
await this.coreDataSource
@@ -150,14 +150,14 @@ export class DevSeederPermissionsService {
}
private async createLimitedRoleForSeedWorkspace({
applicationId,
ownerFlatApplication,
workspaceId,
}: {
workspaceId: string;
applicationId: string;
ownerFlatApplication: FlatApplication;
}) {
const customRole = await this.roleService.createRole({
applicationId,
ownerFlatApplication,
workspaceId,
input: {
label: 'Object-restricted',
@@ -123,6 +123,8 @@ export class TwentyStandardApplicationService {
},
workspaceId,
isSystemBuild: true,
applicationUniversalIdentifier:
workspaceCustomFlatApplication.universalIdentifier,
},
);
@@ -194,6 +196,8 @@ export class TwentyStandardApplicationService {
additionalCacheDataMaps: {
featureFlagsMap,
},
applicationUniversalIdentifier:
twentyStandardFlatApplication.universalIdentifier,
},
);
@@ -1,8 +1,8 @@
import {
type FieldMetadataDefaultValue,
type FieldMetadataSettings,
type FieldMetadataComplexOption,
type FieldMetadataDefaultOption,
type FieldMetadataDefaultValue,
type FieldMetadataSettings,
type FieldMetadataType,
} from 'twenty-shared/types';
import { v4 } from 'uuid';
@@ -110,6 +110,6 @@ export const createStandardFieldFlatMetadata = <
kanbanAggregateOperationViewUniversalIdentifiers: [],
calendarViewUniversalIdentifiers: [],
mainGroupByFieldMetadataViewUniversalIdentifiers: [],
universalSettings: null,
universalSettings: settings ?? null,
};
};
@@ -133,6 +133,6 @@ export const createStandardRelationFieldFlatMetadata = <
kanbanAggregateOperationViewUniversalIdentifiers: [],
calendarViewUniversalIdentifiers: [],
mainGroupByFieldMetadataViewUniversalIdentifiers: [],
universalSettings: null,
universalSettings: settings,
};
};
@@ -121,7 +121,7 @@ export class WorkspaceManagerService {
const memberRole = await this.roleService.createMemberRole({
workspaceId,
applicationId: workspaceCustomFlatApplication.id,
ownerFlatApplication: workspaceCustomFlatApplication,
});
await this.workspaceRepository.update(workspaceId, {
@@ -23,6 +23,14 @@ export const workspaceMigrationRunnerExceptionFormatter = (
...(isExecutionFailed && {
action: error.action,
errors: {
...(error.errors?.actionTranspilation && {
actionTranspilation: {
message: error.errors.actionTranspilation.message,
code:
(error.errors.actionTranspilation as { code?: string })?.code ??
'INTERNAL_SERVER_ERROR',
},
}),
...(error.errors?.metadata && {
metadata: {
message: error.errors.metadata.message,
@@ -124,6 +124,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
fromToAllFlatEntityMaps,
dependencyAllFlatEntityMaps,
additionalCacheDataMaps,
applicationUniversalIdentifier,
}: WorkspaceMigrationOrchestratorBuildArgs): Promise<
| WorkspaceMigrationOrchestratorFailedResult
| WorkspaceMigrationOrchestratorSuccessfulResult
@@ -985,6 +986,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
return {
status: 'success',
workspaceMigration: {
applicationUniversalIdentifier,
actions: [
// Object and fields and indexes
...aggregatedOrchestratorActionsReport.index.delete,
@@ -32,6 +32,7 @@ type ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs = {
[P in AllMetadataName]?: FlatEntityToCreateDeleteUpdate<P>;
};
isSystemBuild?: boolean;
applicationUniversalIdentifier: string;
};
@Injectable()
@@ -123,6 +124,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
private async computeFromToAllFlatEntityMapsAndBuildOptions({
allFlatEntityOperationByMetadataName,
workspaceId,
applicationUniversalIdentifier,
}: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise<{
fromToAllFlatEntityMaps: FromToAllFlatEntityMaps;
inferDeletionFromMissingEntities: InferDeletionFromMissingEntities;
@@ -136,6 +138,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
} = await this.computeAllRelatedFlatEntityMaps({
allFlatEntityOperationByMetadataName,
workspaceId,
applicationUniversalIdentifier,
});
const fromToAllFlatEntityMaps: FromToAllFlatEntityMaps = {};
@@ -216,6 +219,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
allFlatEntityOperationByMetadataName: allFlatEntities,
workspaceId,
isSystemBuild = false,
applicationUniversalIdentifier,
}: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise<
WorkspaceMigrationOrchestratorFailedResult | undefined
> {
@@ -227,9 +231,11 @@ export class WorkspaceMigrationValidateBuildAndRunService {
} = await this.computeFromToAllFlatEntityMapsAndBuildOptions({
allFlatEntityOperationByMetadataName: allFlatEntities,
workspaceId,
applicationUniversalIdentifier,
});
return await this.validateBuildAndRunWorkspaceMigrationFromTo({
applicationUniversalIdentifier,
buildOptions: {
isSystemBuild,
inferDeletionFromMissingEntities,
@@ -1,8 +1,7 @@
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
export type AggregateOrchestratorActionsReportArgs = {
orchestratorActionsReport: OrchestratorActionsReport;
flatFieldMetadataMaps?: FlatEntityMaps<FlatFieldMetadata>;
flatFieldMetadataMaps?: MetadataFlatEntityMaps<'fieldMetadata'>;
};
@@ -3,13 +3,13 @@ import { type FromTo } from 'twenty-shared/types';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import {
type MetadataWorkspaceMigrationActionsRecord,
type MetadataUniversalWorkspaceMigrationActionsRecord,
type WorkspaceMigrationActionType,
} from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
import { type WorkspaceMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
export type FromToAllFlatEntityMaps = {
[P in keyof AllFlatEntityMaps]?: FromTo<AllFlatEntityMaps[P]>;
@@ -21,6 +21,7 @@ export type WorkspaceMigrationOrchestratorBuildArgs = {
fromToAllFlatEntityMaps: FromToAllFlatEntityMaps;
dependencyAllFlatEntityMaps?: Partial<AllFlatEntityMaps>;
additionalCacheDataMaps: WorkspaceMigrationBuilderAdditionalCacheDataMaps;
applicationUniversalIdentifier: string;
};
export type OrchestratorFailureReport = {
@@ -31,7 +32,7 @@ export type OrchestratorFailureReport = {
};
export type OrchestratorActionsReport = {
[P in AllMetadataName]: MetadataWorkspaceMigrationActionsRecord<P>;
[P in AllMetadataName]: MetadataUniversalWorkspaceMigrationActionsRecord<P>;
};
export type WorkspaceMigrationOrchestratorFailedResult = {
@@ -1,146 +0,0 @@
import { type Equal, type Expect } from 'twenty-shared/testing';
import { type SerializedRelation } from 'twenty-shared/types';
import { type ContainsSerializedRelation } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/contains-serialized-relation.type';
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
type EmptyObject = {};
// ContainsSerializedRelation checks for SerializedRelation in object properties
// It recurses into nested objects and arrays, but stops at primitives
// Direct property tests
// eslint-disable-next-line unused-imports/no-unused-vars
type DirectPropertyAssertions = [
// Direct SerializedRelation property
Expect<
Equal<ContainsSerializedRelation<{ targetId: SerializedRelation }>, true>
>,
// Nullable SerializedRelation property
Expect<
Equal<
ContainsSerializedRelation<{ targetId: SerializedRelation | null }>,
true
>
>,
// Optional SerializedRelation property
Expect<
Equal<ContainsSerializedRelation<{ targetId?: SerializedRelation }>, true>
>,
// Array of SerializedRelation
Expect<
Equal<ContainsSerializedRelation<{ ids: SerializedRelation[] }>, true>
>,
// Plain properties only - no SerializedRelation
Expect<
Equal<ContainsSerializedRelation<{ name: string; count: number }>, false>
>,
// Empty object
Expect<Equal<ContainsSerializedRelation<EmptyObject>, false>>,
];
// Nested object tests - should recurse
// eslint-disable-next-line unused-imports/no-unused-vars
type NestedObjectAssertions = [
// Nested object with SerializedRelation
Expect<
Equal<
ContainsSerializedRelation<{
nested: { targetId: SerializedRelation };
}>,
true
>
>,
// Deeply nested SerializedRelation
Expect<
Equal<
ContainsSerializedRelation<{
level1: { level2: { level3: { id: SerializedRelation } } };
}>,
true
>
>,
// Nested object without SerializedRelation
Expect<
Equal<
ContainsSerializedRelation<{
nested: { name: string; count: number };
}>,
false
>
>,
];
// Nested array tests - should recurse
// eslint-disable-next-line unused-imports/no-unused-vars
type NestedArrayAssertions = [
// Array of objects with SerializedRelation
Expect<
Equal<
ContainsSerializedRelation<{
items: { targetId: SerializedRelation }[];
}>,
true
>
>,
// 2D array of SerializedRelation
Expect<
Equal<ContainsSerializedRelation<{ matrix: SerializedRelation[][] }>, true>
>,
// Array of plain objects
Expect<
Equal<
ContainsSerializedRelation<{
items: { name: string }[];
}>,
false
>
>,
// 2D array of strings
Expect<Equal<ContainsSerializedRelation<{ matrix: string[][] }>, false>>,
];
// Primitive types - should return false (not objects)
// eslint-disable-next-line unused-imports/no-unused-vars
type PrimitiveAssertions = [
Expect<Equal<ContainsSerializedRelation<string>, false>>,
Expect<Equal<ContainsSerializedRelation<number>, false>>,
Expect<Equal<ContainsSerializedRelation<boolean>, false>>,
Expect<Equal<ContainsSerializedRelation<null>, false>>,
Expect<Equal<ContainsSerializedRelation<undefined>, false>>,
];
// Real-world tests
// eslint-disable-next-line unused-imports/no-unused-vars
type RealWorldAssertions = [
// Settings with SerializedRelation
Expect<
Equal<
ContainsSerializedRelation<{
relationType?: string;
junctionTargetFieldId?: SerializedRelation;
}>,
true
>
>,
// Workflow config with nested SerializedRelation in array
Expect<
Equal<
ContainsSerializedRelation<{
steps: { assigneeId: SerializedRelation; action: string }[];
}>,
true
>
>,
];
@@ -1,24 +0,0 @@
import {
type IsEmptyObject,
type IsNever,
type IsSerializedRelation,
} from 'twenty-shared/types';
type ContainsSerializedRelationInner<T> = T extends unknown
? IsNever<T> extends true
? false
: unknown extends T
? false
: IsSerializedRelation<T> extends true
? true
: T extends readonly (infer U)[]
? ContainsSerializedRelationInner<U>
: T extends object
? IsEmptyObject<T> extends true
? false
: ContainsSerializedRelationInner<T[keyof T]>
: false
: never;
export type ContainsSerializedRelation<T> =
true extends ContainsSerializedRelationInner<T> ? true : false;
@@ -8,7 +8,6 @@ import { type FromMetadataEntityToMetadataName } from 'src/engine/metadata-modul
import { type MetadataManyToOneJoinColumn } from 'src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type';
import { type SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
import { type AllJsonbPropertiesWithSerializedPropertiesForMetadataName } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/constants/all-jsonb-properties-with-serialized-relation-by-metadata-name.constant';
import { type ContainsSerializedRelation } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/contains-serialized-relation.type';
import { type FormatRecordSerializedRelationProperties } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/format-record-serialized-relation-properties.type';
export type UniversalSyncableFlatEntity = Omit<
@@ -33,11 +32,9 @@ export type UniversalFlatEntityExtraProperties<
} & {
[P in AllJsonbPropertiesWithSerializedPropertiesForMetadataName<TMetadataName> &
keyof TEntity &
string as `universal${Capitalize<P>}`]: true extends ContainsSerializedRelation<
NonNullable<TEntity[P]>
>
? FormatRecordSerializedRelationProperties<TEntity[P]>
: null;
string as `universal${Capitalize<P>}`]: FormatRecordSerializedRelationProperties<
TEntity[P]
>;
};
export type UniversalFlatEntityFrom<
@@ -0,0 +1,12 @@
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatObjectMetadata = UniversalFlatEntityFrom<
Omit<ObjectMetadataEntity, 'targetRelationFields' | 'dataSourceId'>,
'objectMetadata'
> & {
// NOTE: below fields are not reflected on the final UniversalFlatEntity either they should we should define a common source
// TODO remove once https://github.com/twentyhq/core-team-issues/issues/2172 has been resolved
labelIdentifierFieldMetadataUniversalIdentifier: string | null;
imageIdentifierFieldMetadataUniversalIdentifier: string | null;
};
@@ -153,6 +153,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect an upd
"updatedFlatEntityMaps": {
"byId": {
"field-id-1": {
"universalIdentifier": "universal-identifier-1",
"updates": [
{
"from": false,
@@ -283,6 +284,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create
"updatedFlatEntityMaps": {
"byId": {
"field-id-1": {
"universalIdentifier": "universal-identifier-1",
"updates": [
{
"from": true,
@@ -0,0 +1,278 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { aggregateNonRelationFieldsIntoObjectActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-non-relation-fields-into-object-actions.util';
import { type UniversalCreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type UniversalCreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
describe('aggregateNonRelationFieldsIntoObjectActions', () => {
it('should merge non-relation fields into matching create-object actions', () => {
const objectUniversalId = 'object-1';
const fieldUniversalId = 'field-1';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: objectUniversalId,
nameSingular: 'testObject',
namePlural: 'testObjects',
}),
universalFlatFieldMetadatas: [],
} satisfies UniversalCreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: fieldUniversalId,
objectMetadataId: 'object-metadata-id',
objectMetadataUniversalIdentifier: objectUniversalId,
type: FieldMetadataType.TEXT,
name: 'testField',
}),
],
fieldIdByUniversalIdentifier: {
[fieldUniversalId]: 'generated-field-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateNonRelationFieldsIntoObjectActions({
orchestratorActionsReport: input,
});
// Field should be merged into object action
expect(result.objectMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: fieldUniversalId },
],
fieldIdByUniversalIdentifier: {
[fieldUniversalId]: 'generated-field-id',
},
},
]);
// No remaining field actions
expect(result.fieldMetadata.create).toHaveLength(0);
});
it('should keep relation fields in separate create-field actions', () => {
const objectUniversalId = 'object-1';
const relationFieldUniversalId = 'relation-field-1';
const targetFieldUniversalId = 'target-field-1';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: objectUniversalId,
nameSingular: 'testObject',
namePlural: 'testObjects',
}),
universalFlatFieldMetadatas: [],
} satisfies UniversalCreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: relationFieldUniversalId,
objectMetadataId: 'object-metadata-id',
objectMetadataUniversalIdentifier: objectUniversalId,
type: FieldMetadataType.RELATION,
name: 'relationField',
relationTargetFieldMetadataUniversalIdentifier:
targetFieldUniversalId,
relationTargetObjectMetadataUniversalIdentifier: 'other-object',
}),
],
fieldIdByUniversalIdentifier: {
[relationFieldUniversalId]: 'generated-relation-field-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateNonRelationFieldsIntoObjectActions({
orchestratorActionsReport: input,
});
// Object action should have no fields merged
expect(result.objectMetadata.create).toMatchObject([
{ universalFlatFieldMetadatas: [] },
]);
// Relation field should remain in field actions
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: relationFieldUniversalId },
],
},
]);
});
it('should keep fields for existing objects in separate create-field actions', () => {
const existingObjectUniversalId = 'existing-object';
const fieldUniversalId = 'field-for-existing-object';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [], // No objects being created
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: fieldUniversalId,
objectMetadataId: 'existing-object-metadata-id',
objectMetadataUniversalIdentifier: existingObjectUniversalId,
type: FieldMetadataType.TEXT,
name: 'fieldForExistingObject',
}),
],
fieldIdByUniversalIdentifier: {
[fieldUniversalId]: 'generated-field-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateNonRelationFieldsIntoObjectActions({
orchestratorActionsReport: input,
});
// No object actions
expect(result.objectMetadata.create).toHaveLength(0);
// Field should remain in field actions (no matching object to merge into)
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: fieldUniversalId },
],
},
]);
});
it('should handle mixed relation and non-relation fields', () => {
const objectUniversalId = 'object-1';
const textFieldUniversalId = 'text-field';
const relationFieldUniversalId = 'relation-field';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: objectUniversalId,
nameSingular: 'testObject',
namePlural: 'testObjects',
}),
universalFlatFieldMetadatas: [],
} satisfies UniversalCreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: textFieldUniversalId,
objectMetadataId: 'object-metadata-id',
objectMetadataUniversalIdentifier: objectUniversalId,
type: FieldMetadataType.TEXT,
name: 'textField',
}),
getFlatFieldMetadataMock({
universalIdentifier: relationFieldUniversalId,
objectMetadataId: 'object-metadata-id',
objectMetadataUniversalIdentifier: objectUniversalId,
type: FieldMetadataType.RELATION,
name: 'relationField',
relationTargetFieldMetadataUniversalIdentifier: 'target-field',
relationTargetObjectMetadataUniversalIdentifier: 'other-object',
}),
],
fieldIdByUniversalIdentifier: {
[textFieldUniversalId]: 'text-field-id',
[relationFieldUniversalId]: 'relation-field-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateNonRelationFieldsIntoObjectActions({
orchestratorActionsReport: input,
});
// Text field should be merged into object action
expect(result.objectMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: textFieldUniversalId },
],
},
]);
// Relation field should remain in field actions
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: relationFieldUniversalId },
],
},
]);
});
});
@@ -1,491 +0,0 @@
import {
eachTestingContextFilter,
type EachTestingContext,
} from 'twenty-shared/testing';
import { FieldMetadataType } from 'twenty-shared/types';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util';
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type CreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
type CreateAggregationTestCase = EachTestingContext<{
input: OrchestratorActionsReport;
expected: {
expectCreateFieldActionPerObjectMetadataId: Record<string, number>;
expectCreateObjectActionPerObjectMetadataId: Record<string, number>;
};
}>;
describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions', () => {
const testCases: CreateAggregationTestCase[] = [
{
title:
'should aggregate single object with multiple fields into one object action',
context: {
input: {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: 'object-1',
id: 'object-1',
nameSingular: 'user',
namePlural: 'users',
}),
flatFieldMetadatas: [],
} satisfies CreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-1',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-1',
name: 'firstName',
}),
getFlatFieldMetadataMock({
universalIdentifier: 'field-2',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-2',
name: 'lastName',
}),
],
} satisfies CreateFieldAction,
],
update: [],
delete: [],
},
} satisfies OrchestratorActionsReport,
expected: {
expectCreateFieldActionPerObjectMetadataId: {},
expectCreateObjectActionPerObjectMetadataId: {
'object-1': 1,
},
},
},
},
{
title:
'should keep separate field actions when no matching object action exists',
context: {
input: {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-1',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-1',
name: 'firstName',
}),
],
} satisfies CreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-2',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-2',
name: 'secondName',
}),
],
} satisfies CreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-3',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-3',
name: 'lastName',
}),
],
} satisfies CreateFieldAction,
],
update: [],
delete: [],
},
} satisfies OrchestratorActionsReport,
expected: {
expectCreateFieldActionPerObjectMetadataId: {
'object-1': 1,
},
expectCreateObjectActionPerObjectMetadataId: {},
},
},
},
{
title: 'should handle multiple objects with their respective fields',
context: {
input: {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: 'object-1',
id: 'object-1',
nameSingular: 'user',
namePlural: 'users',
}),
flatFieldMetadatas: [],
} satisfies CreateObjectAction,
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: 'object-2',
id: 'object-2',
nameSingular: 'company',
namePlural: 'companies',
}),
flatFieldMetadatas: [],
} satisfies CreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-1',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-1',
name: 'firstName',
}),
],
} satisfies CreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-2',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-2',
objectMetadataId: 'object-2',
type: FieldMetadataType.TEXT,
id: 'field-2',
name: 'name',
}),
getFlatFieldMetadataMock({
universalIdentifier: 'field-3',
objectMetadataId: 'object-2',
type: FieldMetadataType.TEXT,
id: 'field-3',
name: 'industry',
}),
],
} satisfies CreateFieldAction,
],
update: [],
delete: [],
},
} satisfies OrchestratorActionsReport,
expected: {
expectCreateFieldActionPerObjectMetadataId: {},
expectCreateObjectActionPerObjectMetadataId: {
'object-1': 1,
'object-2': 1,
},
},
},
},
{
title:
'should handle mixed scenario with some fields merged and some kept separate',
context: {
input: {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: 'object-1',
id: 'object-1',
nameSingular: 'user',
namePlural: 'users',
}),
flatFieldMetadatas: [],
} satisfies CreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-1',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-1',
name: 'firstName',
}),
],
} satisfies CreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-2',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-2',
objectMetadataId: 'object-2',
type: FieldMetadataType.TEXT,
id: 'field-2',
name: 'orphanField',
}),
],
} satisfies CreateFieldAction,
],
update: [],
delete: [],
},
} satisfies OrchestratorActionsReport,
expected: {
expectCreateFieldActionPerObjectMetadataId: {
'object-2': 1,
},
expectCreateObjectActionPerObjectMetadataId: {
'object-1': 1,
},
},
},
},
{
title:
'should aggregate multiple field actions for the same object when no create object action exists',
context: {
input: {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-1',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-1',
name: 'firstName',
}),
],
} satisfies CreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-2',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-2',
name: 'lastName',
}),
],
} satisfies CreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-3',
objectMetadataId: 'object-1',
type: FieldMetadataType.TEXT,
id: 'field-3',
name: 'email',
}),
],
} satisfies CreateFieldAction,
],
update: [],
delete: [],
},
} satisfies OrchestratorActionsReport,
expected: {
expectCreateFieldActionPerObjectMetadataId: {
'object-1': 1,
},
expectCreateObjectActionPerObjectMetadataId: {},
},
},
},
{
title: 'should handle empty actions report',
context: {
input: createEmptyOrchestratorActionsReport(),
expected: {
expectCreateFieldActionPerObjectMetadataId: {},
expectCreateObjectActionPerObjectMetadataId: {},
},
},
},
{
title:
'should not merge create_field actions containing relation fields into create_object',
context: {
input: {
...createEmptyOrchestratorActionsReport(),
objectMetadata: {
create: [
{
type: 'create',
metadataName: 'objectMetadata',
flatEntity: getFlatObjectMetadataMock({
universalIdentifier: 'object-1',
id: 'object-1',
nameSingular: 'attachment',
namePlural: 'attachments',
}),
flatFieldMetadatas: [],
} satisfies CreateObjectAction,
],
update: [],
delete: [],
},
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: 'object-1',
flatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: 'field-1',
objectMetadataId: 'object-1',
type: FieldMetadataType.RELATION,
id: 'field-1',
name: 'author',
}),
],
} satisfies CreateFieldAction,
],
update: [],
delete: [],
},
} satisfies OrchestratorActionsReport,
expected: {
expectCreateFieldActionPerObjectMetadataId: {
'object-1': 1,
},
expectCreateObjectActionPerObjectMetadataId: {
'object-1': 1,
},
},
},
},
];
test.each(eachTestingContextFilter(testCases))(
'$title',
({ context: { input, expected } }) => {
const result =
aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions({
orchestratorActionsReport: input,
});
const fieldActions = result.fieldMetadata.create as CreateFieldAction[];
const fieldActionCounts = fieldActions.reduce(
(acc, action) => {
acc[action.objectMetadataId] =
(acc[action.objectMetadataId] || 0) + 1;
return acc;
},
{} as Record<string, number>,
);
const objectActions = result.objectMetadata
.create as CreateObjectAction[];
const objectActionCounts = objectActions.reduce(
(acc, action) => {
acc[action.flatEntity.id] = (acc[action.flatEntity.id] || 0) + 1;
return acc;
},
{} as Record<string, number>,
);
Object.entries(
expected.expectCreateFieldActionPerObjectMetadataId,
).forEach(([objectId, expectedCount]) => {
expect(fieldActionCounts[objectId]).toBe(expectedCount);
});
Object.entries(
expected.expectCreateObjectActionPerObjectMetadataId,
).forEach(([objectId, expectedCount]) => {
expect(objectActionCounts[objectId]).toBe(expectedCount);
});
// Check total counts
const expectedTotalFieldActions = Object.values(
expected.expectCreateFieldActionPerObjectMetadataId,
).reduce((sum, count) => sum + count, 0);
const expectedTotalObjectActions = Object.values(
expected.expectCreateObjectActionPerObjectMetadataId,
).reduce((sum, count) => sum + count, 0);
expect(fieldActions).toHaveLength(expectedTotalFieldActions);
expect(objectActions).toHaveLength(expectedTotalObjectActions);
},
);
});
@@ -8,7 +8,7 @@ import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-m
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/search-field-metadata/constants/search-vector-field.constants';
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
import { aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-deprioritize-search-vector-update-field-actions.util';
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type UniversalUpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions', () => {
it('should move searchVector update actions to the end of the update list', () => {
@@ -20,7 +20,7 @@ describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldA
{
type: 'update',
metadataName: 'fieldMetadata',
entityId: 'search-vector-field-1',
universalIdentifier: 'search-vector-field-1',
updates: [
{
property: 'label',
@@ -28,11 +28,11 @@ describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldA
to: 'Updated Search Vector',
},
],
} satisfies UpdateFieldAction,
} satisfies UniversalUpdateFieldAction,
{
type: 'update',
metadataName: 'fieldMetadata',
entityId: 'regular-field-1',
universalIdentifier: 'regular-field-1',
updates: [
{
property: 'label',
@@ -40,11 +40,11 @@ describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldA
to: 'Updated First Name',
},
],
} satisfies UpdateFieldAction,
} satisfies UniversalUpdateFieldAction,
{
type: 'update',
metadataName: 'fieldMetadata',
entityId: 'regular-field-2',
universalIdentifier: 'regular-field-2',
updates: [
{
property: 'label',
@@ -52,7 +52,7 @@ describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldA
to: 'Updated Last Name',
},
],
} satisfies UpdateFieldAction,
} satisfies UniversalUpdateFieldAction,
],
delete: [],
},
@@ -98,11 +98,13 @@ describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldA
);
const updateFieldActions = result.fieldMetadata
.update as UpdateFieldAction[];
.update as UniversalUpdateFieldAction[];
const actualEntityIds = updateFieldActions.map((action) => action.entityId);
const actualUniversalIdentifiers = updateFieldActions.map(
(action) => action.universalIdentifier,
);
expect(actualEntityIds).toEqual([
expect(actualUniversalIdentifiers).toEqual([
'regular-field-1',
'regular-field-2',
'search-vector-field-1',
@@ -0,0 +1,282 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { aggregateRelationFieldPairs } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-relation-field-pairs.util';
import { type UniversalCreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
describe('aggregateRelationFieldPairs', () => {
it('should bundle relation field pairs into single action with merged fieldIdByUniversalIdentifier', () => {
const attachmentObjectId = 'attachment-object';
const taskObjectId = 'task-object';
const targetTaskFieldId = 'target-task-field';
const attachmentsFieldId = 'attachments-field';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: targetTaskFieldId,
objectMetadataId: 'attachment-object-metadata-id',
objectMetadataUniversalIdentifier: attachmentObjectId,
type: FieldMetadataType.RELATION,
name: 'targetTask',
relationTargetFieldMetadataUniversalIdentifier:
attachmentsFieldId,
relationTargetObjectMetadataUniversalIdentifier: taskObjectId,
}),
],
fieldIdByUniversalIdentifier: {
[targetTaskFieldId]: 'target-task-generated-id',
},
} satisfies UniversalCreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: attachmentsFieldId,
objectMetadataId: 'task-object-metadata-id',
objectMetadataUniversalIdentifier: taskObjectId,
type: FieldMetadataType.RELATION,
name: 'attachments',
relationTargetFieldMetadataUniversalIdentifier:
targetTaskFieldId,
relationTargetObjectMetadataUniversalIdentifier:
attachmentObjectId,
}),
],
fieldIdByUniversalIdentifier: {
[attachmentsFieldId]: 'attachments-generated-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateRelationFieldPairs({
orchestratorActionsReport: input,
});
// Should be bundled into a single action with both fields and merged ID map
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: targetTaskFieldId },
{ universalIdentifier: attachmentsFieldId },
],
fieldIdByUniversalIdentifier: {
[targetTaskFieldId]: 'target-task-generated-id',
[attachmentsFieldId]: 'attachments-generated-id',
},
},
]);
});
it('should keep standalone fields (no relation target) as separate actions', () => {
const fieldUniversalId = 'standalone-field';
const objectUniversalId = 'some-object';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: fieldUniversalId,
objectMetadataId: 'some-object-metadata-id',
objectMetadataUniversalIdentifier: objectUniversalId,
type: FieldMetadataType.TEXT,
name: 'standaloneField',
}),
],
fieldIdByUniversalIdentifier: {
[fieldUniversalId]: 'standalone-field-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateRelationFieldPairs({
orchestratorActionsReport: input,
});
// Should remain as single action
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: fieldUniversalId },
],
},
]);
});
it('should handle relation field with target not being created (existing field)', () => {
const relationFieldId = 'new-relation-field';
const existingTargetFieldId = 'existing-target-field';
const objectUniversalId = 'some-object';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: relationFieldId,
objectMetadataId: 'some-object-metadata-id',
objectMetadataUniversalIdentifier: objectUniversalId,
type: FieldMetadataType.RELATION,
name: 'relationToExisting',
relationTargetFieldMetadataUniversalIdentifier:
existingTargetFieldId,
relationTargetObjectMetadataUniversalIdentifier: 'other-object',
}),
],
fieldIdByUniversalIdentifier: {
[relationFieldId]: 'new-relation-field-id',
},
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateRelationFieldPairs({
orchestratorActionsReport: input,
});
// Should remain as single action (target not being created)
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [{ universalIdentifier: relationFieldId }],
},
]);
});
it('should handle multiple independent relation pairs', () => {
const pair1FieldA = 'pair1-field-a';
const pair1FieldB = 'pair1-field-b';
const pair2FieldA = 'pair2-field-a';
const pair2FieldB = 'pair2-field-b';
const input: OrchestratorActionsReport = {
...createEmptyOrchestratorActionsReport(),
fieldMetadata: {
create: [
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: pair1FieldA,
objectMetadataId: 'object-1-metadata-id',
objectMetadataUniversalIdentifier: 'object-1',
type: FieldMetadataType.RELATION,
name: 'pair1FieldA',
relationTargetFieldMetadataUniversalIdentifier: pair1FieldB,
relationTargetObjectMetadataUniversalIdentifier: 'object-2',
}),
],
fieldIdByUniversalIdentifier: { [pair1FieldA]: 'id-1a' },
} satisfies UniversalCreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: pair1FieldB,
objectMetadataId: 'object-2-metadata-id',
objectMetadataUniversalIdentifier: 'object-2',
type: FieldMetadataType.RELATION,
name: 'pair1FieldB',
relationTargetFieldMetadataUniversalIdentifier: pair1FieldA,
relationTargetObjectMetadataUniversalIdentifier: 'object-1',
}),
],
fieldIdByUniversalIdentifier: { [pair1FieldB]: 'id-1b' },
} satisfies UniversalCreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: pair2FieldA,
objectMetadataId: 'object-3-metadata-id',
objectMetadataUniversalIdentifier: 'object-3',
type: FieldMetadataType.RELATION,
name: 'pair2FieldA',
relationTargetFieldMetadataUniversalIdentifier: pair2FieldB,
relationTargetObjectMetadataUniversalIdentifier: 'object-4',
}),
],
fieldIdByUniversalIdentifier: { [pair2FieldA]: 'id-2a' },
} satisfies UniversalCreateFieldAction,
{
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [
getFlatFieldMetadataMock({
universalIdentifier: pair2FieldB,
objectMetadataId: 'object-4-metadata-id',
objectMetadataUniversalIdentifier: 'object-4',
type: FieldMetadataType.RELATION,
name: 'pair2FieldB',
relationTargetFieldMetadataUniversalIdentifier: pair2FieldA,
relationTargetObjectMetadataUniversalIdentifier: 'object-3',
}),
],
fieldIdByUniversalIdentifier: { [pair2FieldB]: 'id-2b' },
} satisfies UniversalCreateFieldAction,
],
update: [],
delete: [],
},
};
const result = aggregateRelationFieldPairs({
orchestratorActionsReport: input,
});
// Should result in 2 bundled actions (one per pair), each with merged fieldIdByUniversalIdentifier
expect(result.fieldMetadata.create).toMatchObject([
{
universalFlatFieldMetadatas: [
{ universalIdentifier: pair1FieldA },
{ universalIdentifier: pair1FieldB },
],
fieldIdByUniversalIdentifier: {
[pair1FieldA]: 'id-1a',
[pair1FieldB]: 'id-1b',
},
},
{
universalFlatFieldMetadatas: [
{ universalIdentifier: pair2FieldA },
{ universalIdentifier: pair2FieldB },
],
fieldIdByUniversalIdentifier: {
[pair2FieldA]: 'id-2a',
[pair2FieldB]: 'id-2b',
},
},
]);
});
});
@@ -0,0 +1,106 @@
import { isDefined } from 'twenty-shared/utils';
import { isMorphOrRelationUniversalFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { mergeFieldIdByUniversalIdentifier } from 'src/engine/workspace-manager/workspace-migration/utils/merge-field-id-by-universal-identifier.util';
import { type UniversalCreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type UniversalCreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
export const aggregateNonRelationFieldsIntoObjectActions = ({
orchestratorActionsReport,
}: AggregateOrchestratorActionsReportArgs): OrchestratorActionsReport => {
const createObjectActions = orchestratorActionsReport.objectMetadata.create;
const createFieldActions = orchestratorActionsReport.fieldMetadata.create;
const createObjectActionByObjectUniversalIdentifier = new Map<
string,
UniversalCreateObjectAction
>();
for (const createObjectAction of createObjectActions) {
createObjectActionByObjectUniversalIdentifier.set(
createObjectAction.flatEntity.universalIdentifier,
createObjectAction,
);
}
const remainingCreateFieldActions: UniversalCreateFieldAction[] = [];
for (const createFieldAction of createFieldActions) {
const nonRelationFields: UniversalFlatFieldMetadata[] = [];
const relationFields: UniversalFlatFieldMetadata[] = [];
for (const field of createFieldAction.universalFlatFieldMetadatas) {
if (isMorphOrRelationUniversalFlatFieldMetadata(field)) {
relationFields.push(field);
} else {
nonRelationFields.push(field);
}
}
const nonRelationFieldsByObjectUniversalIdentifier = new Map<
string,
UniversalFlatFieldMetadata[]
>();
for (const field of nonRelationFields) {
const objectUniversalId = field.objectMetadataUniversalIdentifier;
const existing =
nonRelationFieldsByObjectUniversalIdentifier.get(objectUniversalId);
if (isDefined(existing)) {
existing.push(field);
} else {
nonRelationFieldsByObjectUniversalIdentifier.set(objectUniversalId, [
field,
]);
}
}
const unmergedNonRelationFields: UniversalFlatFieldMetadata[] = [];
for (const [
objectUniversalId,
fields,
] of nonRelationFieldsByObjectUniversalIdentifier) {
const matchingObjectAction =
createObjectActionByObjectUniversalIdentifier.get(objectUniversalId);
if (isDefined(matchingObjectAction)) {
matchingObjectAction.universalFlatFieldMetadatas.push(...fields);
matchingObjectAction.fieldIdByUniversalIdentifier =
mergeFieldIdByUniversalIdentifier(
matchingObjectAction.fieldIdByUniversalIdentifier,
createFieldAction.fieldIdByUniversalIdentifier,
);
} else {
unmergedNonRelationFields.push(...fields);
}
}
const remainingFields = [...unmergedNonRelationFields, ...relationFields];
if (remainingFields.length > 0) {
remainingCreateFieldActions.push({
...createFieldAction,
universalFlatFieldMetadatas: remainingFields,
});
}
}
return {
...orchestratorActionsReport,
objectMetadata: {
...orchestratorActionsReport.objectMetadata,
create: Array.from(
createObjectActionByObjectUniversalIdentifier.values(),
),
},
fieldMetadata: {
...orchestratorActionsReport.fieldMetadata,
create: remainingCreateFieldActions,
},
};
};
@@ -1,189 +0,0 @@
import { isDefined } from 'twenty-shared/utils';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type CreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
type AggregatedActions = {
createdFieldActionByObjectMetadataId: Record<string, CreateFieldAction>;
createdObjectActionByObjectMetadataId: Record<string, CreateObjectAction>;
};
export const aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions =
({
orchestratorActionsReport,
}: AggregateOrchestratorActionsReportArgs): OrchestratorActionsReport => {
const initialCreatedObjectActionByObjectMetadataId = (
orchestratorActionsReport.objectMetadata.create as CreateObjectAction[]
).reduce(
(acc, createObjectAction) => ({
...acc,
[createObjectAction.flatEntity.id]: createObjectAction,
}),
{} as Record<string, CreateObjectAction>,
);
const initialAccumulator: AggregatedActions = {
createdFieldActionByObjectMetadataId: {},
createdObjectActionByObjectMetadataId:
initialCreatedObjectActionByObjectMetadataId,
};
const {
createdFieldActionByObjectMetadataId,
createdObjectActionByObjectMetadataId,
} = (
orchestratorActionsReport.fieldMetadata.create as CreateFieldAction[]
).reduce<AggregatedActions>(
(
{
createdObjectActionByObjectMetadataId,
createdFieldActionByObjectMetadataId,
},
createFieldAction,
) => {
const existingCreateObjectAction =
createdObjectActionByObjectMetadataId[
createFieldAction.objectMetadataId
];
const existingCreateFieldAction =
createdFieldActionByObjectMetadataId[
createFieldAction.objectMetadataId
];
const initialAccumulator: {
morphOrRelationFlatFieldMetadatas: FlatFieldMetadata[];
otherFlatFieldMetadatas: FlatFieldMetadata[];
} = {
morphOrRelationFlatFieldMetadatas: [],
otherFlatFieldMetadatas: [],
};
const { morphOrRelationFlatFieldMetadatas, otherFlatFieldMetadatas } =
createFieldAction.flatFieldMetadatas.reduce(
(acc, flatFieldMetadata) => {
if (isMorphOrRelationFlatFieldMetadata(flatFieldMetadata)) {
return {
...acc,
morphOrRelationFlatFieldMetadatas: [
...acc.morphOrRelationFlatFieldMetadatas,
flatFieldMetadata,
],
};
}
return {
...acc,
otherFlatFieldMetadatas: [
...acc.otherFlatFieldMetadatas,
flatFieldMetadata,
],
};
},
initialAccumulator,
);
if (isDefined(existingCreateObjectAction)) {
if (isDefined(existingCreateFieldAction)) {
return {
createdObjectActionByObjectMetadataId: {
...createdObjectActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: {
...existingCreateObjectAction,
flatFieldMetadatas: [
...existingCreateObjectAction.flatFieldMetadatas,
...otherFlatFieldMetadatas,
],
},
},
createdFieldActionByObjectMetadataId: {
...createdFieldActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: {
...existingCreateFieldAction,
flatFieldMetadatas: [
...existingCreateFieldAction.flatFieldMetadatas,
...morphOrRelationFlatFieldMetadatas,
],
},
},
};
}
if (morphOrRelationFlatFieldMetadatas.length > 0) {
return {
createdObjectActionByObjectMetadataId: {
...createdObjectActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: {
...existingCreateObjectAction,
flatFieldMetadatas: [
...existingCreateObjectAction.flatFieldMetadatas,
...otherFlatFieldMetadatas,
],
},
},
createdFieldActionByObjectMetadataId: {
...createdFieldActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: {
...createFieldAction,
flatFieldMetadatas: morphOrRelationFlatFieldMetadatas,
},
},
};
}
return {
createdObjectActionByObjectMetadataId: {
...createdObjectActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: {
...existingCreateObjectAction,
flatFieldMetadatas: [
...existingCreateObjectAction.flatFieldMetadatas,
...otherFlatFieldMetadatas,
],
},
},
createdFieldActionByObjectMetadataId,
};
}
if (isDefined(existingCreateFieldAction)) {
return {
createdFieldActionByObjectMetadataId: {
...createdFieldActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: {
...existingCreateFieldAction,
flatFieldMetadatas: [
...existingCreateFieldAction.flatFieldMetadatas,
...createFieldAction.flatFieldMetadatas,
],
},
},
createdObjectActionByObjectMetadataId,
};
}
return {
createdFieldActionByObjectMetadataId: {
...createdFieldActionByObjectMetadataId,
[createFieldAction.objectMetadataId]: createFieldAction,
},
createdObjectActionByObjectMetadataId,
};
},
initialAccumulator,
);
return {
...orchestratorActionsReport,
fieldMetadata: {
...orchestratorActionsReport.fieldMetadata,
create: Object.values(createdFieldActionByObjectMetadataId),
},
objectMetadata: {
...orchestratorActionsReport.objectMetadata,
create: Object.values(createdObjectActionByObjectMetadataId),
},
};
};
@@ -1,10 +1,10 @@
import { assertIsDefinedOrThrow } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/search-field-metadata/constants/search-vector-field.constants';
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type UniversalUpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
export const aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions =
({
@@ -13,22 +13,21 @@ export const aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFie
}: AggregateOrchestratorActionsReportArgs): OrchestratorActionsReport => {
assertIsDefinedOrThrow(flatFieldMetadataMaps);
const updateFieldActions = orchestratorActionsReport.fieldMetadata
.update as UpdateFieldAction[];
const updateFieldActions = orchestratorActionsReport.fieldMetadata.update;
const { searchVectorUpdateFieldActions, otherUpdateFieldActions } =
updateFieldActions.reduce<{
searchVectorUpdateFieldActions: UpdateFieldAction[];
otherUpdateFieldActions: UpdateFieldAction[];
searchVectorUpdateFieldActions: UniversalUpdateFieldAction[];
otherUpdateFieldActions: UniversalUpdateFieldAction[];
}>(
(acc, updateFieldAction) => {
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
const flatFieldMetadata = findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: flatFieldMetadataMaps,
flatEntityId: updateFieldAction.entityId,
universalIdentifier: updateFieldAction.universalIdentifier,
});
const isSearchVectorUpdateFieldAction =
flatFieldMetadata?.name === SEARCH_VECTOR_FIELD.name;
flatFieldMetadata.name === SEARCH_VECTOR_FIELD.name;
if (isSearchVectorUpdateFieldAction) {
return {
@@ -1,13 +1,15 @@
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
import { aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util';
import { aggregateNonRelationFieldsIntoObjectActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-non-relation-fields-into-object-actions.util';
import { aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-deprioritize-search-vector-update-field-actions.util';
import { aggregateRelationFieldPairs } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-relation-field-pairs.util';
export const aggregateOrchestratorActionsReport = ({
orchestratorActionsReport,
flatFieldMetadataMaps,
}: AggregateOrchestratorActionsReportArgs) => {
const aggregatedOrchestratorActionsReport = [
aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions,
aggregateNonRelationFieldsIntoObjectActions,
aggregateRelationFieldPairs,
aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions,
].reduce(
(currentOrchestratorActionsReport, aggregator) =>
@@ -0,0 +1,84 @@
import { isDefined } from 'twenty-shared/utils';
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { mergeFieldIdByUniversalIdentifier } from 'src/engine/workspace-manager/workspace-migration/utils/merge-field-id-by-universal-identifier.util';
import { type UniversalCreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
type FieldWithActionContext = {
field: UniversalFlatFieldMetadata;
fieldIdByUniversalIdentifier: Record<string, string> | undefined;
};
export const aggregateRelationFieldPairs = ({
orchestratorActionsReport,
}: AggregateOrchestratorActionsReportArgs): OrchestratorActionsReport => {
const createFieldActions = orchestratorActionsReport.fieldMetadata.create;
const fieldByUniversalIdentifier = new Map<string, FieldWithActionContext>();
for (const action of createFieldActions) {
for (const field of action.universalFlatFieldMetadatas) {
fieldByUniversalIdentifier.set(field.universalIdentifier, {
field,
fieldIdByUniversalIdentifier: action.fieldIdByUniversalIdentifier,
});
}
}
const processedFieldUniversalIdentifiers = new Set<string>();
const aggregatedCreateFieldActions: UniversalCreateFieldAction[] = [];
for (const [
universalIdentifier,
fieldContext,
] of fieldByUniversalIdentifier) {
if (processedFieldUniversalIdentifiers.has(universalIdentifier)) {
continue;
}
const { field, fieldIdByUniversalIdentifier } = fieldContext;
processedFieldUniversalIdentifiers.add(universalIdentifier);
const fieldsToBundle: UniversalFlatFieldMetadata[] = [field];
let mergedFieldIdMap = fieldIdByUniversalIdentifier;
const targetUniversalIdentifier =
field.relationTargetFieldMetadataUniversalIdentifier;
if (isDefined(targetUniversalIdentifier)) {
const targetFieldContext = fieldByUniversalIdentifier.get(
targetUniversalIdentifier,
);
if (
isDefined(targetFieldContext) &&
!processedFieldUniversalIdentifiers.has(targetUniversalIdentifier)
) {
fieldsToBundle.push(targetFieldContext.field);
processedFieldUniversalIdentifiers.add(targetUniversalIdentifier);
mergedFieldIdMap = mergeFieldIdByUniversalIdentifier(
mergedFieldIdMap,
targetFieldContext.fieldIdByUniversalIdentifier,
);
}
}
aggregatedCreateFieldActions.push({
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: fieldsToBundle,
fieldIdByUniversalIdentifier: mergedFieldIdMap,
});
}
return {
...orchestratorActionsReport,
fieldMetadata: {
...orchestratorActionsReport.fieldMetadata,
create: aggregatedCreateFieldActions,
},
};
};
@@ -22,6 +22,8 @@ export type DeletedCreatedUpdatedMatrix<T extends AllMetadataName> = {
string,
{
updates: FlatEntityPropertiesUpdates<T>;
// TMP remove when maps is universal based
universalIdentifier: string;
}
>;
};
@@ -104,6 +106,7 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
}
initialDispatcher.updatedFlatEntityMaps.byId[toFlatEntity.id] = {
universalIdentifier: fromFlatEntity.universalIdentifier,
updates,
};
}
@@ -1,6 +1,6 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataWorkspaceMigrationActionsRecord } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type MetadataUniversalWorkspaceMigrationActionsRecord } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
export const getMetadataEmptyWorkspaceMigrationActionRecord = <
T extends AllMetadataName,
@@ -11,4 +11,4 @@ export const getMetadataEmptyWorkspaceMigrationActionRecord = <
create: [],
delete: [],
update: [],
}) as MetadataWorkspaceMigrationActionsRecord<T>;
}) as MetadataUniversalWorkspaceMigrationActionsRecord<T>;
@@ -0,0 +1,15 @@
import { isDefined } from 'twenty-shared/utils';
export const mergeFieldIdByUniversalIdentifier = (
existing: Record<string, string> | undefined,
incoming: Record<string, string> | undefined,
): Record<string, string> | undefined => {
if (!isDefined(existing) && !isDefined(incoming)) {
return undefined;
}
return {
...existing,
...incoming,
};
};
@@ -1,9 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateAgentAction = BaseCreateWorkspaceMigrationAction<'agent'>;
export type FlatCreateAgentAction =
BaseFlatCreateWorkspaceMigrationAction<'agent'>;
export type UpdateAgentAction = BaseUpdateWorkspaceMigrationAction<'agent'>;
export type FlatUpdateAgentAction =
BaseFlatUpdateWorkspaceMigrationAction<'agent'>;
export type DeleteAgentAction = BaseDeleteWorkspaceMigrationAction<'agent'>;
export type UniversalDeleteAgentAction =
BaseUniversalDeleteWorkspaceMigrationAction<'agent'>;
export type FlatDeleteAgentAction =
BaseFlatDeleteWorkspaceMigrationAction<'agent'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { FlatUpdateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -84,7 +84,7 @@ export class WorkspaceMigrationAgentActionsBuilderService extends WorkspaceEntit
const { flatEntityId, flatEntityUpdates } = args;
const updateAgentAction: UpdateAgentAction = {
const updateAgentAction: FlatUpdateAgentAction = {
type: 'update',
metadataName: 'agent',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateCommandMenuItemAction =
BaseCreateWorkspaceMigrationAction<'commandMenuItem'>;
export type FlatCreateCommandMenuItemAction =
BaseFlatCreateWorkspaceMigrationAction<'commandMenuItem'>;
export type UpdateCommandMenuItemAction =
BaseUpdateWorkspaceMigrationAction<'commandMenuItem'>;
export type FlatUpdateCommandMenuItemAction =
BaseFlatUpdateWorkspaceMigrationAction<'commandMenuItem'>;
export type DeleteCommandMenuItemAction =
BaseDeleteWorkspaceMigrationAction<'commandMenuItem'>;
export type UniversalDeleteCommandMenuItemAction =
BaseUniversalDeleteWorkspaceMigrationAction<'commandMenuItem'>;
export type FlatDeleteCommandMenuItemAction =
BaseFlatDeleteWorkspaceMigrationAction<'commandMenuItem'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { FlatUpdateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -101,7 +101,7 @@ export class WorkspaceMigrationCommandMenuItemActionsBuilderService extends Work
const { flatEntityId, flatEntityUpdates } = args;
const updateCommandMenuItemAction: UpdateCommandMenuItemAction = {
const updateCommandMenuItemAction: FlatUpdateCommandMenuItemAction = {
type: 'update',
metadataName: 'commandMenuItem',
entityId: flatEntityId,
@@ -1,18 +1,38 @@
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type CreateFieldAction = Omit<
BaseCreateWorkspaceMigrationAction<'fieldMetadata'>,
// Universal action types (always use universal identifiers)
export type UniversalCreateFieldAction = Omit<
BaseUniversalCreateWorkspaceMigrationAction<'fieldMetadata'>,
'flatEntity'
> & {
universalFlatFieldMetadatas: UniversalFlatFieldMetadata[];
// Optional map to provide specific IDs for field creation (for API metadata).
fieldIdByUniversalIdentifier?: Record<string, string>;
};
export type UniversalUpdateFieldAction =
BaseUniversalUpdateWorkspaceMigrationAction<'fieldMetadata'>;
export type UniversalDeleteFieldAction =
BaseUniversalDeleteWorkspaceMigrationAction<'fieldMetadata'>;
// Flat action types (always use entity IDs)
export type FlatCreateFieldAction = Omit<
BaseFlatCreateWorkspaceMigrationAction<'fieldMetadata'>,
'flatEntity'
> & {
objectMetadataId: string;
flatFieldMetadatas: FlatFieldMetadata[];
};
export type UpdateFieldAction =
BaseUpdateWorkspaceMigrationAction<'fieldMetadata'>;
export type FlatUpdateFieldAction =
BaseFlatUpdateWorkspaceMigrationAction<'fieldMetadata'>;
export type DeleteFieldAction =
BaseDeleteWorkspaceMigrationAction<'fieldMetadata'>;
export type FlatDeleteFieldAction =
BaseFlatDeleteWorkspaceMigrationAction<'fieldMetadata'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { UniversalUpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -37,13 +37,20 @@ export class WorkspaceMigrationFieldActionsBuilderService extends WorkspaceEntit
const { flatEntityToValidate: flatFieldMetadataToValidate } = args;
const fieldIdByUniversalIdentifier = flatFieldMetadataToValidate.id
? {
[flatFieldMetadataToValidate.universalIdentifier]:
flatFieldMetadataToValidate.id,
}
: undefined;
return {
status: 'success',
action: {
type: 'create',
metadataName: 'fieldMetadata',
objectMetadataId: flatFieldMetadataToValidate.objectMetadataId,
flatFieldMetadatas: [flatFieldMetadataToValidate],
universalFlatFieldMetadatas: [flatFieldMetadataToValidate],
fieldIdByUniversalIdentifier,
},
};
}
@@ -94,12 +101,12 @@ export class WorkspaceMigrationFieldActionsBuilderService extends WorkspaceEntit
};
}
const { flatEntityId, flatEntityUpdates } = args;
const { universalIdentifier, flatEntityUpdates } = args;
const updateFieldAction: UpdateFieldAction = {
const updateFieldAction: UniversalUpdateFieldAction = {
type: 'update',
metadataName: 'fieldMetadata',
entityId: flatEntityId,
universalIdentifier,
updates: flatEntityUpdates,
};
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateFrontComponentAction =
BaseCreateWorkspaceMigrationAction<'frontComponent'>;
export type FlatCreateFrontComponentAction =
BaseFlatCreateWorkspaceMigrationAction<'frontComponent'>;
export type UpdateFrontComponentAction =
BaseUpdateWorkspaceMigrationAction<'frontComponent'>;
export type FlatUpdateFrontComponentAction =
BaseFlatUpdateWorkspaceMigrationAction<'frontComponent'>;
export type DeleteFrontComponentAction =
BaseDeleteWorkspaceMigrationAction<'frontComponent'>;
export type UniversalDeleteFrontComponentAction =
BaseUniversalDeleteWorkspaceMigrationAction<'frontComponent'>;
export type FlatDeleteFrontComponentAction =
BaseFlatDeleteWorkspaceMigrationAction<'frontComponent'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateFrontComponentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
import { FlatUpdateFrontComponentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -101,7 +101,7 @@ export class WorkspaceMigrationFrontComponentActionsBuilderService extends Works
const { flatEntityId, flatEntityUpdates } = args;
const updateFrontComponentAction: UpdateFrontComponentAction = {
const updateFrontComponentAction: FlatUpdateFrontComponentAction = {
type: 'update',
metadataName: 'frontComponent',
entityId: flatEntityId,
@@ -1,12 +1,18 @@
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateIndexAction = BaseCreateWorkspaceMigrationAction<'index'>;
export type FlatCreateIndexAction =
BaseFlatCreateWorkspaceMigrationAction<'index'>;
export type DeleteIndexAction = BaseDeleteWorkspaceMigrationAction<'index'>;
export type UniversalDeleteIndexAction =
BaseUniversalDeleteWorkspaceMigrationAction<'index'>;
export type UpdateIndexAction = {
export type FlatDeleteIndexAction =
BaseFlatDeleteWorkspaceMigrationAction<'index'>;
export type FlatUpdateIndexAction = {
type: 'update';
metadataName: 'index';
entityId: string;
@@ -1,16 +1,20 @@
import { type Sources } from 'twenty-shared/types';
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateLogicFunctionAction =
BaseCreateWorkspaceMigrationAction<'logicFunction'>;
export type FlatCreateLogicFunctionAction =
BaseFlatCreateWorkspaceMigrationAction<'logicFunction'>;
export type UpdateLogicFunctionAction =
BaseUpdateWorkspaceMigrationAction<'logicFunction'> & {
export type FlatUpdateLogicFunctionAction =
BaseFlatUpdateWorkspaceMigrationAction<'logicFunction'> & {
code?: Sources;
};
export type DeleteLogicFunctionAction =
BaseDeleteWorkspaceMigrationAction<'logicFunction'>;
export type UniversalDeleteLogicFunctionAction =
BaseUniversalDeleteWorkspaceMigrationAction<'logicFunction'>;
export type FlatDeleteLogicFunctionAction =
BaseFlatDeleteWorkspaceMigrationAction<'logicFunction'>;
@@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { UpdateLogicFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/types/workspace-migration-logic-function-action.type';
import { FlatUpdateLogicFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/types/workspace-migration-logic-function-action.type';
import {
ValidateAndBuildArgs,
ValidateAndBuildReturnType,
@@ -141,7 +141,7 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
const { flatEntityId, flatEntityUpdates } = args;
const updateLogicFunctionAction: UpdateLogicFunctionAction = {
const updateLogicFunctionAction: FlatUpdateLogicFunctionAction = {
type: 'update',
metadataName: 'logicFunction',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateNavigationMenuItemAction =
BaseCreateWorkspaceMigrationAction<'navigationMenuItem'>;
export type FlatCreateNavigationMenuItemAction =
BaseFlatCreateWorkspaceMigrationAction<'navigationMenuItem'>;
export type UpdateNavigationMenuItemAction =
BaseUpdateWorkspaceMigrationAction<'navigationMenuItem'>;
export type FlatUpdateNavigationMenuItemAction =
BaseFlatUpdateWorkspaceMigrationAction<'navigationMenuItem'>;
export type DeleteNavigationMenuItemAction =
BaseDeleteWorkspaceMigrationAction<'navigationMenuItem'>;
export type UniversalDeleteNavigationMenuItemAction =
BaseUniversalDeleteWorkspaceMigrationAction<'navigationMenuItem'>;
export type FlatDeleteNavigationMenuItemAction =
BaseFlatDeleteWorkspaceMigrationAction<'navigationMenuItem'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateNavigationMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/types/workspace-migration-navigation-menu-item-action.type';
import { FlatUpdateNavigationMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/types/workspace-migration-navigation-menu-item-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -102,7 +102,7 @@ export class WorkspaceMigrationNavigationMenuItemActionsBuilderService extends W
const { flatEntityId, flatEntityUpdates } = args;
const updateNavigationMenuItemAction: UpdateNavigationMenuItemAction = {
const updateNavigationMenuItemAction: FlatUpdateNavigationMenuItemAction = {
type: 'update',
metadataName: 'navigationMenuItem',
entityId: flatEntityId,
@@ -1,15 +1,34 @@
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type CreateObjectAction =
BaseCreateWorkspaceMigrationAction<'objectMetadata'> & {
// Universal action types (always use universal identifiers)
export type UniversalCreateObjectAction =
BaseUniversalCreateWorkspaceMigrationAction<'objectMetadata'> & {
universalFlatFieldMetadatas: UniversalFlatFieldMetadata[];
// Optional map to provide specific IDs for field creation (for API metadata).
fieldIdByUniversalIdentifier?: Record<string, string>;
};
export type UniversalUpdateObjectAction =
BaseUniversalUpdateWorkspaceMigrationAction<'objectMetadata'>;
export type UniversalDeleteObjectAction =
BaseUniversalDeleteWorkspaceMigrationAction<'objectMetadata'>;
// Flat action types (always use entity IDs)
export type FlatCreateObjectAction =
BaseFlatCreateWorkspaceMigrationAction<'objectMetadata'> & {
flatFieldMetadatas: FlatFieldMetadata[];
};
export type UpdateObjectAction =
BaseUpdateWorkspaceMigrationAction<'objectMetadata'>;
export type FlatUpdateObjectAction =
BaseFlatUpdateWorkspaceMigrationAction<'objectMetadata'>;
export type DeleteObjectAction =
BaseDeleteWorkspaceMigrationAction<'objectMetadata'>;
export type FlatDeleteObjectAction =
BaseFlatDeleteWorkspaceMigrationAction<'objectMetadata'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
import { UniversalUpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -42,8 +42,9 @@ export class WorkspaceMigrationObjectActionsBuilderService extends WorkspaceEnti
action: {
type: 'create',
metadataName: 'objectMetadata',
flatFieldMetadatas: [],
universalFlatFieldMetadatas: [],
flatEntity: flatObjectMetadataToValidate,
id: flatObjectMetadataToValidate.id,
},
};
}
@@ -94,12 +95,12 @@ export class WorkspaceMigrationObjectActionsBuilderService extends WorkspaceEnti
};
}
const { flatEntityId, flatEntityUpdates } = args;
const { universalIdentifier, flatEntityUpdates } = args;
const updateObjectAction: UpdateObjectAction = {
const updateObjectAction: UniversalUpdateObjectAction = {
type: 'update',
metadataName: 'objectMetadata',
entityId: flatEntityId,
universalIdentifier,
updates: flatEntityUpdates,
};
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreatePageLayoutTabAction =
BaseCreateWorkspaceMigrationAction<'pageLayoutTab'>;
export type FlatCreatePageLayoutTabAction =
BaseFlatCreateWorkspaceMigrationAction<'pageLayoutTab'>;
export type UpdatePageLayoutTabAction =
BaseUpdateWorkspaceMigrationAction<'pageLayoutTab'>;
export type FlatUpdatePageLayoutTabAction =
BaseFlatUpdateWorkspaceMigrationAction<'pageLayoutTab'>;
export type DeletePageLayoutTabAction =
BaseDeleteWorkspaceMigrationAction<'pageLayoutTab'>;
export type UniversalDeletePageLayoutTabAction =
BaseUniversalDeleteWorkspaceMigrationAction<'pageLayoutTab'>;
export type FlatDeletePageLayoutTabAction =
BaseFlatDeleteWorkspaceMigrationAction<'pageLayoutTab'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdatePageLayoutTabAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/types/workspace-migration-page-layout-tab-action.type';
import { FlatUpdatePageLayoutTabAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/types/workspace-migration-page-layout-tab-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -101,7 +101,7 @@ export class WorkspaceMigrationPageLayoutTabActionsBuilderService extends Worksp
const { flatEntityId, flatEntityUpdates } = args;
const updatePageLayoutTabAction: UpdatePageLayoutTabAction = {
const updatePageLayoutTabAction: FlatUpdatePageLayoutTabAction = {
type: 'update',
metadataName: 'pageLayoutTab',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreatePageLayoutWidgetAction =
BaseCreateWorkspaceMigrationAction<'pageLayoutWidget'>;
export type FlatCreatePageLayoutWidgetAction =
BaseFlatCreateWorkspaceMigrationAction<'pageLayoutWidget'>;
export type UpdatePageLayoutWidgetAction =
BaseUpdateWorkspaceMigrationAction<'pageLayoutWidget'>;
export type FlatUpdatePageLayoutWidgetAction =
BaseFlatUpdateWorkspaceMigrationAction<'pageLayoutWidget'>;
export type DeletePageLayoutWidgetAction =
BaseDeleteWorkspaceMigrationAction<'pageLayoutWidget'>;
export type UniversalDeletePageLayoutWidgetAction =
BaseUniversalDeleteWorkspaceMigrationAction<'pageLayoutWidget'>;
export type FlatDeletePageLayoutWidgetAction =
BaseFlatDeleteWorkspaceMigrationAction<'pageLayoutWidget'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdatePageLayoutWidgetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/types/workspace-migration-page-layout-widget-action.type';
import { FlatUpdatePageLayoutWidgetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/types/workspace-migration-page-layout-widget-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -103,7 +103,7 @@ export class WorkspaceMigrationPageLayoutWidgetActionsBuilderService extends Wor
const { flatEntityId, flatEntityUpdates } = args;
const updatePageLayoutWidgetAction: UpdatePageLayoutWidgetAction = {
const updatePageLayoutWidgetAction: FlatUpdatePageLayoutWidgetAction = {
type: 'update',
metadataName: 'pageLayoutWidget',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreatePageLayoutAction =
BaseCreateWorkspaceMigrationAction<'pageLayout'>;
export type FlatCreatePageLayoutAction =
BaseFlatCreateWorkspaceMigrationAction<'pageLayout'>;
export type UpdatePageLayoutAction =
BaseUpdateWorkspaceMigrationAction<'pageLayout'>;
export type FlatUpdatePageLayoutAction =
BaseFlatUpdateWorkspaceMigrationAction<'pageLayout'>;
export type DeletePageLayoutAction =
BaseDeleteWorkspaceMigrationAction<'pageLayout'>;
export type UniversalDeletePageLayoutAction =
BaseUniversalDeleteWorkspaceMigrationAction<'pageLayout'>;
export type FlatDeletePageLayoutAction =
BaseFlatDeleteWorkspaceMigrationAction<'pageLayout'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdatePageLayoutAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
import { FlatUpdatePageLayoutAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -97,7 +97,7 @@ export class WorkspaceMigrationPageLayoutActionsBuilderService extends Workspace
const { flatEntityId, flatEntityUpdates } = args;
const updatePageLayoutAction: UpdatePageLayoutAction = {
const updatePageLayoutAction: FlatUpdatePageLayoutAction = {
type: 'update',
metadataName: 'pageLayout',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateRoleTargetAction =
BaseCreateWorkspaceMigrationAction<'roleTarget'>;
export type FlatCreateRoleTargetAction =
BaseFlatCreateWorkspaceMigrationAction<'roleTarget'>;
export type UpdateRoleTargetAction =
BaseUpdateWorkspaceMigrationAction<'roleTarget'>;
export type FlatUpdateRoleTargetAction =
BaseFlatUpdateWorkspaceMigrationAction<'roleTarget'>;
export type DeleteRoleTargetAction =
BaseDeleteWorkspaceMigrationAction<'roleTarget'>;
export type UniversalDeleteRoleTargetAction =
BaseUniversalDeleteWorkspaceMigrationAction<'roleTarget'>;
export type FlatDeleteRoleTargetAction =
BaseFlatDeleteWorkspaceMigrationAction<'roleTarget'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/types/workspace-migration-role-target-action.type';
import { FlatUpdateRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/types/workspace-migration-role-target-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -93,7 +93,7 @@ export class WorkspaceMigrationRoleTargetActionsBuilderService extends Workspace
const { flatEntityId, flatEntityUpdates } = args;
const updateRoleTargetAction: UpdateRoleTargetAction = {
const updateRoleTargetAction: FlatUpdateRoleTargetAction = {
type: 'update',
metadataName: 'roleTarget',
entityId: flatEntityId,
@@ -1,9 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateRoleAction = BaseCreateWorkspaceMigrationAction<'role'>;
export type FlatCreateRoleAction =
BaseFlatCreateWorkspaceMigrationAction<'role'>;
export type UpdateRoleAction = BaseUpdateWorkspaceMigrationAction<'role'>;
export type FlatUpdateRoleAction =
BaseFlatUpdateWorkspaceMigrationAction<'role'>;
export type DeleteRoleAction = BaseDeleteWorkspaceMigrationAction<'role'>;
export type UniversalDeleteRoleAction =
BaseUniversalDeleteWorkspaceMigrationAction<'role'>;
export type FlatDeleteRoleAction =
BaseFlatDeleteWorkspaceMigrationAction<'role'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateRoleAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/types/workspace-migration-role-action.type';
import { FlatUpdateRoleAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/types/workspace-migration-role-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -84,7 +84,7 @@ export class WorkspaceMigrationRoleActionsBuilderService extends WorkspaceEntity
const { flatEntityId, flatEntityUpdates } = args;
const updateRoleAction: UpdateRoleAction = {
const updateRoleAction: FlatUpdateRoleAction = {
type: 'update',
metadataName: 'role',
entityId: flatEntityId,
@@ -1,14 +1,18 @@
/* @license Enterprise */
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateRowLevelPermissionPredicateGroupAction =
BaseCreateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type FlatCreateRowLevelPermissionPredicateGroupAction =
BaseFlatCreateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type UpdateRowLevelPermissionPredicateGroupAction =
BaseUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type FlatUpdateRowLevelPermissionPredicateGroupAction =
BaseFlatUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type DeleteRowLevelPermissionPredicateGroupAction =
BaseDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type UniversalDeleteRowLevelPermissionPredicateGroupAction =
BaseUniversalDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type FlatDeleteRowLevelPermissionPredicateGroupAction =
BaseFlatDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
@@ -4,7 +4,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateRowLevelPermissionPredicateGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/types/workspace-migration-row-level-permission-predicate-group-action.type';
import { FlatUpdateRowLevelPermissionPredicateGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/types/workspace-migration-row-level-permission-predicate-group-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -111,7 +111,7 @@ export class WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderSer
const { flatEntityId, flatEntityUpdates } = args;
const updateAction: UpdateRowLevelPermissionPredicateGroupAction = {
const updateAction: FlatUpdateRowLevelPermissionPredicateGroupAction = {
type: 'update',
metadataName: 'rowLevelPermissionPredicateGroup',
entityId: flatEntityId,
@@ -1,14 +1,18 @@
/* @license Enterprise */
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateRowLevelPermissionPredicateAction =
BaseCreateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type FlatCreateRowLevelPermissionPredicateAction =
BaseFlatCreateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type UpdateRowLevelPermissionPredicateAction =
BaseUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type FlatUpdateRowLevelPermissionPredicateAction =
BaseFlatUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type DeleteRowLevelPermissionPredicateAction =
BaseDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type UniversalDeleteRowLevelPermissionPredicateAction =
BaseUniversalDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type FlatDeleteRowLevelPermissionPredicateAction =
BaseFlatDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
@@ -4,7 +4,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateRowLevelPermissionPredicateAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/types/workspace-migration-row-level-permission-predicate-action.type';
import { FlatUpdateRowLevelPermissionPredicateAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/types/workspace-migration-row-level-permission-predicate-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -111,7 +111,7 @@ export class WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService
const { flatEntityId, flatEntityUpdates } = args;
const updateAction: UpdateRowLevelPermissionPredicateAction = {
const updateAction: FlatUpdateRowLevelPermissionPredicateAction = {
type: 'update',
metadataName: 'rowLevelPermissionPredicate',
entityId: flatEntityId,
@@ -1,9 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateSkillAction = BaseCreateWorkspaceMigrationAction<'skill'>;
export type FlatCreateSkillAction =
BaseFlatCreateWorkspaceMigrationAction<'skill'>;
export type UpdateSkillAction = BaseUpdateWorkspaceMigrationAction<'skill'>;
export type FlatUpdateSkillAction =
BaseFlatUpdateWorkspaceMigrationAction<'skill'>;
export type DeleteSkillAction = BaseDeleteWorkspaceMigrationAction<'skill'>;
export type UniversalDeleteSkillAction =
BaseUniversalDeleteWorkspaceMigrationAction<'skill'>;
export type FlatDeleteSkillAction =
BaseFlatDeleteWorkspaceMigrationAction<'skill'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateSkillAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/types/workspace-migration-skill-action.type';
import { FlatUpdateSkillAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/types/workspace-migration-skill-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -84,7 +84,7 @@ export class WorkspaceMigrationSkillActionsBuilderService extends WorkspaceEntit
const { flatEntityId, flatEntityUpdates } = args;
const updateSkillAction: UpdateSkillAction = {
const updateSkillAction: FlatUpdateSkillAction = {
type: 'update',
metadataName: 'skill',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateViewFieldAction =
BaseCreateWorkspaceMigrationAction<'viewField'>;
export type FlatCreateViewFieldAction =
BaseFlatCreateWorkspaceMigrationAction<'viewField'>;
export type UpdateViewFieldAction =
BaseUpdateWorkspaceMigrationAction<'viewField'>;
export type FlatUpdateViewFieldAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewField'>;
export type DeleteViewFieldAction =
BaseDeleteWorkspaceMigrationAction<'viewField'>;
export type UniversalDeleteViewFieldAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewField'>;
export type FlatDeleteViewFieldAction =
BaseFlatDeleteWorkspaceMigrationAction<'viewField'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateViewFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/types/workspace-migration-view-field-action.type';
import { FlatUpdateViewFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/types/workspace-migration-view-field-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -91,7 +91,7 @@ export class WorkspaceMigrationViewFieldActionsBuilderService extends WorkspaceE
const { flatEntityId, flatEntityUpdates } = args;
const updateViewFieldAction: UpdateViewFieldAction = {
const updateViewFieldAction: FlatUpdateViewFieldAction = {
type: 'update',
metadataName: 'viewField',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateViewFilterGroupAction =
BaseCreateWorkspaceMigrationAction<'viewFilterGroup'>;
export type FlatCreateViewFilterGroupAction =
BaseFlatCreateWorkspaceMigrationAction<'viewFilterGroup'>;
export type UpdateViewFilterGroupAction =
BaseUpdateWorkspaceMigrationAction<'viewFilterGroup'>;
export type FlatUpdateViewFilterGroupAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewFilterGroup'>;
export type DeleteViewFilterGroupAction =
BaseDeleteWorkspaceMigrationAction<'viewFilterGroup'>;
export type UniversalDeleteViewFilterGroupAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewFilterGroup'>;
export type FlatDeleteViewFilterGroupAction =
BaseFlatDeleteWorkspaceMigrationAction<'viewFilterGroup'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { type UpdateViewFilterGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/types/workspace-migration-view-filter-group-action.type';
import { type FlatUpdateViewFilterGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/types/workspace-migration-view-filter-group-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -101,7 +101,7 @@ export class WorkspaceMigrationViewFilterGroupActionsBuilderService extends Work
const { flatEntityId, flatEntityUpdates } = args;
const updateViewFilterGroupAction: UpdateViewFilterGroupAction = {
const updateViewFilterGroupAction: FlatUpdateViewFilterGroupAction = {
type: 'update',
metadataName: 'viewFilterGroup',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateViewFilterAction =
BaseCreateWorkspaceMigrationAction<'viewFilter'>;
export type FlatCreateViewFilterAction =
BaseFlatCreateWorkspaceMigrationAction<'viewFilter'>;
export type UpdateViewFilterAction =
BaseUpdateWorkspaceMigrationAction<'viewFilter'>;
export type FlatUpdateViewFilterAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewFilter'>;
export type DeleteViewFilterAction =
BaseDeleteWorkspaceMigrationAction<'viewFilter'>;
export type UniversalDeleteViewFilterAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewFilter'>;
export type FlatDeleteViewFilterAction =
BaseFlatDeleteWorkspaceMigrationAction<'viewFilter'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateViewFilterAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/types/workspace-migration-view-filter-action.type';
import { FlatUpdateViewFilterAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/types/workspace-migration-view-filter-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -93,7 +93,7 @@ export class WorkspaceMigrationViewFilterActionsBuilderService extends Workspace
const { flatEntityId, flatEntityUpdates } = args;
const updateViewFilterAction: UpdateViewFilterAction = {
const updateViewFilterAction: FlatUpdateViewFilterAction = {
type: 'update',
metadataName: 'viewFilter',
entityId: flatEntityId,
@@ -1,12 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateViewGroupAction =
BaseCreateWorkspaceMigrationAction<'viewGroup'>;
export type FlatCreateViewGroupAction =
BaseFlatCreateWorkspaceMigrationAction<'viewGroup'>;
export type UpdateViewGroupAction =
BaseUpdateWorkspaceMigrationAction<'viewGroup'>;
export type FlatUpdateViewGroupAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewGroup'>;
export type DeleteViewGroupAction =
BaseDeleteWorkspaceMigrationAction<'viewGroup'>;
export type UniversalDeleteViewGroupAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewGroup'>;
export type FlatDeleteViewGroupAction =
BaseFlatDeleteWorkspaceMigrationAction<'viewGroup'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateViewGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/types/workspace-migration-view-group-action.type';
import { FlatUpdateViewGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/types/workspace-migration-view-group-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -93,7 +93,7 @@ export class WorkspaceMigrationViewGroupActionsBuilderService extends WorkspaceE
const { flatEntityId, flatEntityUpdates } = args;
const updateViewGroupAction: UpdateViewGroupAction = {
const updateViewGroupAction: FlatUpdateViewGroupAction = {
type: 'update',
metadataName: 'viewGroup',
entityId: flatEntityId,
@@ -1,9 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateViewAction = BaseCreateWorkspaceMigrationAction<'view'>;
export type FlatCreateViewAction =
BaseFlatCreateWorkspaceMigrationAction<'view'>;
export type UpdateViewAction = BaseUpdateWorkspaceMigrationAction<'view'>;
export type FlatUpdateViewAction =
BaseFlatUpdateWorkspaceMigrationAction<'view'>;
export type DeleteViewAction = BaseDeleteWorkspaceMigrationAction<'view'>;
export type UniversalDeleteViewAction =
BaseUniversalDeleteWorkspaceMigrationAction<'view'>;
export type FlatDeleteViewAction =
BaseFlatDeleteWorkspaceMigrationAction<'view'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateViewAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/types/workspace-migration-view-action.type';
import { FlatUpdateViewAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/types/workspace-migration-view-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -84,7 +84,7 @@ export class WorkspaceMigrationViewActionsBuilderService extends WorkspaceEntity
const { flatEntityId, flatEntityUpdates } = args;
const updateViewAction: UpdateViewAction = {
const updateViewAction: FlatUpdateViewAction = {
type: 'update',
metadataName: 'view',
entityId: flatEntityId,
@@ -1,9 +1,16 @@
import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type';
import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type';
import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
export type CreateWebhookAction = BaseCreateWorkspaceMigrationAction<'webhook'>;
export type FlatCreateWebhookAction =
BaseFlatCreateWorkspaceMigrationAction<'webhook'>;
export type UpdateWebhookAction = BaseUpdateWorkspaceMigrationAction<'webhook'>;
export type FlatUpdateWebhookAction =
BaseFlatUpdateWorkspaceMigrationAction<'webhook'>;
export type DeleteWebhookAction = BaseDeleteWorkspaceMigrationAction<'webhook'>;
export type UniversalDeleteWebhookAction =
BaseUniversalDeleteWorkspaceMigrationAction<'webhook'>;
export type FlatDeleteWebhookAction =
BaseFlatDeleteWorkspaceMigrationAction<'webhook'>;
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UpdateWebhookAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/types/workspace-migration-webhook-action.type';
import { FlatUpdateWebhookAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/types/workspace-migration-webhook-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
@@ -93,7 +93,7 @@ export class WorkspaceMigrationWebhookActionsBuilderService extends WorkspaceEnt
const { flatEntityId, flatEntityUpdates } = args;
const updateWebhookAction: UpdateWebhookAction = {
const updateWebhookAction: FlatUpdateWebhookAction = {
type: 'update',
metadataName: 'webhook',
entityId: flatEntityId,
@@ -241,6 +241,7 @@ export abstract class WorkspaceEntityMigrationBuilderService<
workspaceId,
buildOptions,
additionalCacheDataMaps,
universalIdentifier: flatEntityToUpdate.universalIdentifier,
});
if (validationResult.status === 'fail') {
@@ -3,8 +3,9 @@ import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseCreateWorkspaceMigrationAction<T extends AllMetadataName> = {
flatEntity: MetadataFlatEntity<T>;
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.create;
metadataName: T;
};
export type BaseFlatCreateWorkspaceMigrationAction<T extends AllMetadataName> =
{
flatEntity: MetadataFlatEntity<T>;
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.create;
metadataName: T;
};
@@ -0,0 +1,10 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseFlatDeleteWorkspaceMigrationAction<T extends AllMetadataName> =
{
entityId: string;
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.delete;
metadataName: T;
};
@@ -0,0 +1,12 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseFlatUpdateWorkspaceMigrationAction<T extends AllMetadataName> =
{
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.update;
metadataName: T;
entityId: string;
updates: FlatEntityPropertiesUpdates<T>;
};
@@ -0,0 +1,16 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseUniversalCreateWorkspaceMigrationAction<
T extends AllMetadataName,
> = {
// TODO prastoin rename to universalFlatEntity ?
flatEntity: MetadataUniversalFlatEntity<T>;
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.create;
metadataName: T;
// Optional ID to use when creating the entity (for API metadata).
// If not provided, a new UUID will be generated.
id?: string;
};
@@ -2,7 +2,9 @@ import { type AllMetadataName } from 'twenty-shared/metadata';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseDeleteWorkspaceMigrationAction<T extends AllMetadataName> = {
export type BaseUniversalDeleteWorkspaceMigrationAction<
T extends AllMetadataName,
> = {
universalIdentifier: string;
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.delete;
metadataName: T;
@@ -3,9 +3,11 @@ import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseUpdateWorkspaceMigrationAction<T extends AllMetadataName> = {
export type BaseUniversalUpdateWorkspaceMigrationAction<
T extends AllMetadataName,
> = {
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.update;
metadataName: T;
entityId: string;
universalIdentifier: string;
updates: FlatEntityPropertiesUpdates<T>;
};
@@ -9,4 +9,5 @@ export type FlatEntityUpdateValidationArgs<T extends AllMetadataName> = Omit<
> & {
flatEntityId: string;
flatEntityUpdates: FlatEntityPropertiesUpdates<T>;
universalIdentifier: string;
};
@@ -1,7 +1,7 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import {
type MetadataWorkspaceMigrationAction,
type MetadataUniversalWorkspaceMigrationAction,
type WorkspaceMigrationActionType,
} from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
@@ -12,9 +12,10 @@ export type FlatEntityValidationReturnType<
> =
| {
status: 'success';
action:
| MetadataWorkspaceMigrationAction<TMetadataName, TACtionType>
| MetadataWorkspaceMigrationAction<TMetadataName, TACtionType>[];
action: MetadataUniversalWorkspaceMigrationAction<
TMetadataName,
TACtionType
>;
}
| ({
status: 'fail';
@@ -1,10 +1,10 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataFlatEntityAndRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataWorkspaceMigrationActionsRecord } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type MetadataUniversalWorkspaceMigrationActionsRecord } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
export type SuccessfulFlatEntityValidateAndBuild<T extends AllMetadataName> = {
status: 'success';
actions: MetadataWorkspaceMigrationActionsRecord<T>;
actions: MetadataUniversalWorkspaceMigrationActionsRecord<T>;
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataFlatEntityAndRelatedFlatEntityMaps<T>;
};
@@ -1,14 +1,21 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import {
type MetadataWorkspaceMigrationAction,
type MetadataFlatWorkspaceMigrationAction,
type MetadataUniversalWorkspaceMigrationAction,
type WorkspaceMigrationActionType,
} from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
export type WorkspaceMigrationAction = MetadataWorkspaceMigrationAction<
AllMetadataName,
WorkspaceMigrationActionType
>;
export type AllUniversalWorkspaceMigrationAction<
TActionType extends
WorkspaceMigrationActionType = WorkspaceMigrationActionType,
> = MetadataUniversalWorkspaceMigrationAction<AllMetadataName, TActionType>;
export type AllFlatWorkspaceMigrationAction =
MetadataFlatWorkspaceMigrationAction<
AllMetadataName,
WorkspaceMigrationActionType
>;
export { WorkspaceMigrationActionType };
@@ -1,8 +1,10 @@
import { type WorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-action-common';
import { type AllUniversalWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-action-common';
export type WorkspaceMigration<
TActions extends WorkspaceMigrationAction = WorkspaceMigrationAction,
TActions extends
AllUniversalWorkspaceMigrationAction = AllUniversalWorkspaceMigrationAction,
> = {
actions: TActions[];
workspaceId: string;
applicationUniversalIdentifier: string;
};
@@ -7,7 +7,7 @@ import { isDefined } from 'twenty-shared/utils';
import { AgentExceptionCode } from 'src/engine/metadata-modules/ai/ai-agent/agent.exception';
import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
@@ -99,7 +99,16 @@ export class FlatAgentValidatorService {
return validationResult;
}
if (!buildOptions.isSystemBuild && isStandardMetadata(existingAgent)) {
if (
!buildOptions.isSystemBuild &&
// TODO refactor once agent has been migrated to universal pattern
isDefined(existingAgent.__universal) &&
belongsToTwentyStandardApp({
universalIdentifier: existingAgent.universalIdentifier,
applicationUniversalIdentifier:
existingAgent.__universal.applicationUniversalIdentifier,
})
) {
validationResult.errors.push({
code: AgentExceptionCode.AGENT_IS_STANDARD,
message: t`Cannot delete standard agent`,
@@ -144,7 +153,16 @@ export class FlatAgentValidatorService {
return validationResult;
}
if (!buildOptions.isSystemBuild && isStandardMetadata(fromFlatAgent)) {
if (
!buildOptions.isSystemBuild &&
// TODO refactor once agent has been migrated to universal pattern
isDefined(fromFlatAgent.__universal) &&
belongsToTwentyStandardApp({
universalIdentifier: fromFlatAgent.universalIdentifier,
applicationUniversalIdentifier:
fromFlatAgent.__universal.applicationUniversalIdentifier,
})
) {
validationResult.errors.push({
code: AgentExceptionCode.AGENT_IS_STANDARD,
message: t`Cannot update standard agent`,
@@ -13,7 +13,7 @@ import { isFlatFieldMetadataNameSyncedWithLabel } from 'src/engine/metadata-modu
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
import { validateFlatFieldMetadataNameAvailability } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util';
import { validateFlatFieldMetadataName } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name.util';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
@@ -264,7 +264,7 @@ export class FlatFieldMetadataValidatorService {
);
if (
isStandardMetadata(flatFieldMetadataToDelete) &&
belongsToTwentyStandardApp(flatFieldMetadataToDelete) &&
!relationTargetObjectMetadataHasBeenDeleted &&
!parentObjectMetadataHasBeenDeleted
) {
@@ -4,8 +4,8 @@ import { msg, t } from '@lingui/core/macro';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
import { NavigationMenuItemExceptionCode } from 'src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.exception';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
import { validateFlatEntityCircularDependency } from 'src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util';
@@ -107,7 +107,7 @@ export class FlatNavigationMenuItemValidatorService {
}: {
navigationMenuItemId: string;
folderId: string;
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
flatNavigationMenuItemMaps: MetadataFlatEntityMaps<'navigationMenuItem'>;
}): FlatEntityValidationError<NavigationMenuItemExceptionCode>[] {
const circularDependencyResult = validateFlatEntityCircularDependency({
flatEntityId: navigationMenuItemId,
@@ -7,7 +7,7 @@ import { isDefined } from 'twenty-shared/utils';
import { validateFlatObjectMetadataIdentifiers } from 'src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-identifiers.util';
import { validateFlatObjectMetadataNameAndLabels } from 'src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name-and-labels.util';
import { ObjectMetadataExceptionCode } from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
@@ -140,7 +140,7 @@ export class FlatObjectMetadataValidatorService {
if (
!buildOptions.isSystemBuild &&
isStandardMetadata(flatObjectMetadataToDelete)
belongsToTwentyStandardApp(flatObjectMetadataToDelete)
) {
validationResult.errors.push({
code: ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
@@ -7,7 +7,7 @@ import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatSkill } from 'src/engine/metadata-modules/flat-skill/types/flat-skill.type';
import { SkillExceptionCode } from 'src/engine/metadata-modules/skill/skill.exception';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
@@ -93,7 +93,16 @@ export class FlatSkillValidatorService {
return validationResult;
}
if (!buildOptions.isSystemBuild && isStandardMetadata(existingSkill)) {
if (
!buildOptions.isSystemBuild &&
// TODO refactor once skill has been migrated to universal pattern
isDefined(existingSkill.__universal) &&
belongsToTwentyStandardApp({
universalIdentifier: existingSkill.universalIdentifier,
applicationUniversalIdentifier:
existingSkill.__universal.applicationUniversalIdentifier,
})
) {
validationResult.errors.push({
code: SkillExceptionCode.SKILL_IS_STANDARD,
message: t`Cannot delete standard skill`,
@@ -148,9 +157,18 @@ export class FlatSkillValidatorService {
(update) => update.property !== 'isActive',
);
// TODO refactor once skill has been migrated to universal pattern
const isTwentyStandardSkill =
isDefined(fromFlatSkill.__universal) &&
belongsToTwentyStandardApp({
universalIdentifier: fromFlatSkill.universalIdentifier,
applicationUniversalIdentifier:
fromFlatSkill.__universal.applicationUniversalIdentifier,
});
if (
!buildOptions.isSystemBuild &&
isStandardMetadata(fromFlatSkill) &&
isTwentyStandardSkill &&
hasNonIsActiveUpdates
) {
validationResult.errors.push({
@@ -162,7 +180,7 @@ export class FlatSkillValidatorService {
// If only isActive is being updated on a standard skill, allow it
if (
isStandardMetadata(fromFlatSkill) &&
isTwentyStandardSkill &&
isDefined(isActiveUpdate) &&
!hasNonIsActiveUpdates
) {
@@ -3,8 +3,11 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { CreateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { FlatCreateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
@Injectable()
export class CreateAgentActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
@@ -15,11 +18,17 @@ export class CreateAgentActionHandlerService extends WorkspaceMigrationRunnerAct
super();
}
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<FlatCreateAgentAction>,
): Promise<FlatCreateAgentAction> {
return context.action;
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<CreateAgentAction>,
context: WorkspaceMigrationActionRunnerContext<FlatCreateAgentAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { flatEntity } = action;
const { flatAction, queryRunner, workspaceId } = context;
const { flatEntity } = flatAction;
const agentRepository =
queryRunner.manager.getRepository<AgentEntity>(AgentEntity);
@@ -31,7 +40,7 @@ export class CreateAgentActionHandlerService extends WorkspaceMigrationRunnerAct
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<CreateAgentAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatCreateAgentAction>,
): Promise<void> {
return;
}
@@ -3,9 +3,14 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { DeleteAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import {
FlatDeleteAgentAction,
UniversalDeleteAgentAction,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
@Injectable()
export class DeleteAgentActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
@@ -16,25 +21,25 @@ export class DeleteAgentActionHandlerService extends WorkspaceMigrationRunnerAct
super();
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<DeleteAgentAction>,
): Promise<void> {
const { action, queryRunner, workspaceId, allFlatEntityMaps } = context;
const { universalIdentifier } = action;
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<UniversalDeleteAgentAction>,
): Promise<FlatDeleteAgentAction> {
return this.transpileUniversalDeleteActionToFlatDeleteAction(context);
}
const flatAgent = findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: allFlatEntityMaps.flatAgentMaps,
universalIdentifier,
});
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatDeleteAgentAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const agentRepository =
queryRunner.manager.getRepository<AgentEntity>(AgentEntity);
await agentRepository.delete({ id: flatAgent.id, workspaceId });
await agentRepository.delete({ id: flatAction.entityId, workspaceId });
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<DeleteAgentAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatDeleteAgentAction>,
): Promise<void> {
return;
}
@@ -3,8 +3,11 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { UpdateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { FlatUpdateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
@Injectable()
@@ -12,11 +15,17 @@ export class UpdateAgentActionHandlerService extends WorkspaceMigrationRunnerAct
'update',
'agent',
) {
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<FlatUpdateAgentAction>,
): Promise<FlatUpdateAgentAction> {
return context.action;
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<UpdateAgentAction>,
context: WorkspaceMigrationActionRunnerContext<FlatUpdateAgentAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { entityId, updates } = action;
const { flatAction, queryRunner, workspaceId } = context;
const { entityId, updates } = flatAction;
const agentRepository =
queryRunner.manager.getRepository<AgentEntity>(AgentEntity);
@@ -30,7 +39,7 @@ export class UpdateAgentActionHandlerService extends WorkspaceMigrationRunnerAct
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<UpdateAgentAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatUpdateAgentAction>,
): Promise<void> {
return;
}
@@ -3,8 +3,11 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { CommandMenuItemEntity } from 'src/engine/metadata-modules/command-menu-item/entities/command-menu-item.entity';
import { CreateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { FlatCreateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
@Injectable()
export class CreateCommandMenuItemActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
@@ -15,11 +18,17 @@ export class CreateCommandMenuItemActionHandlerService extends WorkspaceMigratio
super();
}
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<FlatCreateCommandMenuItemAction>,
): Promise<FlatCreateCommandMenuItemAction> {
return context.action;
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<CreateCommandMenuItemAction>,
context: WorkspaceMigrationActionRunnerContext<FlatCreateCommandMenuItemAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { flatEntity } = action;
const { flatAction, queryRunner, workspaceId } = context;
const { flatEntity } = flatAction;
const commandMenuItemRepository =
queryRunner.manager.getRepository<CommandMenuItemEntity>(
@@ -33,7 +42,7 @@ export class CreateCommandMenuItemActionHandlerService extends WorkspaceMigratio
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<CreateCommandMenuItemAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatCreateCommandMenuItemAction>,
): Promise<void> {
return;
}
@@ -3,9 +3,14 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { CommandMenuItemEntity } from 'src/engine/metadata-modules/command-menu-item/entities/command-menu-item.entity';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { DeleteCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import {
FlatDeleteCommandMenuItemAction,
UniversalDeleteCommandMenuItemAction,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
@Injectable()
export class DeleteCommandMenuItemActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
@@ -16,16 +21,16 @@ export class DeleteCommandMenuItemActionHandlerService extends WorkspaceMigratio
super();
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<DeleteCommandMenuItemAction>,
): Promise<void> {
const { action, queryRunner, workspaceId, allFlatEntityMaps } = context;
const { universalIdentifier } = action;
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<UniversalDeleteCommandMenuItemAction>,
): Promise<FlatDeleteCommandMenuItemAction> {
return this.transpileUniversalDeleteActionToFlatDeleteAction(context);
}
const flatCommandMenuItem = findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: allFlatEntityMaps.flatCommandMenuItemMaps,
universalIdentifier,
});
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatDeleteCommandMenuItemAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const commandMenuItemRepository =
queryRunner.manager.getRepository<CommandMenuItemEntity>(
@@ -33,13 +38,13 @@ export class DeleteCommandMenuItemActionHandlerService extends WorkspaceMigratio
);
await commandMenuItemRepository.delete({
id: flatCommandMenuItem.id,
id: flatAction.entityId,
workspaceId,
});
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<DeleteCommandMenuItemAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatDeleteCommandMenuItemAction>,
): Promise<void> {
return;
}
@@ -3,8 +3,11 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { CommandMenuItemEntity } from 'src/engine/metadata-modules/command-menu-item/entities/command-menu-item.entity';
import { UpdateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { FlatUpdateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
@Injectable()
@@ -12,11 +15,17 @@ export class UpdateCommandMenuItemActionHandlerService extends WorkspaceMigratio
'update',
'commandMenuItem',
) {
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<FlatUpdateCommandMenuItemAction>,
): Promise<FlatUpdateCommandMenuItemAction> {
return context.action;
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<UpdateCommandMenuItemAction>,
context: WorkspaceMigrationActionRunnerContext<FlatUpdateCommandMenuItemAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { entityId, updates } = action;
const { flatAction, queryRunner, workspaceId } = context;
const { entityId, updates } = flatAction;
const commandMenuItemRepository =
queryRunner.manager.getRepository<CommandMenuItemEntity>(
@@ -32,7 +41,7 @@ export class UpdateCommandMenuItemActionHandlerService extends WorkspaceMigratio
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<UpdateCommandMenuItemAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatUpdateCommandMenuItemAction>,
): Promise<void> {
return;
}
@@ -2,17 +2,29 @@ import { Injectable } from '@nestjs/common';
import { RelationType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type QueryRunner } from 'typeorm';
import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-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 { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration/utils/convert-on-delete-action-to-on-delete.util';
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import {
type FlatCreateFieldAction,
type UniversalCreateFieldAction,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { fromUniversalFlatFieldMetadataToFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/from-universal-flat-field-metadata-to-flat-field-metadata.util';
import {
WorkspaceMigrationActionRunnerContext,
type WorkspaceMigrationActionRunnerArgs,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { generateColumnDefinitions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util';
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util';
import {
@@ -32,108 +44,199 @@ export class CreateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
super();
}
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<UniversalCreateFieldAction>,
): Promise<FlatCreateFieldAction> {
const { action, allFlatEntityMaps } = context;
const { universalFlatFieldMetadatas, fieldIdByUniversalIdentifier } =
action;
const allFieldIdToBeCreatedInActionByUniversalIdentifierMap = new Map<
string,
string
>();
for (const universalFlatFieldMetadata of universalFlatFieldMetadatas) {
const providedId =
fieldIdByUniversalIdentifier?.[
universalFlatFieldMetadata.universalIdentifier
];
allFieldIdToBeCreatedInActionByUniversalIdentifierMap.set(
universalFlatFieldMetadata.universalIdentifier,
providedId ?? v4(),
);
}
const flatFieldMetadatas = universalFlatFieldMetadatas.map(
(universalFlatFieldMetadata) =>
fromUniversalFlatFieldMetadataToFlatFieldMetadata({
universalFlatFieldMetadata,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
allFlatEntityMaps,
context,
}),
);
return {
type: action.type,
metadataName: action.metadataName,
flatFieldMetadatas,
};
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<CreateFieldAction>,
context: WorkspaceMigrationActionRunnerContext<FlatCreateFieldAction>,
): Promise<void> {
const { action, queryRunner } = context;
const { queryRunner, flatAction } = context;
const { flatFieldMetadatas } = flatAction;
const fieldMetadataRepository =
queryRunner.manager.getRepository<FieldMetadataEntity>(
FieldMetadataEntity,
);
const { flatFieldMetadatas } = action;
for (const flatFieldMetadata of flatFieldMetadatas) {
await fieldMetadataRepository.insert(flatFieldMetadata);
}
await fieldMetadataRepository.insert(flatFieldMetadatas);
}
async executeForWorkspaceSchema(
context: WorkspaceMigrationActionRunnerArgs<CreateFieldAction>,
context: WorkspaceMigrationActionRunnerContext<FlatCreateFieldAction>,
): Promise<void> {
const {
action,
flatAction,
queryRunner,
allFlatEntityMaps: { flatObjectMetadataMaps },
workspaceId,
} = context;
const { flatFieldMetadatas } = action;
const { flatFieldMetadatas } = flatAction;
const fieldsByObjectMetadataId = new Map<
string,
typeof flatFieldMetadatas
>();
// TODO prastoin improve doing batchs
for (const flatFieldMetadata of flatFieldMetadatas) {
const existingFields = fieldsByObjectMetadataId.get(
flatFieldMetadata.objectMetadataId,
);
if (isDefined(existingFields)) {
existingFields.push(flatFieldMetadata);
} else {
fieldsByObjectMetadataId.set(flatFieldMetadata.objectMetadataId, [
flatFieldMetadata,
]);
}
}
for (const [
objectMetadataId,
objectFlatFieldMetadatas,
] of fieldsByObjectMetadataId) {
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityMaps: flatObjectMetadataMaps,
flatEntityId: flatFieldMetadata.objectMetadataId,
flatEntityId: objectMetadataId,
});
const { schemaName, tableName } = getWorkspaceSchemaContextForMigration({
workspaceId,
flatObjectMetadata,
objectMetadata: flatObjectMetadata,
});
const enumOperations = collectEnumOperationsForField({
flatFieldMetadata,
tableName,
operation: EnumOperation.CREATE,
});
const columnDefinitions = generateColumnDefinitions({
flatFieldMetadata,
flatObjectMetadata,
});
await executeBatchEnumOperations({
enumOperations,
queryRunner,
schemaName,
workspaceSchemaManagerService: this.workspaceSchemaManagerService,
});
await this.workspaceSchemaManagerService.columnManager.addColumns({
queryRunner,
schemaName,
tableName,
columnDefinitions,
});
if (
isMorphOrRelationFlatFieldMetadata(flatFieldMetadata) &&
flatFieldMetadata.settings.relationType === RelationType.MANY_TO_ONE
) {
const targetFlatObjectMetadata =
findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatFieldMetadata.relationTargetObjectMetadataId,
flatEntityMaps: flatObjectMetadataMaps,
});
const referencedTableName = computeObjectTargetTable(
targetFlatObjectMetadata,
);
const joinColumnName = flatFieldMetadata.settings.joinColumnName;
if (!isDefined(joinColumnName)) {
throw new Error(
'Join column name is not defined in a MANY_TO_ONE relation',
);
}
await this.workspaceSchemaManagerService.foreignKeyManager.createForeignKey(
{
queryRunner,
schemaName,
foreignKey: {
tableName,
columnName: joinColumnName,
referencedTableName,
referencedColumnName: 'id',
onDelete:
convertOnDeleteActionToOnDelete(
flatFieldMetadata.settings.onDelete,
) ?? 'CASCADE',
},
},
);
for (const flatFieldMetadata of objectFlatFieldMetadatas) {
await this.executeSingleFieldMetadataWorkspaceSchema({
flatFieldMetadata,
flatObjectMetadata,
flatObjectMetadataMaps,
queryRunner,
schemaName,
tableName,
workspaceId,
});
}
}
}
private async executeSingleFieldMetadataWorkspaceSchema({
flatFieldMetadata,
flatObjectMetadata,
flatObjectMetadataMaps,
queryRunner,
schemaName,
tableName,
workspaceId,
}: {
flatFieldMetadata: FlatFieldMetadata;
flatObjectMetadata: FlatObjectMetadata;
flatObjectMetadataMaps: MetadataFlatEntityMaps<'objectMetadata'>;
queryRunner: QueryRunner;
schemaName: string;
tableName: string;
workspaceId: string;
}): Promise<void> {
const enumOperations = collectEnumOperationsForField({
flatFieldMetadata,
tableName,
operation: EnumOperation.CREATE,
});
const columnDefinitions = generateColumnDefinitions({
flatFieldMetadata,
flatObjectMetadata,
workspaceId,
});
await executeBatchEnumOperations({
enumOperations,
queryRunner,
schemaName,
workspaceSchemaManagerService: this.workspaceSchemaManagerService,
});
await this.workspaceSchemaManagerService.columnManager.addColumns({
queryRunner,
schemaName,
tableName,
columnDefinitions,
});
if (
isMorphOrRelationFlatFieldMetadata(flatFieldMetadata) &&
flatFieldMetadata.settings?.relationType === RelationType.MANY_TO_ONE
) {
const targetFlatObjectMetadata =
findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityMaps: flatObjectMetadataMaps,
flatEntityId: flatFieldMetadata.relationTargetObjectMetadataId!,
});
const referencedTableName = computeObjectTargetTable(
targetFlatObjectMetadata,
);
const joinColumnName = flatFieldMetadata.settings?.joinColumnName;
if (!isDefined(joinColumnName)) {
throw new Error(
'Join column name is not defined in a MANY_TO_ONE relation',
);
}
await this.workspaceSchemaManagerService.foreignKeyManager.createForeignKey(
{
queryRunner,
schemaName,
foreignKey: {
tableName,
columnName: joinColumnName,
referencedTableName,
referencedColumnName: 'id',
onDelete:
convertOnDeleteActionToOnDelete(
flatFieldMetadata.settings?.onDelete,
) ?? 'CASCADE',
},
},
);
}
}
}
@@ -3,10 +3,16 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import { type DeleteFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import {
type FlatDeleteFieldAction,
type UniversalDeleteFieldAction,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import {
type WorkspaceMigrationActionRunnerArgs,
type WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { generateColumnDefinitions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util';
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util';
import {
@@ -26,16 +32,16 @@ export class DeleteFieldActionHandlerService extends WorkspaceMigrationRunnerAct
super();
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<DeleteFieldAction>,
) {
const { action, queryRunner, allFlatEntityMaps } = context;
const { universalIdentifier } = action;
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<UniversalDeleteFieldAction>,
): Promise<FlatDeleteFieldAction> {
return this.transpileUniversalDeleteActionToFlatDeleteAction(context);
}
const flatFieldMetadata = findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: allFlatEntityMaps.flatFieldMetadataMaps,
universalIdentifier,
});
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatDeleteFieldAction>,
) {
const { flatAction, queryRunner, workspaceId } = context;
const fieldMetadataRepository =
queryRunner.manager.getRepository<FieldMetadataEntity>(
@@ -43,40 +49,40 @@ export class DeleteFieldActionHandlerService extends WorkspaceMigrationRunnerAct
);
await fieldMetadataRepository.delete({
id: flatFieldMetadata.id,
workspaceId: context.workspaceId,
id: flatAction.entityId,
workspaceId,
});
}
async executeForWorkspaceSchema(
context: WorkspaceMigrationActionRunnerArgs<DeleteFieldAction>,
context: WorkspaceMigrationActionRunnerContext<FlatDeleteFieldAction>,
) {
const {
action,
flatAction,
queryRunner,
allFlatEntityMaps: { flatObjectMetadataMaps, flatFieldMetadataMaps },
workspaceId,
} = context;
const { universalIdentifier } = action;
const fieldMetadata = findFlatEntityByUniversalIdentifierOrThrow({
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityMaps: flatFieldMetadataMaps,
universalIdentifier,
flatEntityId: flatAction.entityId,
});
const flatObjectMetadata = findFlatEntityByUniversalIdentifierOrThrow({
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityMaps: flatObjectMetadataMaps,
universalIdentifier: fieldMetadata.objectMetadataUniversalIdentifier,
flatEntityId: flatFieldMetadata.objectMetadataId,
});
const { schemaName, tableName } = getWorkspaceSchemaContextForMigration({
workspaceId,
flatObjectMetadata,
objectMetadata: flatObjectMetadata,
});
const columnDefinitions = generateColumnDefinitions({
flatFieldMetadata: fieldMetadata,
flatObjectMetadata: flatObjectMetadata,
flatFieldMetadata,
flatObjectMetadata,
workspaceId,
});
const columnNamesToDrop = columnDefinitions.map((def) => def.name);
@@ -89,7 +95,7 @@ export class DeleteFieldActionHandlerService extends WorkspaceMigrationRunnerAct
});
const enumOperations = collectEnumOperationsForField({
flatFieldMetadata: fieldMetadata,
flatFieldMetadata,
tableName,
operation: EnumOperation.DROP,
});
@@ -9,7 +9,6 @@ import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-mana
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
import { getCompositeTypeOrThrow } from 'src/engine/metadata-modules/field-metadata/utils/get-composite-type-or-throw.util';
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
@@ -25,13 +24,19 @@ import { PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration
import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration/utils/convert-on-delete-action-to-on-delete.util';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/is-property-update.util';
import { UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import {
FlatUpdateFieldAction,
UniversalUpdateFieldAction,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { serializeDefaultValue } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/utils/serialize-default-value.util';
import {
WorkspaceMigrationActionExecutionException,
WorkspaceMigrationActionExecutionExceptionCode,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/exceptions/workspace-migration-action-execution.exception';
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import {
type WorkspaceMigrationActionRunnerArgs,
type WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { fieldMetadataTypeToColumnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/field-metadata-type-to-column-type.util';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
import { generateColumnDefinitions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util';
@@ -64,48 +69,68 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
super();
}
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<UniversalUpdateFieldAction>,
): Promise<FlatUpdateFieldAction> {
const { action, allFlatEntityMaps } = context;
const flatFieldMetadata = findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: allFlatEntityMaps.flatFieldMetadataMaps,
universalIdentifier: action.universalIdentifier,
});
// TODO: transpile settings universal identifiers when builder has been migrated
// For now, updates only contain flat entity diff properties (already IDs, not universal identifiers)
return {
type: 'update',
metadataName: 'fieldMetadata',
entityId: flatFieldMetadata.id,
updates: action.updates,
};
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<UpdateFieldAction>,
context: WorkspaceMigrationActionRunnerContext<FlatUpdateFieldAction>,
): Promise<void> {
const { action, queryRunner } = context;
const { flatAction, queryRunner } = context;
const fieldMetadataRepository =
queryRunner.manager.getRepository<FieldMetadataEntity>(
FieldMetadataEntity,
);
const { entityId } = action;
const { entityId } = flatAction;
await fieldMetadataRepository.update(
entityId,
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(action),
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
);
}
async executeForWorkspaceSchema(
context: WorkspaceMigrationActionRunnerArgs<UpdateFieldAction>,
context: WorkspaceMigrationActionRunnerContext<FlatUpdateFieldAction>,
): Promise<void> {
const {
action,
flatAction,
queryRunner,
allFlatEntityMaps: { flatObjectMetadataMaps, flatFieldMetadataMaps },
workspaceId,
} = context;
const { entityId, updates } = action;
const { entityId, updates } = flatAction;
const currentFlatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: entityId,
flatEntityMaps: flatFieldMetadataMaps,
});
const flatObjectMetadata = findFlatEntityByUniversalIdentifierOrThrow({
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityMaps: flatObjectMetadataMaps,
universalIdentifier:
currentFlatFieldMetadata.objectMetadataUniversalIdentifier,
flatEntityId: currentFlatFieldMetadata.objectMetadataId,
});
const { schemaName, tableName } = getWorkspaceSchemaContextForMigration({
workspaceId,
flatObjectMetadata,
objectMetadata: flatObjectMetadata,
});
let optimisticFlatFieldMetadata = structuredClone(currentFlatFieldMetadata);
@@ -166,9 +191,10 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
queryRunner,
schemaName,
tableName,
flatObjectMetadata,
flatFieldMetadata: optimisticFlatFieldMetadata,
flatObjectMetadata,
update,
workspaceId,
});
optimisticFlatFieldMetadata.options = update.to ?? [];
}
@@ -337,7 +363,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
}
const enumOperations = collectEnumOperationsForField({
flatFieldMetadata: flatFieldMetadata,
flatFieldMetadata,
tableName,
operation: EnumOperation.RENAME,
options: {
@@ -360,7 +386,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
tableName,
update,
}: UpdateFieldPropertyUpdateHandlerArgs<'defaultValue'>) {
if (isCompositeFieldMetadataType(flatFieldMetadata.type)) {
if (isCompositeFlatFieldMetadata(flatFieldMetadata)) {
const compositeType = getCompositeTypeOrThrow(flatFieldMetadata.type);
for (const property of compositeType.properties) {
@@ -435,8 +461,10 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
tableName,
update,
flatObjectMetadata,
workspaceId,
}: UpdateFieldPropertyUpdateHandlerArgs<'options'> & {
flatObjectMetadata: FlatObjectMetadata;
workspaceId: string;
}) {
const fromOptionsById = new Map(
(update.from ?? [])
@@ -461,8 +489,9 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
}
const enumColumnDefinitions = generateColumnDefinitions({
flatFieldMetadata: flatFieldMetadata,
flatObjectMetadata: flatObjectMetadata,
flatFieldMetadata,
flatObjectMetadata,
workspaceId,
});
for (const enumColumnDefinition of enumColumnDefinitions) {
@@ -0,0 +1,27 @@
import { isDefined } from 'twenty-shared/utils';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
export const findFieldMetadataIdInCreateFieldContext = ({
universalIdentifier,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
flatFieldMetadataMaps,
}: {
universalIdentifier: string;
allFieldIdToBeCreatedInActionByUniversalIdentifierMap: Map<string, string>;
flatFieldMetadataMaps: MetadataFlatEntityMaps<'fieldMetadata'>;
}): string | null => {
const generatedId =
allFieldIdToBeCreatedInActionByUniversalIdentifierMap.get(
universalIdentifier,
);
if (isDefined(generatedId)) {
return generatedId;
}
const existingFieldId =
flatFieldMetadataMaps.idByUniversalIdentifier[universalIdentifier];
return existingFieldId ?? null;
};
@@ -0,0 +1,147 @@
import { isDefined } from 'twenty-shared/utils';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type AllUniversalWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-action-common';
import { findFieldMetadataIdInCreateFieldContext } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/find-field-metadata-id-in-create-field-context.util';
import { fromUniversalSettingsToFlatFieldMetadataSettings } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/from-universal-settings-to-flat-field-metadata-settings.util';
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
export type FromUniversalFlatFieldMetadataToFlatFieldMetadataArgs = {
allFieldIdToBeCreatedInActionByUniversalIdentifierMap: Map<string, string>;
universalFlatFieldMetadata: UniversalFlatFieldMetadata;
allFlatEntityMaps: AllFlatEntityMaps;
context: Pick<
WorkspaceMigrationActionRunnerArgs<AllUniversalWorkspaceMigrationAction>,
'workspaceId' | 'flatApplication'
>;
objectMetadataId?: string;
};
const getIdFromUniversalIdentifier = (
universalIdentifier: string,
flatEntityMaps: { idByUniversalIdentifier: Partial<Record<string, string>> },
): string | null => {
return flatEntityMaps.idByUniversalIdentifier[universalIdentifier] ?? null;
};
export const fromUniversalFlatFieldMetadataToFlatFieldMetadata = ({
universalFlatFieldMetadata,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
allFlatEntityMaps,
objectMetadataId: optionalObjectMetadataId,
context: {
flatApplication: { id: applicationId },
workspaceId,
},
}: FromUniversalFlatFieldMetadataToFlatFieldMetadataArgs): FlatFieldMetadata => {
const {
universalIdentifier,
applicationUniversalIdentifier,
objectMetadataUniversalIdentifier,
relationTargetFieldMetadataUniversalIdentifier,
relationTargetObjectMetadataUniversalIdentifier,
viewFilterUniversalIdentifiers: _viewFilterUniversalIdentifiers,
viewFieldUniversalIdentifiers: _viewFieldUniversalIdentifiers,
kanbanAggregateOperationViewUniversalIdentifiers:
_kanbanAggregateOperationViewUniversalIdentifiers,
calendarViewUniversalIdentifiers: _calendarViewUniversalIdentifiers,
mainGroupByFieldMetadataViewUniversalIdentifiers:
_mainGroupByFieldMetadataViewUniversalIdentifiers,
universalSettings,
...restProperties
} = universalFlatFieldMetadata;
const generatedId =
allFieldIdToBeCreatedInActionByUniversalIdentifierMap.get(
universalIdentifier,
);
if (!isDefined(generatedId)) {
throw new Error(
`Generated ID not found for universal identifier: ${universalIdentifier}`,
);
}
const objectMetadataId =
optionalObjectMetadataId ??
getIdFromUniversalIdentifier(
objectMetadataUniversalIdentifier,
allFlatEntityMaps.flatObjectMetadataMaps,
);
if (!isDefined(objectMetadataId)) {
throw new Error(
`Object metadata not found for universal identifier: ${objectMetadataUniversalIdentifier}`,
);
}
let relationTargetFieldMetadataId: string | null = null;
if (isDefined(relationTargetFieldMetadataUniversalIdentifier)) {
relationTargetFieldMetadataId = findFieldMetadataIdInCreateFieldContext({
universalIdentifier: relationTargetFieldMetadataUniversalIdentifier,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
flatFieldMetadataMaps: allFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(relationTargetFieldMetadataId)) {
throw new Error(
`Relation target field metadata not found for universal identifier: ${relationTargetFieldMetadataUniversalIdentifier}`,
);
}
}
let relationTargetObjectMetadataId: string | null = null;
if (isDefined(relationTargetObjectMetadataUniversalIdentifier)) {
relationTargetObjectMetadataId = getIdFromUniversalIdentifier(
relationTargetObjectMetadataUniversalIdentifier,
allFlatEntityMaps.flatObjectMetadataMaps,
);
if (!isDefined(relationTargetObjectMetadataId)) {
throw new Error(
`Relation target object metadata not found for universal identifier: ${relationTargetObjectMetadataUniversalIdentifier}`,
);
}
}
const settings = fromUniversalSettingsToFlatFieldMetadataSettings({
universalSettings,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
flatFieldMetadataMaps: allFlatEntityMaps.flatFieldMetadataMaps,
});
return {
...restProperties,
settings,
universalSettings,
id: generatedId,
workspaceId,
applicationId,
standardId: null,
universalIdentifier,
objectMetadataId,
objectMetadataUniversalIdentifier,
relationTargetFieldMetadataId,
relationTargetFieldMetadataUniversalIdentifier:
relationTargetFieldMetadataUniversalIdentifier ?? null,
relationTargetObjectMetadataId,
relationTargetObjectMetadataUniversalIdentifier:
relationTargetObjectMetadataUniversalIdentifier ?? null,
applicationUniversalIdentifier,
// Empty aggregator arrays for newly created entities
viewFieldIds: [],
viewFilterIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
kanbanAggregateOperationViewIds: [],
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
calendarViewUniversalIdentifiers: [],
mainGroupByFieldMetadataViewUniversalIdentifiers: [],
kanbanAggregateOperationViewUniversalIdentifiers: [],
};
};
@@ -0,0 +1,68 @@
import {
type FieldMetadataSettings,
FieldMetadataType,
} from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { isUniversalFieldMetadataSettingsOftype } from 'src/engine/metadata-modules/field-metadata/utils/is-field-metadata-settings-of-type.util';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { findFieldMetadataIdInCreateFieldContext } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/find-field-metadata-id-in-create-field-context.util';
import {
WorkspaceMigrationActionExecutionException,
WorkspaceMigrationActionExecutionExceptionCode,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/exceptions/workspace-migration-action-execution.exception';
export const fromUniversalSettingsToFlatFieldMetadataSettings = ({
universalSettings,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
flatFieldMetadataMaps,
}: {
universalSettings: UniversalFlatFieldMetadata['universalSettings'];
allFieldIdToBeCreatedInActionByUniversalIdentifierMap: Map<string, string>;
flatFieldMetadataMaps: MetadataFlatEntityMaps<'fieldMetadata'>;
}): FieldMetadataSettings => {
if (!isDefined(universalSettings)) {
return null;
}
if (
isUniversalFieldMetadataSettingsOftype(
universalSettings,
FieldMetadataType.RELATION,
) ||
isUniversalFieldMetadataSettingsOftype(
universalSettings,
FieldMetadataType.MORPH_RELATION,
)
) {
const { junctionTargetFieldUniversalIdentifier, ...rest } =
universalSettings;
const junctionTargetFieldId = isDefined(
junctionTargetFieldUniversalIdentifier,
)
? (findFieldMetadataIdInCreateFieldContext({
universalIdentifier: junctionTargetFieldUniversalIdentifier,
allFieldIdToBeCreatedInActionByUniversalIdentifierMap,
flatFieldMetadataMaps,
}) ?? undefined)
: undefined;
if (
isDefined(junctionTargetFieldUniversalIdentifier) &&
!isDefined(junctionTargetFieldId)
) {
throw new WorkspaceMigrationActionExecutionException({
code: WorkspaceMigrationActionExecutionExceptionCode.FIELD_METADATA_NOT_FOUND,
message: `Could not not find junction column id for universal identifier ${junctionTargetFieldUniversalIdentifier}`,
});
}
return {
...rest,
junctionTargetFieldId,
};
}
return universalSettings;
};
@@ -3,8 +3,11 @@ import { Injectable } from '@nestjs/common';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
import { CreateFrontComponentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { FlatCreateFrontComponentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
import {
WorkspaceMigrationActionRunnerArgs,
WorkspaceMigrationActionRunnerContext,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
@Injectable()
export class CreateFrontComponentActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
@@ -15,11 +18,17 @@ export class CreateFrontComponentActionHandlerService extends WorkspaceMigration
super();
}
override async transpileUniversalActionToFlatAction(
context: WorkspaceMigrationActionRunnerArgs<FlatCreateFrontComponentAction>,
): Promise<FlatCreateFrontComponentAction> {
return context.action;
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<CreateFrontComponentAction>,
context: WorkspaceMigrationActionRunnerContext<FlatCreateFrontComponentAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { flatEntity } = action;
const { flatAction, queryRunner, workspaceId } = context;
const { flatEntity } = flatAction;
const frontComponentRepository =
queryRunner.manager.getRepository<FrontComponentEntity>(
@@ -33,7 +42,7 @@ export class CreateFrontComponentActionHandlerService extends WorkspaceMigration
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<CreateFrontComponentAction>,
_context: WorkspaceMigrationActionRunnerContext<FlatCreateFrontComponentAction>,
): Promise<void> {
return;
}

Some files were not shown because too many files have changed in this diff Show More