Fix role synchronisation (#19469)

As title
solves
https://discord.com/channels/1130383047699738754/1491167098398052503
This commit is contained in:
martmull
2026-04-09 11:36:16 +02:00
committed by GitHub
parent 5edc034f8b
commit 5eaabe95e7
18 changed files with 282 additions and 170 deletions
@@ -363,6 +363,9 @@ export const EXPECTED_MANIFEST: Manifest = {
canBeAssignedToAgents: false,
canBeAssignedToUsers: true,
canBeAssignedToApiKeys: false,
fieldPermissions: [],
objectPermissions: [],
permissionFlags: [],
},
],
};
@@ -1499,6 +1499,9 @@ export const EXPECTED_MANIFEST: Manifest = {
description: 'A simple root-level role',
label: 'Root role',
universalIdentifier: 'c0c1c2c3-c4c5-4000-8000-000000000001',
fieldPermissions: [],
objectPermissions: [],
permissionFlags: [],
},
{
canBeAssignedToAgents: false,
@@ -1512,6 +1515,7 @@ export const EXPECTED_MANIFEST: Manifest = {
description: 'Default role for function Twenty client',
fieldPermissions: [
{
universalIdentifier: 'dbc86ced-bd2c-5874-93f1-1f72c5111991',
canReadFieldValue: false,
canUpdateFieldValue: false,
fieldUniversalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
@@ -1521,6 +1525,7 @@ export const EXPECTED_MANIFEST: Manifest = {
label: 'Default function role',
objectPermissions: [
{
universalIdentifier: '99c7c326-04ca-5c8b-ad11-da6c5b819813',
canDestroyObjectRecords: false,
canReadObjectRecords: true,
canSoftDeleteObjectRecords: false,
@@ -1528,7 +1533,12 @@ export const EXPECTED_MANIFEST: Manifest = {
objectUniversalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
},
],
permissionFlags: [PermissionFlagType.APPLICATIONS],
permissionFlags: [
{
universalIdentifier: '01d7865a-7700-5d49-b2aa-62623c2cbac7',
flag: PermissionFlagType.APPLICATIONS,
},
],
universalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
},
],
@@ -38,6 +38,8 @@ import {
import { getInputSchemaFromSourceCode } from 'twenty-shared/logic-function';
import { assertUnreachable } from 'twenty-shared/utils';
import { addMissingFieldOptionIds } from '@/cli/utilities/build/manifest/utils/add-missing-field-option-ids';
import { fromRoleConfigToRoleManifest } from '@/cli/utilities/build/manifest/utils/from-role-config-to-role-manifest';
import { type RoleConfig } from '@/sdk/roles/role-config';
const loadSources = async (appPath: string): Promise<string[]> => {
return await glob(['**/*.ts', '**/*.tsx'], {
@@ -170,11 +172,12 @@ export const buildManifest = async (
break;
}
case ManifestEntityKey.Roles: {
const extract = await extractManifestFromFile<RoleManifest>({
const extract = await extractManifestFromFile<RoleConfig>({
appPath,
filePath,
});
roles.push(extract.config);
const roleConfig = fromRoleConfigToRoleManifest(extract.config);
roles.push(roleConfig);
errors.push(...extract.errors);
rolesFilePaths.push(relativePath);
break;
@@ -0,0 +1,41 @@
import { type RoleConfig } from '@/sdk/roles/role-config';
import { type RoleManifest } from 'twenty-shared/application';
import { v5 as uuidv5 } from 'uuid';
const ROLE_UNIVERSAL_IDENTIFIER_NAMESPACE =
'b403ec59-4d80-4f22-85e6-717a192dc9cb';
export const fromRoleConfigToRoleManifest = (
roleConfig: RoleConfig,
): RoleManifest => {
return {
...roleConfig,
objectPermissions: (roleConfig.objectPermissions ?? []).map(
(objectPermission) => ({
...objectPermission,
universalIdentifier: uuidv5(
`${roleConfig.universalIdentifier}:${objectPermission.objectUniversalIdentifier}`,
ROLE_UNIVERSAL_IDENTIFIER_NAMESPACE,
),
}),
),
fieldPermissions: (roleConfig.fieldPermissions ?? []).map(
(fieldPermission) => ({
...fieldPermission,
universalIdentifier: uuidv5(
`${roleConfig.universalIdentifier}:${fieldPermission.objectUniversalIdentifier}:${fieldPermission.fieldUniversalIdentifier}`,
ROLE_UNIVERSAL_IDENTIFIER_NAMESPACE,
),
}),
),
permissionFlags: (roleConfig.permissionFlags ?? []).map(
(permissionFlag) => ({
universalIdentifier: uuidv5(
`${roleConfig.universalIdentifier}:${permissionFlag}`,
ROLE_UNIVERSAL_IDENTIFIER_NAMESPACE,
),
flag: permissionFlag,
}),
),
};
};