[WHEN_RELEASED_REQUIRES_CACHE_FLUSH] Object related record logic in v2 (#14937)

# Introduction
Initial motivation here was to migrate the object related records logic
from v1 to v2, please note that now in v2 views aren't records anymore
but core engine entities

## What's done
- Added specific label identifier targeting view field logic
- Handled side effects on viewField creation with lowest position on
object label identifier mutation
- Added viewField relations in field metadate entity + handled
optimistic in builder v2
- Added view relations in object metadata entity + handled optimistic in
builder v2
- Added integration tests covering the side effects and new validation
exceptions
- Sandardized cache computation
- Coverage on object metadata creation side effect on views and view
fields

## Coverage
```ts
 PASS  test/integration/graphql/suites/view/view-field/object-identifier-update-side-effect-on-view-field.integration-spec.ts
  View Field Resolver - Successful object metadata identifier update side effect on view field
    ✓ should create a view field on label identifier object metadata update if it does not exist on view (7 ms)
    ✓ Should not allow deleting a label identifier view field (17 ms)
    ✓ Should not allow destroying a label identifier view field (6 ms)
    ✓ Should not allow updating a label identifier view field visibility to false (8 ms)
    ✓ Should not allow creating a view field with a position lower than the label idenfitier view field (180 ms)
    ✓ Should not allow updated labelIdentifier view field with a position higher than existing other view field (346 ms)
    ✓ Should allow updated labelIdentifier view field with a position higher than existing other view field (434 ms)

Test Suites: 1 passed, 1 total
Tests:       7 passed, 7 total
Snapshots:   5 passed, 5 total
Time:        4.571 s, estimated 5 s
```

close https://github.com/twentyhq/core-team-issues/issues/1664
This commit is contained in:
Paul Rastoin
2025-10-08 16:23:37 +02:00
committed by GitHub
parent 1c1739ec80
commit 4ecc9c622d
80 changed files with 6858 additions and 627 deletions
@@ -1,42 +0,0 @@
import { isDefined } from 'twenty-shared/utils';
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type CachedFieldMetadataEntity } from 'src/engine/metadata-modules/types/cached-field-metadata-entity';
import { type ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
export const getFieldMetadataEntityFromCachedObjectMetadataMaps = ({
fieldMetadataId,
objectMetadataId,
objectMetadataMaps,
}: {
objectMetadataMaps: ObjectMetadataMaps;
objectMetadataId: string;
fieldMetadataId: string;
}): FieldMetadataEntity | undefined => {
const objectMetadataFromCache = objectMetadataMaps.byId[objectMetadataId];
if (!isDefined(objectMetadataFromCache)) {
return undefined;
}
const fieldMetadataFromCache: CachedFieldMetadataEntity =
objectMetadataFromCache.fieldsById[fieldMetadataId];
if (!isDefined(fieldMetadataFromCache)) {
return undefined;
}
// We need to determine if graphql will be able to handle relations crafting byitself
return {
...fieldMetadataFromCache,
object: {} as ObjectMetadataEntity,
relationTargetFieldMetadata: null,
relationTargetObjectMetadata: null,
indexFieldMetadatas: {} as IndexFieldMetadataEntity,
fieldPermissions: [],
createdAt: new Date(fieldMetadataFromCache.createdAt),
updatedAt: new Date(fieldMetadataFromCache.updatedAt),
};
};