Refactor workspace migration update action (#17701)

# Introduction
Removing:
- `from` property from actions definition, as it's a legitimate source
of truth. The stored comparison might have been compromised since action
generation. If from is needed it should be computed from the optimistic
cache at runner lvl
- Removed the `FlatEntityPropertyUpdates` Array complexity in favor of

From
```ts
export type PropertyUpdate<T, P extends keyof T> = {
  property: P;
} & FromTo<T[P]>;
```

To
```ts
export type FlatEntityUpdate<T extends AllMetadataName> = Partial<
  Pick<
    MetadataFlatEntity<T>,
    Extract<FlatEntityPropertiesToCompare<T>, keyof MetadataFlatEntity<T>>
  >
>;
```

## New interactions
From
```ts
    const positionUpdate = findFlatEntityPropertyUpdate({
      flatEntityUpdates,
      property: 'position',
    });

    if (
      isDefined(positionUpdate) &&
      (!Number.isInteger(positionUpdate.to) || positionUpdate.to < 0)
    ) {


   const toFlatNavigationMenuItem = {
      ...fromFlatNavigationMenuItem,
      ...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
        updates: flatEntityUpdates,
      }),
    };
```

To
```ts
    const positionUpdate = flatEntityUpdate.position;
    if (
      isDefined(positionUpdate) &&
      (!Number.isInteger(positionUpdate) || positionUpdate < 0)
    ) {

    const toFlatNavigationMenuItem = {
      ...fromFlatNavigationMenuItem,
      ...flatEntityUpdate,
    };
```

## `SanitizeFlatEntityUpdate`
Enforcing the `flatEntityUpdate` to only contains comparable properties
per flat entity by striping out all unexpected keys
In the future we will also move the whole validation at runner lvl at
some point

```ts
export const sanitizeFlatEntityUpdate = <T extends AllMetadataName>({
  flatEntityUpdate,
  metadataName,
}: {
  flatEntityUpdate: FlatEntityUpdate<T>;
  metadataName: T;
}): FlatEntityUpdate<T> => {
  const { propertiesToCompare } =
    ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY[metadataName];

  const initialAccumulator: FlatEntityUpdate<T> = {};

  return propertiesToCompare.reduce((accumulator, property) => {
    const updatedValue =
      flatEntityUpdate[property as MetadataFlatEntityComparableProperties<T>];

    if (updatedValue === undefined) {
      return accumulator;
    }

    return {
      ...accumulator,
      [property]: updatedValue,
    };
  }, initialAccumulator);
};
```
This commit is contained in:
Paul Rastoin
2026-02-04 14:50:46 +01:00
committed by GitHub
parent b03e3772e6
commit 48c8fa6809
89 changed files with 813 additions and 800 deletions
@@ -11,7 +11,6 @@ import {
type FlatViewGroupsToDeleteUpdateAndCreate,
recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate,
} from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-view-groups-on-flat-field-metadata-options-update.util';
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
type HandleEnumFlatFieldMetadataOptionsUpdateSideEffectsArgs = FromTo<
FlatFieldMetadata<EnumFieldMetadataType>,
@@ -49,20 +48,14 @@ export const handleEnumFlatFieldMetadataUpdateSideEffects = ({
JSON.stringify(fromFlatFieldMetadata.options) !==
JSON.stringify(toFlatFieldMetadata.options)
) {
const optionsPropertyUpdate: PropertyUpdate<
FlatFieldMetadata<EnumFieldMetadataType>,
'options'
> = {
from: fromFlatFieldMetadata.options,
property: 'options',
to: toFlatFieldMetadata.options,
};
const optionsPropertyUpdate =
toFlatFieldMetadata.options as FlatFieldMetadata<EnumFieldMetadataType>['options'];
const { flatViewFiltersToDelete, flatViewFiltersToUpdate } =
recomputeViewFiltersOnFlatFieldMetadataOptionsUpdate({
flatViewFilterMaps,
fromFlatFieldMetadata,
update: optionsPropertyUpdate,
toOptions: optionsPropertyUpdate,
});
sideEffectResult.flatViewFiltersToDelete.push(...flatViewFiltersToDelete);
@@ -76,7 +69,7 @@ export const handleEnumFlatFieldMetadataUpdateSideEffects = ({
flatViewMaps,
flatViewGroupMaps,
fromFlatFieldMetadata,
update: optionsPropertyUpdate,
toOptions: optionsPropertyUpdate,
});
sideEffectResult.flatViewGroupsToCreate.push(...flatViewGroupsToCreate);
@@ -11,11 +11,10 @@ import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metada
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { compareTwoFlatFieldMetadataEnumOptions } from 'src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata-enum-options.util';
import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type';
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
type RecomputeViewFiltersOnFlatFieldMetadataOptionsUpdateArgs = {
fromFlatFieldMetadata: FlatFieldMetadata<EnumFieldMetadataType>;
update: PropertyUpdate<FlatFieldMetadata<EnumFieldMetadataType>, 'options'>;
toOptions: FlatFieldMetadata<EnumFieldMetadataType>['options'];
} & Pick<AllFlatEntityMaps, 'flatViewFilterMaps'>;
export type FlatViewFiltersToDeleteAndUpdate = {
@@ -25,7 +24,7 @@ export type FlatViewFiltersToDeleteAndUpdate = {
export const recomputeViewFiltersOnFlatFieldMetadataOptionsUpdate = ({
flatViewFilterMaps,
fromFlatFieldMetadata,
update,
toOptions,
}: RecomputeViewFiltersOnFlatFieldMetadataOptionsUpdateArgs): FlatViewFiltersToDeleteAndUpdate => {
const flatViewFiltersToCreateAndUpdate: FlatViewFiltersToDeleteAndUpdate = {
flatViewFiltersToDelete: [],
@@ -38,7 +37,7 @@ export const recomputeViewFiltersOnFlatFieldMetadataOptionsUpdate = ({
} = compareTwoFlatFieldMetadataEnumOptions({
compareLabel: false,
fromOptions: fromFlatFieldMetadata.options,
toOptions: update.to,
toOptions,
});
if (
@@ -13,11 +13,10 @@ import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-m
import { compareTwoFlatFieldMetadataEnumOptions } from 'src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata-enum-options.util';
import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type';
import { reduceFlatViewGroupsByViewId } from 'src/engine/metadata-modules/flat-view-group/utils/reduce-flat-view-groups-by-view-id.util';
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
type RecomputeViewGroupsOnFlatFieldMetadataOptionsUpdateArgs = {
fromFlatFieldMetadata: FlatFieldMetadata<EnumFieldMetadataType>;
update: PropertyUpdate<FlatFieldMetadata<EnumFieldMetadataType>, 'options'>;
toOptions: FlatFieldMetadata<EnumFieldMetadataType>['options'];
} & Pick<AllFlatEntityMaps, 'flatViewMaps' | 'flatViewGroupMaps'>;
export type FlatViewGroupsToDeleteUpdateAndCreate = {
@@ -29,7 +28,7 @@ export const recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate = ({
flatViewMaps,
flatViewGroupMaps,
fromFlatFieldMetadata,
update,
toOptions,
}: RecomputeViewGroupsOnFlatFieldMetadataOptionsUpdateArgs): FlatViewGroupsToDeleteUpdateAndCreate => {
const {
deleted: deletedFieldMetadataOptions,
@@ -38,7 +37,7 @@ export const recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate = ({
} = compareTwoFlatFieldMetadataEnumOptions({
compareLabel: false,
fromOptions: fromFlatFieldMetadata.options,
toOptions: update.to,
toOptions,
});
const flatViewsAffected = findManyFlatEntityByIdInFlatEntityMapsOrThrow({