Skip to content

Commit cb34f0d

Browse files
committed
fix(server): on field update synchronize updates to other relations members accordingly
1 parent 3353e66 commit cb34f0d

7 files changed

+310
-146
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
2+
3+
export const FLAT_FIELD_METADATA_MORPH_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_RELATION_UPDATE_CONSTANT =
4+
{
5+
custom: [
6+
'defaultValue',
7+
'description',
8+
'icon',
9+
'isActive',
10+
'isLabelSyncedWithName',
11+
'isUnique',
12+
'label',
13+
'options',
14+
],
15+
standard: [
16+
'defaultValue',
17+
'description',
18+
'icon',
19+
'isActive',
20+
'label',
21+
'options',
22+
],
23+
} as const satisfies Record<
24+
'standard' | 'custom',
25+
(keyof FlatFieldMetadata)[]
26+
>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
2+
3+
export const FLAT_FIELD_METADATA_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_OR_RELATION_UPDATE_CONSTANT =
4+
['isActive'] as const satisfies (keyof FlatFieldMetadata)[];

packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-metadata-related-flat-field-metadata.util.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ export const computeFlatFieldMetadataRelatedFlatFieldMetadata = ({
3333
FieldMetadataType.MORPH_RELATION,
3434
)
3535
) {
36-
return findFlatFieldMetadatasRelatedToMorphRelationOrThrow({
37-
flatFieldMetadata,
38-
flatFieldMetadataMaps,
39-
flatObjectMetadata,
40-
});
36+
const { morphRelationFlatFieldMetadatas, relationFlatFieldMetadatas } =
37+
findFlatFieldMetadatasRelatedToMorphRelationOrThrow({
38+
flatFieldMetadata,
39+
flatFieldMetadataMaps,
40+
flatObjectMetadata,
41+
});
42+
return [...morphRelationFlatFieldMetadatas, ...relationFlatFieldMetadatas];
4143
}
4244

