
Paul RastoinandGitHub
5544b5dcfe
Fix and refactor all metadata relation (#17978)
# Introduction
The initial motivation was that in the workspace migration create action
some universal foreign key aggregators weren't correctly deleted before
returned due to constant missconfiguration
<img width="2300" height="972" alt="image"
src="https://github.com/user-attachments/assets/9401eb02-2bb2-4e69-9c5f-9a354ff61079"
/>
It also meant that under the hood some optimistic behavior wasn't
correctly rendered for some aggregators
## Solution
Refactored the `ALL_METADATA_RELATIONS` as follows:
This way we can infer the FK and transpile it to a universalFK, also the
aggregators are one to one instead of one versus all available
Making the only manual configuration to be defined the `foreignKey` and
`inverseOneToManyProperty`
```
┌──────────────────────────────────────┐ ┌─────────────────────────────────────────────┐
│ ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY│ │ ALL_ONE_TO_MANY_METADATA_RELATIONS │
│──────────────────────────────────────│ │─────────────────────────────────────────────│
│ Derived from: Entity types │ │ Derived from: Entity types │
│ │ │ │
│ Provides: │ │ Provides: │
│ • foreignKey │ │ • metadataName │
│ │ │ • flatEntityForeignKeyAggregator │
│ Standalone low-level primitive │ │ • universalFlatEntityForeignKeyAggregator │
└──────────────┬───────────────────────┘ └──────────────┬──────────────────────────────┘
│ │
│ foreignKey type + │ inverseOneToManyProperty
│ universalForeignKey derivation │ keys (type constraint)
│ │
▼ ▼
┌───────────────────────────────────────────────────────────────┐
│ ALL_MANY_TO_ONE_METADATA_RELATIONS │
│───────────────────────────────────────────────────────────────│
│ Derived from: │
│ • Entity types (metadataName, isNullable) │
│ • ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY (FK → universalFK) │
│ • ALL_ONE_TO_MANY_METADATA_RELATIONS (inverse keys) │
│ │
│ Provides: │
│ • metadataName │
│ • foreignKey (replicated from FK constant) │
│ • inverseOneToManyProperty │
│ • isNullable │
│ • universalForeignKey │
└──────────────────────────┬────────────────────────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌────────────────┐ ┌──────────────────────┐
│ Type consumers │ │ Atomic utils │ │ Optimistic utils │
│───────────────────│ │────────────────│ │──────────────────────│
│ • JoinColumn │ │ • resolve-* │ │ • add/delete flat │
│ • RelatedNames │ │ • get-* │ │ entity maps │
│ • UniversalFlat │ │ │ │ • add/delete │
│ EntityFrom │ │ │ │ universal flat │
│ │ │ │ │ entity maps │
└───────────────────┘ └────────────────┘ │ │
│ (bridge via │
│ inverseOneToMany │
│ Property → │
│ ONE_TO_MANY for │
│ aggregator lookup) │
└──────────────────────┘
```
### Previously
```
┌─────────────────────────────────────────────────────────────────────┐
│ ALL_METADATA_RELATIONS │
│─────────────────────────────────────────────────────────────────────│
│ Derived from: Entity types │
│ │
│ Structure: { [metadataName]: { manyToOne: {...}, oneToMany: {...},│
│ serializedRelations?: {...} } } │
│ │
│ manyToOne provides: │
│ • metadataName │
│ • foreignKey │
│ • flatEntityForeignKeyAggregator (nullable, often wrong/null) │
│ • isNullable │
│ │
│ oneToMany provides: │
│ • metadataName │
│ │
│ Monolithic single source of truth │
└──────────────────────────┬──────────────────────────────────────────┘
│
│ manyToOne entries transformed via
│ ToUniversalMetadataManyToOneRelationConfiguration
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ ALL_UNIVERSAL_METADATA_RELATIONS │
│─────────────────────────────────────────────────────────────────────│
│ Derived from: ALL_METADATA_RELATIONS (type-level transform) │
│ │
│ Structure: { [metadataName]: { manyToOne: {...}, oneToMany: {...} │
│ } } │
│ │
│ manyToOne provides: │
│ • metadataName │
│ • foreignKey │
│ • universalForeignKey (derived: FK → replace Id → UniversalId) │
│ • universalFlatEntityForeignKeyAggregator (derived from │
│ flatEntityForeignKeyAggregator → replace Ids → UniversalIds) │
│ • isNullable │
│ │
│ oneToMany: passthrough from ALL_METADATA_RELATIONS │
│ │
│ Duplicated monolith with universal key transforms │
└──────────────────────────┬──────────────────────────────────────────┘
│
┌──────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌────────────────────┐ ┌──────────────────────┐
│ Type consumers│ │ Atomic utils │ │ Optimistic utils │
│───────────────│ │────────────────────│ │──────────────────────│
│ • JoinColumn │ │ • resolve-entity- │ │ • add/delete flat │
│ • RelatedNames│ │ relation-univ-id │ │ entity maps │
│ • Universal │ │ (ALL_METADATA_ │ │ (ALL_METADATA_ │
│ FlatEntity │ │ RELATIONS │ │ RELATIONS │
│ From │ │ .manyToOne) │ │ .manyToOne) │
│ │ │ │ │ │
│ Mixed usage │ │ • resolve-univ- │ │ • add/delete univ │
│ of both │ │ relation-ids │ │ flat entity maps │
│ constants │ │ (ALL_UNIVERSAL_ │ │ (ALL_UNIVERSAL_ │
│ │ │ METADATA_REL │ │ METADATA_REL │
│ │ │ .manyToOne) │ │ .manyToOne) │
│ │ │ │ │ │
│ │ │ • resolve-univ- │ │ universalFlatEntity │
│ │ │ update-rel-ids │ │ ForeignKeyAggregator │
│ │ │ (ALL_UNIVERSAL_ │ │ read directly from │
│ │ │ METADATA_REL │ │ the constant │
│ │ │ .manyToOne) │ │ │
│ │ │ │ │ │
│ │ │ • regex hack: │ │ │
│ │ │ foreignKey │ │ │
│ │ │ .replace(/Id$/, │ │ │
│ │ │ 'UniversalId') │ │ │
└───────────────┘ └────────────────────┘ └──────────────────────┘
```
2026-02-17 11:13:54 +01:00
..
2026-02-13 18:03:13 +01:00
2026-02-03 17:16:54 +00:00
2025-12-22 15:19:11 +01:00
2026-02-09 14:35:13 +01:00
2026-02-17 09:29:37 +01:00
2026-02-11 15:33:51 +00:00
2026-02-13 10:39:26 +00:00
2026-02-13 17:55:04 +01:00
2026-02-17 11:05:36 +01:00
2026-02-16 16:50:46 +01:00
2026-02-17 11:13:54 +01:00
2026-02-17 09:29:17 +01:00
2026-02-17 09:29:17 +01:00
2026-02-13 15:43:32 +00:00
2026-02-13 16:12:16 +00:00
2025-12-17 14:39:51 +01:00