From 084fa8eaba022435dadaecef04503edc9bb8de89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Fri, 22 May 2026 11:56:33 +0200 Subject: [PATCH] fix(server): auto-index targetId join columns on polymorphic standard objects (#20820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #20726 ## The bug `timelineActivity` (and the three other polymorphic standard objects — `attachment`, `noteTarget`, `taskTarget`) store relations as N nullable `targetId` columns, one per related object. Each one is a join key queried as `WHERE targetId IN (...) AND deletedAt IS NULL`. For **built-in** related objects (Person, Company, Opportunity, …), each `targetId` column gets a BTREE index, declared statically in `compute-{timelineActivity,attachment,noteTarget,taskTarget}-standard-flat-index-metadata.util.ts`. For **custom** related objects, the same `targetId` column was added — **without an index**. On a `timelineActivity` table at issue-reporter scale (~21.9M rows, 7.1 GB), this turned record loads into 20–40s sequential scans and produced `QueryFailedError: Query read timeout` for end users. ## Diagnosis The morph/relation field generator (`generateMorphOrRelationFlatFieldMetadataPair`) already creates a BTREE index for the field that owns the join column and returns it alongside the field metadata pair. The two user-driven entry points (`fromRelationCreateFieldInput…`, `fromMorphRelationCreateFieldInput…`) correctly destructure and propagate that index. But the **custom-object creation path** — `buildDefaultRelationFlatFieldMetadatasForCustomObject`, called when a user creates a new custom object — destructured only `{ flatFieldMetadatas }` and threw away `indexMetadatas`. So every `targetId` column added to the four polymorphic standard objects has been shipping unindexed since custom morph relations went in. ## The fix Three commits. ### 1. `fix(server): index targetId columns on standard polymorphic objects` 13 lines across 2 files. - `build-default-relation-flat-field-metadatas-for-custom-object.util.ts` — also destructure `indexMetadatas` from the pair generator and accumulate them into the returned record (new field `standardTargetFlatIndexMetadatas`). - `from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts` — append the accumulated indexes to `flatIndexMetadataToCreate`. The migration pipeline at `object-metadata.service.ts:559–562` already passes `flatIndexMetadataToCreate` to the migration runner, so no further wiring is needed. From now on, creating a custom object also creates the four BTREE indexes — one per polymorphic standard object's new `targetId` column — atomically with the rest of the migration. ### 2. `feat(server): backfill workspace command for relation join column indexes` For existing workspaces whose custom objects were created before the forward-fix. `upgrade:2-8:backfill-relation-join-column-indexes` is a `@RegisteredWorkspaceCommand('2.8.0', 1798100000000)` matching the pattern from `2-7-workspace-command-…-drop-connected-account-standard-object.command.ts`. Per workspace: 1. Load `flatObjectMetadataMaps`, `flatFieldMetadataMaps`, `flatIndexMaps` from the workspace cache. 2. Resolve the four polymorphic standard object IDs by `nameSingular` against `DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS`. 3. Collect every field ID that's already covered by any existing index. 4. Filter `flatFieldMetadataMaps` to MORPH_RELATION fields on those four objects whose `settings.relationType === MANY_TO_ONE` (i.e. owns a join column) and whose ID isn't in the indexed set. 5. Generate a BTREE `UniversalFlatIndexMetadata` for each via `generateIndexForFlatFieldMetadata` (same helper the forward-fix uses). 6. Create the indexes in the workspace schema with **CONCURRENTLY** (see commit 3). 7. Submit the metadata through `WorkspaceMigrationValidateBuildAndRunService` so it lands in `indexMetadata` and the cache — same pipeline as a normal metadata change. The pipeline's own `CREATE INDEX IF NOT EXISTS` no-ops because the index already exists. Properties: - **Idempotent.** Re-running is a no-op once indexes exist. - **Scoped.** Only the four polymorphic standard objects, only their MANY_TO_ONE morph relation fields, only those with no covering index. - **Same code path as the forward-fix.** The backfill produces exactly the indexes the forward-fix would have created at custom-object creation time. - **`--dry-run` supported** via the base `ActiveOrSuspendedWorkspaceCommandRunner`. ### 3. `feat(server): create index CONCURRENTLY in relation join column backfill` Adds an opt-in `concurrently` flag to `WorkspaceSchemaIndexManagerService.createIndex` (threaded through `createIndexInWorkspaceSchema`). When `true`, emits `CREATE INDEX CONCURRENTLY IF NOT EXISTS …`. Defaults to `false` — every existing caller keeps the current transactional `CREATE INDEX` behavior. The backfill command opts in. It creates a QueryRunner **without** `startTransaction()`, issues the CONCURRENTLY indexes one-by-one (each waits for the previous to finish), then submits the metadata through the normal migration pipeline whose own `CREATE INDEX IF NOT EXISTS` is now a no-op. Why not flip the default for the helper: - `CREATE INDEX CONCURRENTLY` cannot run inside a transaction — Postgres errors out. The migration pipeline calls `createIndex` from inside a transactional schema migration. - CONCURRENTLY doesn't roll back with the transaction. If the surrounding migration fails, the index remains and you end up with metadata/schema drift. - Failed CONCURRENTLY builds leave an INVALID index behind that needs manual `DROP`. - UNIQUE indexes have different failure semantics under CONCURRENTLY (deferred, not immediate). So CONCURRENTLY is opt-in, used only where it's the right tool (post-hoc backfills on populated tables). ## Decisions / tradeoffs - **Single-column BTREE vs partial `WHERE deletedAt IS NULL` vs composite.** Twenty's queries always include `deletedAt IS NULL`. A partial index would be slightly better than a plain BTREE (smaller, no wasted seeks on soft-deleted rows). This PR ships single-column to match the existing built-in target index pattern, which already covers >95% of the available speedup (the 20s→4ms drop the reporter saw comes from having any index — composite/partial is a second-order effect). Switching all relation indexes to partial is a separate, broader change. - **CONCURRENTLY operator caveat.** If a CONCURRENTLY build is interrupted (kill, connection drop, OOM), Postgres leaves the index as INVALID. We deliberately don't probe `pg_index` for invalid leftovers on every create — catalog-table queries can be slow at multi-tenant scale and the failure mode is rare. Recovery is manual: `DROP INDEX ` and re-run the backfill. - **Forward-fix is not gated** behind a feature flag. The change is metadata-pipeline-internal; before, custom-object creation silently produced a degraded state. After, it produces the correct state. No new public API, no behavioural change for end users besides the indexes existing. ## Risk - Forward-fix: changes only the metadata produced during custom-object creation. New objects get four extra `FlatIndexMetadata` rows and four extra `CREATE INDEX` statements during their creation migration. Tables are empty at that point so the index builds in microseconds. - Helper change: API-compatible, default behavior unchanged. The new `concurrently` parameter is optional. - Backfill: read-only state probe → CONCURRENTLY index creation (no write blocking) → metadata insert via the normal migration pipeline. Idempotent. Reverting is `DROP INDEX`. ## Test plan - [ ] Verify forward-fix: create a custom object, confirm four new BTREE indexes appear on `timelineActivity`, `attachment`, `noteTarget`, `taskTarget` for the new `targetId` columns, and that `flatIndexMaps` has matching entries. - [ ] Verify backfill on a workspace that had custom objects created before the fix: run `--dry-run` first, confirm the expected indexes are listed; then run for real, confirm the indexes appear in pg (and as `indisvalid = true` in `pg_index`) and in `flatIndexMaps`. Re-run; confirm no-op. - [ ] Verify backfill on a clean workspace: should log "no missing indexes" and exit. - [ ] Verify CONCURRENTLY behavior under load: run backfill against a workspace with active writes on `timelineActivity`; confirm inserts/updates keep working during index build (no `ShareLock` waits in `pg_stat_activity`). - [ ] On the affected reporter-scale workspace, confirm `EXPLAIN ANALYZE` switches from sequential scan to index scan and timeline activity timeouts go away. --- .../2-8/2-8-upgrade-version-command.module.ts | 20 + ...ll-relation-join-column-indexes.command.ts | 225 ++++ .../workspace-command-provider.module.ts | 2 + ...and-flat-field-metadatas-to-create.util.ts | 8 +- ...-to-flat-field-metadatas-to-delete.util.ts | 9 +- ...-field-metadatas-for-custom-object.util.ts | 9 +- .../workspace-schema-manager.exception.ts | 5 + .../workspace-schema-index-manager.service.ts | 17 +- ...lder-graphql-api-exception-handler.util.ts | 4 +- .../index/utils/index-action-handler.utils.ts | 3 + ...morph-relation-v2.integration-spec.ts.snap | 4 +- ...morph-relation-v2.integration-spec.ts.snap | 4 +- ...relation-creation.integration-spec.ts.snap | 12 +- ...bject-metadata-v2.integration-spec.ts.snap | 1050 ++++++++++++++++- 14 files changed, 1310 insertions(+), 62 deletions(-) create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-upgrade-version-command.module.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-upgrade-version-command.module.ts new file mode 100644 index 0000000000..e464b224ef --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-upgrade-version-command.module.ts @@ -0,0 +1,20 @@ +import { Module } from '@nestjs/common'; + +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; +import { BackfillRelationJoinColumnIndexesCommand } from 'src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command'; +import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; +import { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.module'; +import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; +import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; + +@Module({ + imports: [ + ApplicationModule, + WorkspaceCacheModule, + WorkspaceIteratorModule, + WorkspaceMigrationModule, + WorkspaceSchemaManagerModule, + ], + providers: [BackfillRelationJoinColumnIndexesCommand], +}) +export class V2_8_UpgradeVersionCommandModule {} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts new file mode 100644 index 0000000000..fc65c1ee78 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-8/2-8-workspace-command-1798100000000-backfill-relation-join-column-indexes.command.ts @@ -0,0 +1,225 @@ +import { Command } from 'nest-commander'; +import { DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS } from 'twenty-shared/metadata'; +import { RelationType } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; + +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { ApplicationService } from 'src/engine/core-modules/application/application.service'; +import { RegisteredWorkspaceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-workspace-command.decorator'; +import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util'; +import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; +import { generateIndexForFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/generate-index-for-flat-field-metadata.util'; +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 { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; +import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util'; +import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; + +const POLYMORPHIC_STANDARD_OBJECT_NAMES_SINGULAR: ReadonlySet = new Set( + DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS, +); + +@RegisteredWorkspaceCommand('2.8.0', 1798100000000) +@Command({ + name: 'upgrade:2-8:backfill-relation-join-column-indexes', + description: + 'Backfill missing BTREE indexes on targetId join columns added to polymorphic standard objects (timelineActivity, attachment, noteTarget, taskTarget) when custom objects were created before the auto-index fix. Indexes are created with CONCURRENTLY so writes are not blocked.', +}) +export class BackfillRelationJoinColumnIndexesCommand extends ActiveOrSuspendedWorkspaceCommandRunner { + constructor( + protected readonly workspaceIteratorService: WorkspaceIteratorService, + private readonly applicationService: ApplicationService, + private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, + private readonly workspaceCacheService: WorkspaceCacheService, + private readonly workspaceSchemaManagerService: WorkspaceSchemaManagerService, + ) { + super(workspaceIteratorService); + } + + override async runOnWorkspace({ + workspaceId, + dataSource, + options, + }: RunOnWorkspaceArgs): Promise { + const isDryRun = options.dryRun ?? false; + + if (!dataSource) { + this.logger.log(`No data source for workspace ${workspaceId}, skipping`); + + return; + } + + const { flatObjectMetadataMaps, flatFieldMetadataMaps, flatIndexMaps } = + await this.workspaceCacheService.getOrRecompute(workspaceId, [ + 'flatObjectMetadataMaps', + 'flatFieldMetadataMaps', + 'flatIndexMaps', + ]); + + const polymorphicStandardObjectIds = new Set( + Object.values(flatObjectMetadataMaps.byUniversalIdentifier) + .filter(isDefined) + .filter((flatObject) => + POLYMORPHIC_STANDARD_OBJECT_NAMES_SINGULAR.has( + flatObject.nameSingular, + ), + ) + .map((flatObject) => flatObject.id), + ); + + if (polymorphicStandardObjectIds.size === 0) { + this.logger.log( + `No polymorphic standard objects found for workspace ${workspaceId}, skipping`, + ); + + return; + } + + const indexedFieldIds = new Set(); + + for (const flatIndex of Object.values(flatIndexMaps.byUniversalIdentifier)) { + if (!isDefined(flatIndex)) { + continue; + } + + for (const indexField of flatIndex.flatIndexFieldMetadatas) { + indexedFieldIds.add(indexField.fieldMetadataId); + } + } + + const fieldsNeedingIndex = Object.values( + flatFieldMetadataMaps.byUniversalIdentifier, + ) + .filter(isDefined) + .filter(isMorphOrRelationFlatFieldMetadata) + .filter((flatField) => + polymorphicStandardObjectIds.has(flatField.objectMetadataId), + ) + .filter( + (flatField) => + flatField.settings?.relationType === RelationType.MANY_TO_ONE, + ) + .filter((flatField) => !indexedFieldIds.has(flatField.id)); + + if (fieldsNeedingIndex.length === 0) { + this.logger.log( + `No missing relation join column indexes for workspace ${workspaceId}, skipping`, + ); + + return; + } + + const flatIndexBuildPlans = fieldsNeedingIndex.map((flatField) => { + const flatObjectMetadata = + findFlatEntityByIdInFlatEntityMapsOrThrow({ + flatEntityId: flatField.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); + + const universalFlatIndexMetadata = generateIndexForFlatFieldMetadata({ + flatFieldMetadata: flatField, + flatObjectMetadata, + }); + + const joinColumnName = computeMorphOrRelationFieldJoinColumnName({ + name: flatField.name, + }); + + return { + flatObjectMetadata, + universalFlatIndexMetadata, + joinColumnName, + }; + }); + + this.logger.log( + `${isDryRun ? '[DRY RUN] ' : ''}Found ${flatIndexBuildPlans.length} missing relation join column index(es) for workspace ${workspaceId}: ${flatIndexBuildPlans.map(({ universalFlatIndexMetadata }) => universalFlatIndexMetadata.name).join(', ')}`, + ); + + if (isDryRun) { + return; + } + + const queryRunner = dataSource.createQueryRunner(); + let isQueryRunnerConnected = false; + + try { + await queryRunner.connect(); + isQueryRunnerConnected = true; + + for (const { + flatObjectMetadata, + universalFlatIndexMetadata, + joinColumnName, + } of flatIndexBuildPlans) { + const { schemaName, tableName } = getWorkspaceSchemaContextForMigration({ + workspaceId, + objectMetadata: flatObjectMetadata, + }); + + await this.workspaceSchemaManagerService.indexManager.createIndex({ + queryRunner, + schemaName, + tableName, + index: { + name: universalFlatIndexMetadata.name, + columns: [joinColumnName], + isUnique: universalFlatIndexMetadata.isUnique, + type: universalFlatIndexMetadata.indexType, + where: universalFlatIndexMetadata.indexWhereClause ?? undefined, + }, + concurrently: true, + }); + + this.logger.log( + `Created index ${universalFlatIndexMetadata.name} on workspace ${workspaceId}`, + ); + } + } finally { + if (isQueryRunnerConnected) { + await queryRunner.release(); + } + } + + const { twentyStandardFlatApplication } = + await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( + { workspaceId }, + ); + + const validateAndBuildResult = + await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( + { + isSystemBuild: true, + allFlatEntityOperationByMetadataName: { + index: { + flatEntityToCreate: flatIndexBuildPlans.map( + ({ universalFlatIndexMetadata }) => universalFlatIndexMetadata, + ), + flatEntityToDelete: [], + flatEntityToUpdate: [], + }, + }, + workspaceId, + applicationUniversalIdentifier: + twentyStandardFlatApplication.universalIdentifier, + }, + ); + + if (validateAndBuildResult.status === 'fail') { + this.logger.error( + `Failed to persist relation join column index metadata:\n${JSON.stringify(validateAndBuildResult, null, 2)}`, + ); + + throw new Error( + `Failed to persist relation join column index metadata for workspace ${workspaceId}`, + ); + } + + this.logger.log( + `Successfully backfilled ${flatIndexBuildPlans.length} relation join column index(es) for workspace ${workspaceId}`, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/workspace-command-provider.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/workspace-command-provider.module.ts index b73d3108f9..8181d62cc2 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/workspace-command-provider.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/workspace-command-provider.module.ts @@ -10,6 +10,7 @@ import { V2_3_UpgradeVersionCommandModule } from 'src/database/commands/upgrade- import { V2_4_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-4/2-4-upgrade-version-command.module'; import { V2_5_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-5/2-5-upgrade-version-command.module'; import { V2_7_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-7/2-7-upgrade-version-command.module'; +import { V2_8_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-8/2-8-upgrade-version-command.module'; @Module({ imports: [ @@ -23,6 +24,7 @@ import { V2_7_UpgradeVersionCommandModule } from 'src/database/commands/upgrade- V2_4_UpgradeVersionCommandModule, V2_5_UpgradeVersionCommandModule, V2_7_UpgradeVersionCommandModule, + V2_8_UpgradeVersionCommandModule, ], }) export class WorkspaceCommandProviderModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts index 9f2af66004..bb11907d93 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts @@ -101,6 +101,7 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre const { standardSourceFlatFieldMetadatas, standardTargetFlatFieldMetadatas, + standardTargetFlatIndexMetadatas, } = buildDefaultRelationFlatFieldMetadatasForCustomObject({ existingFlatObjectMetadataMaps, sourceFlatObjectMetadata: universalFlatObjectMetadataToCreate, @@ -120,9 +121,10 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre return { flatObjectMetadataToCreate: universalFlatObjectMetadataToCreate, - flatIndexMetadataToCreate: Object.values( - defaultIndexesForCustomObject.indexes, - ), + flatIndexMetadataToCreate: [ + ...Object.values(defaultIndexesForCustomObject.indexes), + ...standardTargetFlatIndexMetadatas, + ], relationTargetFlatFieldMetadataToCreate: standardTargetFlatFieldMetadatas, flatFieldMetadataToCreateOnObject: objectFlatFieldMetadatas, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts index 4052b62c2d..fba3ea96f2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts @@ -77,13 +77,20 @@ export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({ }, ); + const fieldIdsToDelete = new Set( + flatFieldMetadatasToDelete.map((flatField) => flatField.id), + ); + // TODO We should maintain a idsByObjectMetadataId in the flatIndexMaps const flatIndexMetadataToDelete = Object.values( flatIndexMaps.byUniversalIdentifier, ).filter( (flatIndex): flatIndex is FlatIndexMetadata => isDefined(flatIndex) && - flatIndex.objectMetadataId === flatObjectMetadataToDelete.id, + (flatIndex.objectMetadataId === flatObjectMetadataToDelete.id || + flatIndex.flatIndexFieldMetadatas.some((flatIndexField) => + fieldIdsToDelete.has(flatIndexField.fieldMetadataId), + )), ); return { diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts index 0a0f3841d0..2d92136476 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts @@ -19,6 +19,7 @@ import { } from 'src/engine/metadata-modules/object-metadata/object-metadata.exception'; import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-migration/constant/standard-object-icons'; import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type'; +import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type'; import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type'; const morphIdByRelationObjectNameSingular = { @@ -41,11 +42,13 @@ export type BuildDefaultRelationFieldsForCustomObjectArgs = { type SourceAndTargetFlatFieldMetadatasRecord = { standardSourceFlatFieldMetadatas: UniversalFlatFieldMetadata[]; standardTargetFlatFieldMetadatas: UniversalFlatFieldMetadata[]; + standardTargetFlatIndexMetadatas: UniversalFlatIndexMetadata[]; }; const EMPTY_SOURCE_AND_TARGET_FLAT_FIELD_METADATAS_RECORD: SourceAndTargetFlatFieldMetadatasRecord = { standardSourceFlatFieldMetadatas: [], standardTargetFlatFieldMetadatas: [], + standardTargetFlatIndexMetadatas: [], }; export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({ @@ -107,7 +110,7 @@ export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({ const morphId = morphIdByRelationObjectNameSingular[objectMetadataNameSingular]; - const { flatFieldMetadatas } = + const { flatFieldMetadatas, indexMetadatas } = generateMorphOrRelationFlatFieldMetadataPair({ sourceFlatObjectMetadata, targetFlatObjectMetadata, @@ -144,6 +147,10 @@ export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({ ...sourceAndTargetFlatFieldMetadatasRecord.standardTargetFlatFieldMetadatas, flatFieldMetadatas[1], ], + standardTargetFlatIndexMetadatas: [ + ...sourceAndTargetFlatFieldMetadatasRecord.standardTargetFlatIndexMetadatas, + ...indexMetadatas, + ], }; }, EMPTY_SOURCE_AND_TARGET_FLAT_FIELD_METADATAS_RECORD, diff --git a/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/exceptions/workspace-schema-manager.exception.ts b/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/exceptions/workspace-schema-manager.exception.ts index eda234bfa5..b47c18f39b 100644 --- a/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/exceptions/workspace-schema-manager.exception.ts +++ b/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/exceptions/workspace-schema-manager.exception.ts @@ -1,4 +1,5 @@ import { type MessageDescriptor } from '@lingui/core'; +import { msg } from '@lingui/core/macro'; import { assertUnreachable } from 'twenty-shared/utils'; import { STANDARD_ERROR_MESSAGE } from 'src/engine/api/common/common-query-runners/errors/standard-error-message.constant'; @@ -9,12 +10,16 @@ import { export const WorkspaceSchemaManagerExceptionCode = appendCommonExceptionCode({ ENUM_OPERATION_FAILED: 'ENUM_OPERATION_FAILED', + CONCURRENT_INDEX_CREATION_IN_TRANSACTION: + 'CONCURRENT_INDEX_CREATION_IN_TRANSACTION', } as const); const getWorkspaceSchemaManagerExceptionUserFriendlyMessage = ( code: keyof typeof WorkspaceSchemaManagerExceptionCode, ) => { switch (code) { + case WorkspaceSchemaManagerExceptionCode.CONCURRENT_INDEX_CREATION_IN_TRANSACTION: + return msg`Could not create the index because it must run outside a database transaction.`; case WorkspaceSchemaManagerExceptionCode.ENUM_OPERATION_FAILED: case WorkspaceSchemaManagerExceptionCode.INTERNAL_SERVER_ERROR: return STANDARD_ERROR_MESSAGE; diff --git a/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/services/workspace-schema-index-manager.service.ts b/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/services/workspace-schema-index-manager.service.ts index b81cd5f454..528018aec2 100644 --- a/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/services/workspace-schema-index-manager.service.ts +++ b/packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/services/workspace-schema-index-manager.service.ts @@ -1,5 +1,9 @@ import { type QueryRunner } from 'typeorm'; +import { + WorkspaceSchemaManagerException, + WorkspaceSchemaManagerExceptionCode, +} from 'src/engine/twenty-orm/workspace-schema-manager/exceptions/workspace-schema-manager.exception'; import { type WorkspaceSchemaIndexDefinition } from 'src/engine/twenty-orm/workspace-schema-manager/types/workspace-schema-index-definition.type'; import { escapeIdentifier } from 'src/engine/workspace-manager/workspace-migration/utils/remove-sql-injection.util'; import { validateAndReturnIndexWhereClause } from 'src/engine/workspace-manager/workspace-migration/utils/validate-index-where-clause.util'; @@ -19,12 +23,21 @@ export class WorkspaceSchemaIndexManagerService { schemaName, tableName, index, + concurrently = false, }: { queryRunner: QueryRunner; schemaName: string; tableName: string; index: WorkspaceSchemaIndexDefinition; + concurrently?: boolean; }): Promise { + if (concurrently && queryRunner.isTransactionActive) { + throw new WorkspaceSchemaManagerException( + 'CREATE INDEX CONCURRENTLY cannot run inside a transaction block. Pass a QueryRunner with no active transaction.', + WorkspaceSchemaManagerExceptionCode.CONCURRENT_INDEX_CREATION_IN_TRANSACTION, + ); + } + const quotedColumns = index.columns.map((column) => escapeIdentifier(column), ); @@ -47,7 +60,9 @@ export class WorkspaceSchemaIndexManagerService { const sql = [ 'CREATE', isUnique && 'UNIQUE', - 'INDEX IF NOT EXISTS', + 'INDEX', + concurrently && 'CONCURRENTLY', + 'IF NOT EXISTS', escapeIdentifier(index.name), 'ON', `${escapeIdentifier(schemaName)}.${escapeIdentifier(tableName)}`, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util.ts index 82519ec278..3d50477394 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util.ts @@ -1,6 +1,8 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; import { isDefined } from 'twenty-shared/utils'; +import { plural } from 'pluralize'; + import { BaseGraphQLError, ErrorCode, @@ -23,7 +25,7 @@ export const workspaceMigrationBuilderGraphqlApiExceptionHandler = ( return []; } - return [`${count} ${metadataName}${count > 1 ? 's' : ''}`]; + return [`${count} ${count === 1 ? metadataName : plural(metadataName)}`]; }) .join(', ')}`; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils.ts index 2aa38e9a31..dce026136a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils.ts @@ -106,6 +106,7 @@ export const createIndexInWorkspaceSchema = async ({ workspaceSchemaManagerService, queryRunner, workspaceId, + concurrently = false, }: { flatIndexMetadata: FlatIndexMetadata; flatObjectMetadata: FlatObjectMetadata; @@ -113,6 +114,7 @@ export const createIndexInWorkspaceSchema = async ({ workspaceSchemaManagerService: WorkspaceSchemaManagerService; queryRunner: QueryRunner; workspaceId: string; + concurrently?: boolean; }): Promise => { const { schemaName, tableName } = getWorkspaceSchemaContextForMigration({ workspaceId, @@ -135,6 +137,7 @@ export const createIndexInWorkspaceSchema = async ({ queryRunner, schemaName, tableName, + concurrently, }); }; diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-add-one-target-to-metadata-morph-relation-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-add-one-target-to-metadata-morph-relation-v2.integration-spec.ts.snap index 803b86e1a4..4ddeb1519d 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-add-one-target-to-metadata-morph-relation-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-add-one-target-to-metadata-morph-relation-v2.integration-spec.ts.snap @@ -72,7 +72,7 @@ exports[`updateOne FieldMetadataService morph relation fields v2 - Add one targe }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, @@ -145,7 +145,7 @@ exports[`updateOne FieldMetadataService morph relation fields v2 - Add one targe }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap index 597da41c2e..f1c0eaa3b9 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap @@ -78,7 +78,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 Morh re }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 2 indexs", + "message": "Validation failed for 2 fieldMetadata, 2 indices", "summary": { "fieldMetadata": 2, "index": 2, @@ -189,7 +189,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap index 1d8fc45a05..69aefd7883 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap @@ -422,7 +422,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE when }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, @@ -576,7 +576,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE when }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, @@ -1165,7 +1165,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY when }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, @@ -1325,7 +1325,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY when }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, @@ -1537,7 +1537,7 @@ exports[`Field metadata relation creation should fail should fail when creating }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, @@ -1611,7 +1611,7 @@ exports[`Field metadata relation creation should fail should fail when creating }, ], }, - "message": "Validation failed for 2 fieldMetadatas, 1 index", + "message": "Validation failed for 2 fieldMetadata, 1 index", "summary": { "fieldMetadata": 2, "index": 1, diff --git a/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap index 9f07aef552..0ef26bfb1a 100644 --- a/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap @@ -318,6 +318,70 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -469,12 +533,12 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -803,6 +867,70 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -954,12 +1082,12 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -1299,6 +1427,70 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -1450,12 +1642,12 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -1784,6 +1976,70 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -1935,12 +2191,12 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -2304,6 +2560,70 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_324a6d52c1895ce5305d1024380", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_c272fd92a23a4d7923264fb6276", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_7769cef7ef7aec094d87acb12ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_72ed42f723f974934ee84669ebb", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -2455,12 +2775,12 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -2789,6 +3109,70 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -2940,12 +3324,12 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -3274,6 +3658,70 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -3425,12 +3873,12 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -3770,6 +4218,70 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_fd5becdd844da5d29aa3705b8e3", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_9b4339dd5677a5839c08b19c4ad", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_520fabad85767ae5f80c5d7486c", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_038c6e5f7bda7e0a15d47989333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -3921,12 +4433,12 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -4279,6 +4791,70 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_029b9dd75360ba7da1ab4c0747b", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_aaae895f506fa1661852dc9bf42", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_64634990b31740604eb47f703ce", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_a0e64f0f4efa7059b311181c2eb", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -4430,12 +5006,12 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -4764,6 +5340,70 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_1f9aa49970136caad8d2935d30d", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_d43a2090e820ec715f7d8e2853a", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_8a36a2e34ae674a43fca10bd5a5", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_804fa1028c77560a9e82b557bda", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -4921,12 +5561,12 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -5279,6 +5919,70 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_ea15d00c9266152973b76ab33e9", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_644c63c5b3d46c7bba9de898a3a", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_1064f768e233a3e317f760b3486", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_b82ff441b1c2b619214fb9718f4", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -5430,12 +6134,12 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -5764,6 +6468,70 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_bb8bb48f49adfc8cc47d1ded24f", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_06a2b62da335c351776f5df92af", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_02ca06f9107bb17c7a8ceba1e07", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_7a687aeb69dbe2488c590aac1bb", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -5915,12 +6683,12 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -6284,6 +7052,70 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_98de50499d6abf5fab56bb06f0a", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_de3e2c9dbdd952a934092748f50", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_c1e7e3e2ff4b6d4ccd2a1c10333", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_ac5c0d87a928495b3b34725f6cc", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -6435,12 +7267,12 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -6769,6 +7601,70 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] = "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_5190f0afa7bbe895b940e4e0607", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_1165ad738587910a93c6d8046f4", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_89c3e265f897fec9ccdcb952c8a", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_8af4de4e98c2999f29d8fda679e", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -6920,12 +7816,12 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] = }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, }, @@ -7254,6 +8150,70 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res "status": "fail", "type": "create", }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_5190f0afa7bbe895b940e4e0607", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_1165ad738587910a93c6d8046f4", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_89c3e265f897fec9ccdcb952c8a", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, + { + "errors": [ + { + "code": "INDEX_FIELD_NOT_FOUND", + "message": "Could not find index field related field metadata", + "userFriendlyMessage": "Field referenced in index does not exist", + }, + ], + "flatEntityMinimalInformation": { + "name": "IDX_8af4de4e98c2999f29d8fda679e", + "universalIdentifier": Any, + }, + "metadataName": "index", + "status": "fail", + "type": "create", + }, ], "objectMetadata": [ { @@ -7405,12 +8365,12 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res }, ], }, - "message": "Validation failed for 17 fieldMetadatas, 1 objectMetadata, 1 view, 5 viewFields, 1 index", + "message": "Validation failed for 17 fieldMetadata, 1 objectMetadata, 1 view, 5 viewFields, 5 indices", "summary": { "fieldMetadata": 17, - "index": 1, + "index": 5, "objectMetadata": 1, - "totalErrors": 25, + "totalErrors": 29, "view": 1, "viewField": 5, },