4345
return [];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { type UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
2+
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
3+
import { FLAT_FIELD_METADATA_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-editable-properties.constant';
4+
import { FLAT_FIELD_METADATA_MORPH_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_RELATION_UPDATE_CONSTANT } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-morph-relation-editable-properties-on-sibling-morph-relation-update.constant';
5+
import { FLAT_FIELD_METADATA_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_OR_RELATION_UPDATE_CONSTANT } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-relation-editable-properties-on-sibling-morph-or-relation-update.constant';
6+
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
7+
import { findFlatFieldMetadatasRelatedToMorphRelationOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-flat-field-metadatas-related-to-morph-relation-or-throw.util';
8+
import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
9+
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
10+
import { sanitizeRawUpdateFieldInput } from 'src/engine/metadata-modules/flat-field-metadata/utils/sanitize-raw-update-field-input';
11+
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
12+
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
13+
import { mergeUpdateInExistingRecord } from 'src/utils/merge-update-in-existing-record.util';
14+
import { FieldMetadataType, FromTo } from 'twenty-shared/types';
15+
16+
type ComputeFlatFieldToUpdateAndRelatedFlatFieldToUpdateReturnType = {
17+
flatFieldMetadataFromTo: FromTo<FlatFieldMetadata, 'flatFieldMetadata'>;
18+
relatedFlatFieldMetadatasFromTo: FromTo<
19+
FlatFieldMetadata,
20+
'flatFieldMetadata'
21+
>[];
22+
};
23+
24+
type ComputeFlatFieldToUpdateAndRelatedFlatFieldToUpdateArgs = {
25+
rawUpdateFieldInput: UpdateFieldInput;
26+
fromFlatFieldMetadata: FlatFieldMetadata;
27+
flatObjectMetadata: FlatObjectMetadata;
28+
} & Pick<AllFlatEntityMaps, 'flatFieldMetadataMaps'>;
29+
// Note: Standard override is way too complex we should land a smoother implemenentation once we standardize
30+
// them across every flat entities
31+
export const computeFlatFieldToUpdateAndRelatedFlatFieldToUpdate = ({
32+
fromFlatFieldMetadata,
33+
rawUpdateFieldInput,
34+
flatFieldMetadataMaps,
35+
flatObjectMetadata,
36+
}: ComputeFlatFieldToUpdateAndRelatedFlatFieldToUpdateArgs): ComputeFlatFieldToUpdateAndRelatedFlatFieldToUpdateReturnType => {
37+
const { standardOverrides, updatedEditableFieldProperties } =
38+
sanitizeRawUpdateFieldInput({
39+
existingFlatFieldMetadata: fromFlatFieldMetadata,
40+
rawUpdateFieldInput,
41+
});
42+
43+
const isStandardField = isStandardMetadata(fromFlatFieldMetadata);
44+
45+
const toFlatFieldMetadata = {
46+
...mergeUpdateInExistingRecord({
47+
existing: fromFlatFieldMetadata,
48+
properties:
49+
FLAT_FIELD_METADATA_EDITABLE_PROPERTIES[
50+
isStandardField ? 'standard' : 'custom'
51+
],
52+
update: updatedEditableFieldProperties,
53+
}),
54+
standardOverrides,
55+
};
56+
57+
if (
58+
isFlatFieldMetadataOfType(fromFlatFieldMetadata, FieldMetadataType.RELATION)
59+
) {
60+
const relatedFlatFieldMetadataFrom =
61+
findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow({
62+
flatFieldMetadata: fromFlatFieldMetadata,
63+
flatFieldMetadataMaps,
64+
});
65+
66+
const relatedFlatFieldMetadataTo = mergeUpdateInExistingRecord({
67+
existing: relatedFlatFieldMetadataFrom as FlatFieldMetadata,
68+
properties:
69+
FLAT_FIELD_METADATA_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_OR_RELATION_UPDATE_CONSTANT,
70+
update: updatedEditableFieldProperties,
71+
});
72+
73+
return {
74+
flatFieldMetadataFromTo: {
75+
fromFlatFieldMetadata,
76+
toFlatFieldMetadata,
77+
},
78+
relatedFlatFieldMetadatasFromTo: [
79+
{
80+
fromFlatFieldMetadata: relatedFlatFieldMetadataFrom,
81+
toFlatFieldMetadata: relatedFlatFieldMetadataTo,
82+
},
83+
],
84+
};
85+
}
86+
87+
if (
88+
isFlatFieldMetadataOfType(
89+
fromFlatFieldMetadata,
90+
FieldMetadataType.MORPH_RELATION,
91+
)
92+
) {
93+
const { morphRelationFlatFieldMetadatas, relationFlatFieldMetadatas } =
94+
findFlatFieldMetadatasRelatedToMorphRelationOrThrow({
95+
flatFieldMetadata: fromFlatFieldMetadata,
96+
flatFieldMetadataMaps,
97+
flatObjectMetadata,
98+
});
99+
100+
const relatedMorphRelationFlatFieldMetdataTo =
101+
morphRelationFlatFieldMetadatas.map<
102+
FromTo<FlatFieldMetadata, 'flatFieldMetadata'>
103+
>((relatedFlatFieldMetadataFrom) => {
104+
const relatedMorphPropertiesToUpdateTo =
105+
FLAT_FIELD_METADATA_MORPH_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_RELATION_UPDATE_CONSTANT[
106+
isStandardField ? 'standard' : 'custom'
107+
];
108+
const relatedFlatFieldMetadataTo = {
109+
...mergeUpdateInExistingRecord({
110+
existing: relatedFlatFieldMetadataFrom as FlatFieldMetadata,
111+
properties: relatedMorphPropertiesToUpdateTo,
112+
update: updatedEditableFieldProperties,
113+
}),
114+
standardOverrides,
115+
};
116+
117+
return {
118+
fromFlatFieldMetadata: relatedFlatFieldMetadataFrom,
119+
toFlatFieldMetadata: relatedFlatFieldMetadataTo,
120+
};
121+
});
122+
123+
const relatedRelationFlatFieldMetadataTo = relationFlatFieldMetadatas.map<
124+
FromTo<FlatFieldMetadata, 'flatFieldMetadata'>
125+
>((relatedFlatFieldMetadataFrom) => {
126+
const relatedFlatFieldMetadataTo = mergeUpdateInExistingRecord({
127+
existing: relatedFlatFieldMetadataFrom as FlatFieldMetadata,
128+
properties:
129+
FLAT_FIELD_METADATA_RELATION_EDITABLE_PROPERTIES_ON_SIBLING_MORPH_OR_RELATION_UPDATE_CONSTANT,
130+
update: updatedEditableFieldProperties,
131+
});
132+
133+
return {
134+
fromFlatFieldMetadata: relatedFlatFieldMetadataFrom,
135+
toFlatFieldMetadata: relatedFlatFieldMetadataTo,
136+
};
137+
});
138+
139+
return {
140+
flatFieldMetadataFromTo: {
141+
fromFlatFieldMetadata,
142+
toFlatFieldMetadata,
143+
},
144+
relatedFlatFieldMetadatasFromTo: [
145+
...relatedMorphRelationFlatFieldMetdataTo,
146+
...relatedRelationFlatFieldMetadataTo,
147+
],
148+
};
149+
}
150+
151+
return {
152+
flatFieldMetadataFromTo: {
153+
fromFlatFieldMetadata,
154+
toFlatFieldMetadata,
155+
},
156+
relatedFlatFieldMetadatasFromTo: [],
157+
};
158+
};
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { type FieldMetadataType } from 'twenty-shared/types';
22

3-
import { type MorphOrRelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/morph-or-relation-field-metadata-type.type';
43
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
54
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
65
import { findAllOthersMorphRelationFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util';
@@ -12,32 +11,35 @@ export type FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs = {
1211
flatFieldMetadata: FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
1312
flatObjectMetadata: FlatObjectMetadata;
1413
};
14+
15+
type FindFlatFieldMetadatasRelatedToMorphRelationOrThrowReturnType = {
16+
morphRelationFlatFieldMetadatas: FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>[];
17+
relationFlatFieldMetadatas: FlatFieldMetadata<FieldMetadataType.RELATION>[];
18+
};
1519
export const findFlatFieldMetadatasRelatedToMorphRelationOrThrow = ({
1620
flatFieldMetadataMaps,
1721
flatFieldMetadata: morphRelationFlatFieldMetadata,
1822
flatObjectMetadata,
19-
}: FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs): FlatFieldMetadata<MorphOrRelationFieldMetadataType>[] => {
20-
const allMorphFlatFieldMetadatas =
23+
}: FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs): FindFlatFieldMetadatasRelatedToMorphRelationOrThrowReturnType => {
24+
const morphRelationFlatFieldMetadatas =
2125
findAllOthersMorphRelationFlatFieldMetadatasOrThrow({
2226
flatFieldMetadata: morphRelationFlatFieldMetadata,
2327
flatFieldMetadataMaps,
2428
flatObjectMetadata,
2529
});
2630

27-
return [
31+
const relationFlatFieldMetadatas = [
2832
morphRelationFlatFieldMetadata,
29-
...allMorphFlatFieldMetadatas,
30-
].flatMap((flatFieldMetadata) => {
31-
const relationTargetFlatFieldMetadata =
32-
findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow({
33-
flatFieldMetadata,
34-
flatFieldMetadataMaps,
35-
});
36-
37-
if (flatFieldMetadata.id === morphRelationFlatFieldMetadata.id) {
38-
return [relationTargetFlatFieldMetadata];
39-
}
33+
...morphRelationFlatFieldMetadatas,
34+
].map((flatFieldMetadata) =>
35+
findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow({
36+
flatFieldMetadata,
37+
flatFieldMetadataMaps,
38+
}),
39+
) as FlatFieldMetadata<FieldMetadataType.RELATION>[];
4040

41-
return [flatFieldMetadata, relationTargetFlatFieldMetadata];
42-
});
41+
return {
42+
morphRelationFlatFieldMetadatas,
43+
relationFlatFieldMetadatas,
44+
};
4345
};

0 commit comments

Comments
 (0)