Fix 2.16 search field metadata cross version upgrade (#22039)

# Introduction
Allow decorating at class scope the properties introduced in specific
upgrade command
```
@WasIntroducedInUpgrade({
  upgradeCommandName:
    ADD_UNIVERSAL_IDENTIFIER_AND_APPLICATION_ID_TO_SEARCH_FIELD_METADATA_UPGRADE_COMMAND_NAME,
  properties: ['universalIdentifier', 'applicationId', 'position'],
})
``` 

Here the search field metadata has been created as it without extending
the syncableEntity a previous PR I've created now extends it, but
nothing has been protected the fact they're not decorated. Also having
to re-declare the properties would be redundant to me

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22039?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Paul Rastoin
2026-06-23 18:51:07 +02:00
committed by GitHub
parent b7350eba46
commit b768441c13
8 changed files with 328 additions and 7 deletions
@@ -4,8 +4,8 @@ import { InjectDataSource } from '@nestjs/typeorm';
import { type ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
import { type EntityMetadata } from 'typeorm/metadata/EntityMetadata';
import { DataSource } from 'typeorm';
import { isDefined } from 'twenty-shared/utils';
import { DataSource } from 'typeorm';
import { UpgradeMigrationService } from 'src/engine/core-modules/upgrade/services/upgrade-migration.service';
import { UpgradeSequenceReaderService } from 'src/engine/core-modules/upgrade/services/upgrade-sequence-reader.service';
@@ -346,13 +346,28 @@ export class UpgradeAwareEntityMetadataAdapter implements OnModuleInit {
}
private validateDecoratorsAgainstSequence(): void {
const entityClasses = this.coreDataSource.entityMetadatas
.map((metadata) => metadata.target)
.filter((target): target is Function => typeof target === 'function');
const entityClasses: Function[] = [];
const columnPropertyNamesByEntityClass = new Map<
Function,
ReadonlySet<string>
>();
for (const metadata of this.coreDataSource.entityMetadatas) {
if (typeof metadata.target !== 'function') {
continue;
}
entityClasses.push(metadata.target);
columnPropertyNamesByEntityClass.set(
metadata.target,
new Set(metadata.columns.map((column) => column.propertyName)),
);
}
const problems = validateUpgradeAwareEntityDecorators({
entityClasses,
stepNameToIndex: this.stepNameToIndex,
columnPropertyNamesByEntityClass,
});
if (problems.length === 0) {