Identify standard field do deploy until IS_WORKSPACE_CREATION_V2_ENABLED is enabled in prod (#16981)

# Introduction

fixes https://github.com/twentyhq/twenty/issues/16905

Do not merge until `IS_WORKSPACE_CREATION_V2_ENABLED` has been activated
by default, and so sync metadata has been deprecated by doing so. As the
sync metadata will attempt to insert `null` `applicationId` and
`universalIdentifier` values while creating a workspace

In this PR we're introducing a new `SyncableEntityRequired` which
enforces the non nullable `applicationId` and `universalIdentifier` on
extending entity

In this PR we also migrate the field metadata entity to extend the
required

## Identification upgrade command
This command will search for workspace field metadata entities that
aren't associated to an applicationId, dispatch them to either the
workspace-custom `applicationId` or the twenty-standard `applicationId`.
For the standard entities it will also set their universal identifier
based on the `STANDARD_OBJECTS` const hashmap

## Typeorm migration
As the non nullable `applicationId` and `universalIdentifier`migration
won't pass in the first we've been using the save point and upgrade
command migration fallback pattern

## Tests
Tested the command on a prod extract locally

Both `twenty-eng` and `twenty-for-twenty` have unexpected standard
objects
Please note that we will deprecate the `isCustom` and `standardId` col
later in the future

### Twenty-eng
```ts
[Nest] 98971  - 01/01/2026, 3:18:00 PM     LOG [IdentifyStandardEntitiesCommand] Successfully validated 600/600 field metadata update(s) for workspace 9870323e-22c3-4d14-9b7f-5bdc84f7d6ee (309 custom, 291 standard)
[Nest] 98971  - 01/01/2026, 3:18:00 PM    WARN [IdentifyStandardEntitiesCommand] Found 35 warning(s) while processing field metadata for workspace 9870323e-22c3-4d14-9b7f-5bdc84f7d6ee. These fields will become custom.
```

### Twenty for twenty

### Just created workspace
This commit is contained in:
Paul Rastoin
2026-01-12 10:59:01 +01:00
committed by GitHub
parent 46e5420d20
commit a6f371a42a
13 changed files with 459 additions and 16 deletions
@@ -0,0 +1,22 @@
import { Column, Index, JoinColumn, ManyToOne, type Relation } from 'typeorm';
import type { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
@Index(['workspaceId', 'universalIdentifier'], {
unique: true,
})
export abstract class SyncableEntityRequired extends WorkspaceRelatedEntity {
@Column({ nullable: false, type: 'uuid' })
universalIdentifier: string;
@Column({ nullable: false, type: 'uuid' })
applicationId: string;
@ManyToOne('ApplicationEntity', {
onDelete: 'CASCADE',
nullable: false,
})
@JoinColumn({ name: 'applicationId' })
application: Relation<ApplicationEntity>;
}