fix(server): type WasRemovedInUpgrade columns with WasRemovedInUpgrade<> (#21785)

## Context

WasRemovedInUpgrade type brand was introduced in
https://github.com/twentyhq/twenty/pull/21228/changes#diff-1b6d688610669a46b3ee8e3a41b1c7eb0ee03e19146d0d249f95df6e56164a92R15
for the `isCustom` property deprecation.
The @WasRemovedInUpgrade decorator and the WasRemovedInUpgrade<T> type
are meant to go together: the type brand makes the property optional in
every derived flat-entity type, so the column only needs to be declared
on the entity itself. RolePermissionFlagEntity.flag had the decorator
but was typed as a plain PermissionFlagType, forcing the property to be
supplied everywhere.

This PR:
- Types flag as WasRemovedInUpgrade<PermissionFlagType> (matching the
isCustom reference impl on object/field metadata).
- Removes the now-redundant flag from the flat-entity construction
sites, the create input, and the service call site — leaving it only on
the entity. The GraphQL RolePermissionFlagDTO.flag is kept (it's an API
field derived from permissionFlag.key, not the removed column).
- Fixes a latent brand-leak in the flat-entity config type: toStringify
is computed via object-detection, and a branded type reads as an object.
This was harmless for boolean but wrongly forced toStringify: true for
enum/string columns. Added UnwrapWasRemovedInUpgrade<T> and applied it
so the brand is transparent making the pattern work for any type, not
just
booleans.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21785?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Weiko
2026-06-18 15:23:24 +02:00
committed by GitHub
parent 2b3b2362db
commit cc4659ce11
8 changed files with 16 additions and 25 deletions
@@ -1,7 +1,3 @@
import {
PermissionFlagType,
SystemPermissionFlag,
} from 'twenty-shared/constants';
import { v5 } from 'uuid';
import { type UniversalFlatRolePermissionFlag } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-role-permission-flag.type';
@@ -9,10 +5,6 @@ import { type UniversalFlatRolePermissionFlag } from 'src/engine/workspace-manag
export const ROLE_PERMISSION_FLAG_UUID_NAMESPACE =
'b9a3b3b3-58a3-4f6c-9c1f-3a4f6c9c1f3a';
const SYSTEM_PERMISSION_FLAG_BY_UNIVERSAL_IDENTIFIER = Object.fromEntries(
Object.entries(SystemPermissionFlag).map(([key, uuid]) => [uuid, key]),
) as Record<string, PermissionFlagType | undefined>;
export const fromPermissionFlagToUniversalFlatRolePermissionFlag = ({
permissionFlagUniversalIdentifier,
roleUniversalIdentifier,
@@ -29,17 +21,11 @@ export const fromPermissionFlagToUniversalFlatRolePermissionFlag = ({
ROLE_PERMISSION_FLAG_UUID_NAMESPACE,
);
const resolvedFlag =
SYSTEM_PERMISSION_FLAG_BY_UNIVERSAL_IDENTIFIER[
permissionFlagUniversalIdentifier
];
return {
universalIdentifier,
applicationUniversalIdentifier,
roleUniversalIdentifier,
permissionFlagUniversalIdentifier,
flag: resolvedFlag as PermissionFlagType,
createdAt: now,
updatedAt: now,
};