Solo transaction application synchronization service refactor (#17864)

# Introduction
Refactoring the application sync service to be making a single validate
build and run transaction instead of calling all the services n times
thanks to the universal workspace migration refactor that allow doing so

## What's next
Migrating all below entities to by syncableEntities so they can be
universalised too ( right now they're still calling the services n times
and won't be returned in the workspace migration )
-
[objectPermission](https://github.com/twentyhq/core-team-issues/issues/2223)
-
[fieldPermission](https://github.com/twentyhq/core-team-issues/issues/2224)
-
[permissionFlag](https://github.com/twentyhq/core-team-issues/issues/2225)
This commit is contained in:
Paul Rastoin
2026-02-11 17:30:01 +01:00
committed by GitHub
parent 0ee63a0525
commit b2f7c745f8
27 changed files with 848 additions and 1127 deletions
@@ -1,17 +1,16 @@
import {
type FieldMetadataType,
type FieldMetadataSettings,
type FieldMetadataOptions,
type FieldMetadataDefaultValue,
} from '@/types';
import { type SyncableEntityOptions } from '@/application/syncableEntityOptionsType';
import { type RelationOnDeleteAction } from '@/types/RelationOnDeleteAction.type';
import { type RelationType } from '@/types/RelationType';
import {
type FieldMetadataDefaultValue,
type FieldMetadataOptions,
type FieldMetadataType,
type FieldMetadataUniversalSettings,
type RelationAndMorphRelationFieldMetadataType,
} from '@/types';
export type RegularFieldManifest<
T extends FieldMetadataType = Exclude<
FieldMetadataType,
FieldMetadataType.RELATION
RelationAndMorphRelationFieldMetadataType
>,
> = SyncableEntityOptions & {
type: T;
@@ -21,23 +20,24 @@ export type RegularFieldManifest<
icon?: string;
defaultValue?: FieldMetadataDefaultValue<T>;
options?: FieldMetadataOptions<T>;
settings?: FieldMetadataSettings<T>;
universalSettings?: FieldMetadataUniversalSettings<T>;
isNullable?: boolean;
objectUniversalIdentifier: string;
};
export type RelationFieldManifest =
RegularFieldManifest<FieldMetadataType.RELATION> & {
relationType: RelationType;
targetObjectUniversalIdentifier: string;
targetFieldLabel: string;
targetFieldIcon?: string;
onDelete?: RelationOnDeleteAction;
};
// Both sides of a relation must be declared explicitly in the manifest.
// Relation-specific universal settings (relationType, onDelete, joinColumnName)
// are provided through the `universalSettings` field.
export type RelationFieldManifest<
T extends RelationAndMorphRelationFieldMetadataType = RelationAndMorphRelationFieldMetadataType,
> = RegularFieldManifest<T> & {
relationTargetFieldMetadataUniversalIdentifier: string;
relationTargetObjectMetadataUniversalIdentifier: string;
};
export type FieldManifest<
T extends FieldMetadataType = Exclude<
FieldMetadataType,
FieldMetadataType.RELATION
RelationAndMorphRelationFieldMetadataType
>,
> = RegularFieldManifest<T> | RelationFieldManifest;
@@ -36,5 +36,9 @@ export type {
export type { Manifest } from './manifestType';
export type { ObjectFieldManifest } from './objectFieldManifest.type';
export type { ObjectManifest } from './objectManifestType';
export type { RoleManifest } from './roleManifestType';
export type {
ObjectPermissionManifest,
FieldPermissionManifest,
RoleManifest,
} from './roleManifestType';
export type { SyncableEntityOptions } from './syncableEntityOptionsType';
@@ -1,7 +1,7 @@
import { type PermissionFlagType } from '@/constants';
import { type SyncableEntityOptions } from '@/application/syncableEntityOptionsType';
type ObjectPermission = {
export type ObjectPermissionManifest = {
objectUniversalIdentifier: string;
canReadObjectRecords?: boolean;
canUpdateObjectRecords?: boolean;
@@ -9,7 +9,7 @@ type ObjectPermission = {
canDestroyObjectRecords?: boolean;
};
type FieldPermission = {
export type FieldPermissionManifest = {
objectUniversalIdentifier: string;
fieldUniversalIdentifier: string;
canReadFieldValue?: boolean;
@@ -29,7 +29,7 @@ export type RoleManifest = SyncableEntityOptions & {
canBeAssignedToUsers?: boolean;
canBeAssignedToAgents?: boolean;
canBeAssignedToApiKeys?: boolean;
objectPermissions?: ObjectPermission[];
fieldPermissions?: FieldPermission[];
objectPermissions?: ObjectPermissionManifest[];
fieldPermissions?: FieldPermissionManifest[];
permissionFlags?: PermissionFlagType[];
};