Skip to content
Merged
Show file tree
Hide file tree
Changes from 154 commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
b2beefb
Add permission flag metadata and related types
abdulrahmancodes Mar 11, 2026
23c2449
Add migration to include universalIdentifier and applicationId in per…
abdulrahmancodes Mar 11, 2026
27f2a81
Add permission flag handling and related utilities
abdulrahmancodes Mar 11, 2026
bc15708
Add permission flag actions and validation services
abdulrahmancodes Mar 11, 2026
4e8d2c7
Add permission flag action handlers for workspace migration
abdulrahmancodes Mar 11, 2026
e35ef97
Refactor permission flag module and service for workspace migration
abdulrahmancodes Mar 11, 2026
9483ba3
Add integration tests for permission flag upsert functionality
abdulrahmancodes Mar 11, 2026
9bc64ae
Refactor permission flag utility and update workspace migration service
abdulrahmancodes Mar 11, 2026
100962e
Add permission flag to metadata error handler
abdulrahmancodes Mar 11, 2026
411cb73
Add Jest snapshots for failing permission flag upsert tests
abdulrahmancodes Mar 11, 2026
6d69808
Add permissionFlag to AllMetadataName type and GraphQL schema
abdulrahmancodes Mar 11, 2026
ee8c74f
Update snapshot for failing permission flag upsert test to correct me…
abdulrahmancodes Mar 11, 2026
0b0ef20
Add permissionFlag properties to Jest snapshot for comparison and str…
abdulrahmancodes Mar 11, 2026
7af8fdb
Add permissionFlag to AllMetadataName enum in GraphQL schema
abdulrahmancodes Mar 11, 2026
ef99ec6
Update Jest snapshots to include permissionFlag in related tests
abdulrahmancodes Mar 11, 2026
e5defd6
Add duplicate permission flag validation in FlatPermissionFlagValidat…
abdulrahmancodes Mar 12, 2026
194ca85
Refactor successful permission flag upsert test for clarity
abdulrahmancodes Mar 12, 2026
498a019
Merge branch 'main' into migrate-permission-flag-to-syncable-entity
abdulrahmancodes Mar 12, 2026
28268d5
Add objectPermission to useMetadataErrorHandler hook
abdulrahmancodes Mar 12, 2026
476c6f1
Add objectPermission support across various modules
abdulrahmancodes Mar 12, 2026
3f63417
Add migration to include universalIdentifier and applicationId in obj…
abdulrahmancodes Mar 12, 2026
5cc5303
Add flat-object-permission module and related utilities
abdulrahmancodes Mar 12, 2026
cc4caba
Add objectPermission properties to various modules
abdulrahmancodes Mar 12, 2026
fcb672c
Add object permission handling in workspace migration
abdulrahmancodes Mar 12, 2026
6e260d4
Refactor ApplicationManifestResolver to enforce type safety on worksp…
abdulrahmancodes Mar 12, 2026
69d7a89
Add object permission action handlers for workspace migration
abdulrahmancodes Mar 12, 2026
06dc304
Add utility function to convert flat object permissions to DTO
abdulrahmancodes Mar 12, 2026
25e5e10
Refactor ObjectPermissionService to integrate application and migrati…
abdulrahmancodes Mar 12, 2026
940e13c
Add integration tests for object permission upsert functionality
abdulrahmancodes Mar 12, 2026
d328ca6
Remove unused WorkspaceCacheService from PermissionFlagService and cl…
abdulrahmancodes Mar 12, 2026
e582146
Refactor permission flag validation to handle non-editable roles
abdulrahmancodes Mar 12, 2026
e136d2d
Refactor PermissionFlagService and RoleResolver to return FlatPermiss…
abdulrahmancodes Mar 12, 2026
ca36341
Refactor FlatPermissionFlagValidatorService for improved readability
abdulrahmancodes Mar 12, 2026
5c49ee2
Add MakePermissionFlagUniversalIdentifierAndApplicationIdNotNullableM…
abdulrahmancodes Mar 12, 2026
cce3a82
Update roles integration tests to reflect changes in permissions erro…
abdulrahmancodes Mar 12, 2026
4d34653
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 12, 2026
f43b79e
Enhance FlatObjectPermissionValidatorService to handle non-editable r…
abdulrahmancodes Mar 12, 2026
b704680
Refactor ObjectPermissionService and RoleResolver to streamline permi…
abdulrahmancodes Mar 12, 2026
25915a7
Update roles integration tests and snapshots for enhanced error handling
abdulrahmancodes Mar 12, 2026
c7d8999
Merge branch 'main' into migrate-permission-flag-to-syncable-entity
abdulrahmancodes Mar 12, 2026
30283f7
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 12, 2026
5d4391e
Refactor WorkspaceFlatPermissionFlagMapCacheService to filter permiss…
abdulrahmancodes Mar 13, 2026
6bbb75e
Add migration to enforce NOT NULL constraints on permissionFlag fields
abdulrahmancodes Mar 13, 2026
c87904a
Refactor error handling in migration for permission flags
abdulrahmancodes Mar 13, 2026
678a430
Revert "Refactor WorkspaceFlatPermissionFlagMapCacheService to filter…
abdulrahmancodes Mar 13, 2026
737c5f0
Update error logging in migration command to use error level
abdulrahmancodes Mar 13, 2026
4a20b2d
Add applicationId population and cleanup for permissionFlag table
abdulrahmancodes Mar 13, 2026
750dd48
Refactor permissionFlag migration to ensure unique index and foreign …
abdulrahmancodes Mar 13, 2026
9d01905
Refactor error handling in permissionFlag migration
abdulrahmancodes Mar 13, 2026
717ba1c
Update applicationId population logic in permissionFlag migration
abdulrahmancodes Mar 13, 2026
3c2e62b
Add objectPermission to AllMetadataName enum and schema
abdulrahmancodes Mar 13, 2026
48c5941
Add objectPermission to AllMetadataName enum
abdulrahmancodes Mar 13, 2026
bba9ceb
Refactor tests and RoleResolver for improved readability
abdulrahmancodes Mar 13, 2026
39b388e
Remove unused ApplicationService from ObjectPermissionService tests f…
abdulrahmancodes Mar 13, 2026
57f67d9
Refactor ObjectPermissionService to streamline permission checks
abdulrahmancodes Mar 13, 2026
1180485
Update snapshot for failing object permission upsert test to correct …
abdulrahmancodes Mar 13, 2026
3eb5517
Update failing object permission upsert test to use system object node
abdulrahmancodes Mar 13, 2026
97a9f9e
Remove redundant expectation from ObjectPermissionService test to imp…
abdulrahmancodes Mar 15, 2026
643c18e
Add non-system object metadata ID to failing object permission upsert…
abdulrahmancodes Mar 15, 2026
2f0fefe
Update failing object permission upsert test to handle string values …
abdulrahmancodes Mar 15, 2026
8b9c337
Refactor ObjectPermissionService test by removing unused WorkspaceCac…
abdulrahmancodes Mar 15, 2026
8ca6ddf
Add objectPermission related snapshots for metadata tests
abdulrahmancodes Mar 15, 2026
458af0c
Update failing object permission upsert test to use non-system object…
abdulrahmancodes Mar 15, 2026
0556da6
Merge branch 'main' into migrate-permission-flag-to-syncable-entity
abdulrahmancodes Mar 15, 2026
d890eda
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 15, 2026
1397b81
Update snapshot for ALL_UNIVERSAL_FLAT_ENTITY_FOREIGN_KEY_AGGREGATOR_…
abdulrahmancodes Mar 15, 2026
82a0e96
Refactor role validation in permission validators
abdulrahmancodes Mar 16, 2026
0b4302e
Merge branch 'main' into migrate-permission-flag-to-syncable-entity
abdulrahmancodes Mar 16, 2026
b9aea14
feat: add permissionFlag to AllMetadataName enum
abdulrahmancodes Mar 16, 2026
27a91f7
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 16, 2026
f502242
Remove deprecated AllMetadataName enum and its TypeScript definition,…
abdulrahmancodes Mar 16, 2026
657e931
Revert "Refactor role validation in permission validators"
abdulrahmancodes Mar 16, 2026
d57f76d
feat: add objectPermission to AllMetadataName enum
abdulrahmancodes Mar 16, 2026
6c7f01b
feat: add migration command for objectPermission universalIdentifier …
abdulrahmancodes Mar 16, 2026
27a6aa8
feat: introduce fieldPermission entity and related constants
abdulrahmancodes Mar 16, 2026
5d55800
feat: add 1-20 migration command for permissionFlag and update module…
abdulrahmancodes Mar 16, 2026
4615a6f
chore: remove obsolete migration for permissionFlag's universalIdenti…
abdulrahmancodes Mar 16, 2026
61b95b5
feat: add backfill command for permissionFlag applicationId and updat…
abdulrahmancodes Mar 17, 2026
ec49859
Merge branch 'main' into migrate-permission-flag-to-syncable-entity
abdulrahmancodes Mar 17, 2026
c20d277
refactor: update variable naming in PermissionFlagService for clarity
abdulrahmancodes Mar 17, 2026
6296377
refactor: remove applicationId backfill query from permissionFlag mig…
abdulrahmancodes Mar 17, 2026
c307f07
feat: introduce IdentifyPermissionFlagMetadataCommand and update upgr…
abdulrahmancodes Mar 17, 2026
683748d
refactor: simplify foreign key constraint addition in permissionFlag …
abdulrahmancodes Mar 17, 2026
c583f3b
fix: enhance role validation in FlatPermissionFlagValidatorService
abdulrahmancodes Mar 17, 2026
46eccc7
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 17, 2026
8221312
feat: add new commands for object permission metadata and update upgr…
abdulrahmancodes Mar 17, 2026
d8794e9
refactor: simplify action handling in ApplicationManifestResolver
abdulrahmancodes Mar 17, 2026
3f58199
fix: correct object permission mapping in flat object metadata utility
abdulrahmancodes Mar 17, 2026
1d1e876
feat: create migration to enforce NOT NULL constraints on permissionF…
abdulrahmancodes Mar 18, 2026
3af3b7d
refactor: streamline migration for adding universalIdentifier and app…
abdulrahmancodes Mar 18, 2026
7bcb672
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 18, 2026
3585f9c
refactor: integrate column addition directly into migration for objec…
abdulrahmancodes Mar 18, 2026
9bc214a
fix: handle potential undefined objectPermissions in flat object meta…
abdulrahmancodes Mar 18, 2026
e560b67
fix: update action type casting in ApplicationManifestResolver
abdulrahmancodes Mar 18, 2026
8b26438
Merge branch 'main' into migrate-permission-flag-to-syncable-entity
abdulrahmancodes Mar 18, 2026
6dec7fc
Merge branch 'migrate-object-permission-to-syncable-entity' into migr…
abdulrahmancodes Mar 18, 2026
c7ebdc8
feat: implement utility to convert field permission entity to flat fi…
abdulrahmancodes Mar 18, 2026
d058639
feat: add flatFieldPermissionMaps to workspace cache keys
abdulrahmancodes Mar 18, 2026
9a4fac5
feat: add WorkspaceFlatFieldPermissionMapCacheService for flat field …
abdulrahmancodes Mar 18, 2026
ed099cc
feat: add commands for field permission metadata and migration
abdulrahmancodes Mar 18, 2026
fc1adbb
refactor: remove unnecessary DROP statements from permissionFlag migr…
abdulrahmancodes Mar 18, 2026
235ca14
Merge branch 'migrate-permission-flag-to-syncable-entity' into migrat…
abdulrahmancodes Mar 18, 2026
6aa2a6c
refactor: simplify down method in objectPermission migration
abdulrahmancodes Mar 18, 2026
6acd267
Merge branch 'migrate-object-permission-to-syncable-entity' into migr…
abdulrahmancodes Mar 18, 2026
89eaed4
feat: enhance flat role utility and workspace cache service for field…
abdulrahmancodes Mar 18, 2026
066aa99
feat: add FIELD_PERMISSION_NOT_FOUND exception codes and messages
abdulrahmancodes Mar 18, 2026
265b312
feat: add fieldPermission support to metadata event handling
abdulrahmancodes Mar 18, 2026
bbeab07
Merge branch 'main' into migrate-object-permission-to-syncable-entity
abdulrahmancodes Mar 18, 2026
4a911c0
Merge branch 'migrate-object-permission-to-syncable-entity' into migr…
abdulrahmancodes Mar 18, 2026
7b21a64
Add field permission migration support
abdulrahmancodes Mar 18, 2026
15e9f90
Refactor migration name formatting for consistency
abdulrahmancodes Mar 18, 2026
58a1295
Add utility function to convert field permission input to universal f…
abdulrahmancodes Mar 18, 2026
059c3c1
fix: remove duplicate import of IdentifyPermissionFlagMetadataCommand…
abdulrahmancodes Mar 18, 2026
38b56a0
fix: ensure consistent formatting in GraphQL schema files
abdulrahmancodes Mar 18, 2026
156476d
feat: enhance workspace metadata caching by integrating object permis…
abdulrahmancodes Mar 18, 2026
7022423
fix: streamline object permissions mapping in metadata utility
abdulrahmancodes Mar 18, 2026
b6b90d4
fix: update object permissions selection in workspace role map cache …
abdulrahmancodes Mar 18, 2026
e31e9d3
Merge branch 'migrate-object-permission-to-syncable-entity' into migr…
abdulrahmancodes Mar 18, 2026
82b4bb8
feat: enhance field permission service and add DTO conversion utility
abdulrahmancodes Mar 19, 2026
1c2f2af
feat: enhance field permission service tests with migration validation
abdulrahmancodes Mar 19, 2026
c6334a9
feat: add integration tests for field permission upsert functionality
abdulrahmancodes Mar 19, 2026
108bceb
Merge branch 'main' into migrate-object-permission-to-syncable-entity
abdulrahmancodes Mar 19, 2026
da7a2fb
Merge branch 'migrate-object-permission-to-syncable-entity' into migr…
abdulrahmancodes Mar 19, 2026
88a252e
fix: update Jest snapshot for ALL_UNIVERSAL_FLAT_ENTITY_FOREIGN_KEY_A…
abdulrahmancodes Mar 19, 2026
685af65
refactor: remove deprecated feature flag from GraphQL schema
abdulrahmancodes Mar 19, 2026
6ff1369
test: update Jest snapshots to include fieldPermission metadata
abdulrahmancodes Mar 19, 2026
d37411e
feat: add fieldPermission to AllMetadataName enum
abdulrahmancodes Mar 19, 2026
ea1bd76
feat: add fieldPermission to useMetadataErrorHandler hook
abdulrahmancodes Mar 19, 2026
a5eed5f
test: enhance FieldPermissionService tests with additional field rela…
abdulrahmancodes Mar 19, 2026
c1aa32f
feat: add fieldPermission properties to metadata structures
abdulrahmancodes Mar 19, 2026
2fc912d
fix: update foreign key and index constraints in fieldPermission migr…
abdulrahmancodes Mar 19, 2026
17b7d75
test: enhance field permissions integration tests with error handling…
abdulrahmancodes Mar 19, 2026
9d8704e
refactor: streamline fieldPermission mapping in metadata utilities
abdulrahmancodes Mar 19, 2026
0014caa
feat: add IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED flag and field…
abdulrahmancodes Mar 19, 2026
573f6a5
feat: add FilterableField decorator to objectMetadataId in FieldMetad…
abdulrahmancodes Mar 19, 2026
929cea7
Merge branch 'main' into migrate-field-permission-to-syncable-entity
abdulrahmancodes Mar 25, 2026
eacbea2
Add fieldPermissionUniversalIdentifiers to flat field metadata snapshots
abdulrahmancodes Mar 25, 2026
cfa3038
Refactor field permission tests to validate restricted fields are hidden
abdulrahmancodes Mar 25, 2026
52f1f88
Enhance field permission tests to verify restricted fields are hidden
abdulrahmancodes Mar 25, 2026
ebda546
Update field permission tests to reflect correct update permissions
abdulrahmancodes Mar 25, 2026
f56a56b
Add IdentifyFieldPermissionMetadataCommand to upgrade version module
abdulrahmancodes Mar 25, 2026
bfe464a
Add objectMetadataId to Field, FieldFilter, and UpdateFieldInput types
abdulrahmancodes Mar 25, 2026
474aa03
Refactor field permission integration tests to remove unused variable…
abdulrahmancodes Mar 25, 2026
f3911e1
Update field permission integration tests to validate accessibility o…
abdulrahmancodes Mar 25, 2026
b6936d4
Add objectMetadataId to Field, FieldFilter, and Create/UpdateFieldInp…
abdulrahmancodes Mar 25, 2026
9c099fe
Potential fix for pull request finding 'Unused variable, import, func…
abdulrahmancodes Mar 25, 2026
ba2e873
Add objectMetadataId to FieldMetadataItem type
abdulrahmancodes Mar 25, 2026
44201cf
Refactor field permission integration tests to validate accessibility…
abdulrahmancodes Mar 25, 2026
b0b3e3d
Update failing field permission upsert snapshot to reflect validation…
abdulrahmancodes Mar 25, 2026
794d253
Merge branch 'main' into migrate-field-permission-to-syncable-entity
abdulrahmancodes Mar 25, 2026
c1c405a
Refactor upsert field permissions utility
abdulrahmancodes Mar 25, 2026
d2264fe
Merge branch 'main' into migrate-field-permission-to-syncable-entity
abdulrahmancodes Mar 25, 2026
53ed615
Refactor field permission utility to streamline identifier resolution
abdulrahmancodes Mar 25, 2026
6f2c2f6
Remove unused import from field permission upsert integration test
abdulrahmancodes Mar 25, 2026
8b1c96b
Merge branch 'main' into migrate-field-permission-to-syncable-entity
abdulrahmancodes Mar 26, 2026
b990f57
Merge remote-tracking branch 'origin/main' into migrate-field-permiss…
charlesBochet Mar 27, 2026
6d1cb5b
Update failing field permission upsert snapshot for relation field au…
charlesBochet Mar 27, 2026
320334d
Fix flaky field permission test by selecting non-relation field
charlesBochet Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ type Field {
defaultValue: JSON
options: JSON
settings: JSON
objectMetadataId: UUID!
isLabelSyncedWithName: Boolean
morphId: UUID
createdAt: DateTime!
Expand Down Expand Up @@ -540,6 +541,7 @@ input FieldFilter {
isActive: BooleanFieldComparison
isSystem: BooleanFieldComparison
isUIReadOnly: BooleanFieldComparison
objectMetadataId: UUIDFilterComparison
}

input IndexFilter {
Expand Down Expand Up @@ -3090,6 +3092,7 @@ enum AllMetadataName {
navigationMenuItem
permissionFlag
objectPermission
fieldPermission
frontComponent
webhook
}
Expand Down Expand Up @@ -4272,8 +4275,8 @@ input CreateFieldInput {
defaultValue: JSON
options: JSON
settings: JSON
isLabelSyncedWithName: Boolean
objectMetadataId: UUID!
isLabelSyncedWithName: Boolean
isRemoteCreation: Boolean
relationCreationPayload: JSON
morphRelationsCreationPayload: [JSON!]
Expand Down Expand Up @@ -4301,6 +4304,7 @@ input UpdateFieldInput {
defaultValue: JSON
options: JSON
settings: JSON
objectMetadataId: UUID
isLabelSyncedWithName: Boolean
morphRelationsUpdatePayload: [JSON!]
}
Expand Down
11 changes: 7 additions & 4 deletions packages/twenty-client-sdk/src/metadata/generated/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ export interface Field {
defaultValue?: Scalars['JSON']
options?: Scalars['JSON']
settings?: Scalars['JSON']
objectMetadataId: Scalars['UUID']
isLabelSyncedWithName?: Scalars['Boolean']
morphId?: Scalars['UUID']
createdAt: Scalars['DateTime']
Expand Down Expand Up @@ -2676,7 +2677,7 @@ export interface CollectionHash {
__typename: 'CollectionHash'
}

export type AllMetadataName = 'fieldMetadata' | 'objectMetadata' | 'view' | 'viewField' | 'viewFieldGroup' | 'viewGroup' | 'viewSort' | 'rowLevelPermissionPredicate' | 'rowLevelPermissionPredicateGroup' | 'viewFilterGroup' | 'index' | 'logicFunction' | 'viewFilter' | 'role' | 'roleTarget' | 'agent' | 'skill' | 'pageLayout' | 'pageLayoutWidget' | 'pageLayoutTab' | 'commandMenuItem' | 'navigationMenuItem' | 'permissionFlag' | 'objectPermission' | 'frontComponent' | 'webhook'
export type AllMetadataName = 'fieldMetadata' | 'objectMetadata' | 'view' | 'viewField' | 'viewFieldGroup' | 'viewGroup' | 'viewSort' | 'rowLevelPermissionPredicate' | 'rowLevelPermissionPredicateGroup' | 'viewFilterGroup' | 'index' | 'logicFunction' | 'viewFilter' | 'role' | 'roleTarget' | 'agent' | 'skill' | 'pageLayout' | 'pageLayoutWidget' | 'pageLayoutTab' | 'commandMenuItem' | 'navigationMenuItem' | 'permissionFlag' | 'objectPermission' | 'fieldPermission' | 'frontComponent' | 'webhook'

export interface MinimalObjectMetadata {
id: Scalars['UUID']
Expand Down Expand Up @@ -3360,6 +3361,7 @@ export interface FieldGenqlSelection{
defaultValue?: boolean | number
options?: boolean | number
settings?: boolean | number
objectMetadataId?: boolean | number
isLabelSyncedWithName?: boolean | number
morphId?: boolean | number
createdAt?: boolean | number
Expand Down Expand Up @@ -3476,7 +3478,7 @@ export interface ObjectGenqlSelection{
__scalar?: boolean | number
}

export interface FieldFilter {and?: (FieldFilter[] | null),or?: (FieldFilter[] | null),id?: (UUIDFilterComparison | null),isCustom?: (BooleanFieldComparison | null),isActive?: (BooleanFieldComparison | null),isSystem?: (BooleanFieldComparison | null),isUIReadOnly?: (BooleanFieldComparison | null)}
export interface FieldFilter {and?: (FieldFilter[] | null),or?: (FieldFilter[] | null),id?: (UUIDFilterComparison | null),isCustom?: (BooleanFieldComparison | null),isActive?: (BooleanFieldComparison | null),isSystem?: (BooleanFieldComparison | null),isUIReadOnly?: (BooleanFieldComparison | null),objectMetadataId?: (UUIDFilterComparison | null)}

export interface IndexFilter {and?: (IndexFilter[] | null),or?: (IndexFilter[] | null),id?: (UUIDFilterComparison | null),isCustom?: (BooleanFieldComparison | null)}

Expand Down Expand Up @@ -6527,15 +6529,15 @@ export interface CreateOneFieldMetadataInput {
/** The record to create */
field: CreateFieldInput}

export interface CreateFieldInput {type: FieldMetadataType,name: Scalars['String'],label: Scalars['String'],description?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),isCustom?: (Scalars['Boolean'] | null),isActive?: (Scalars['Boolean'] | null),isSystem?: (Scalars['Boolean'] | null),isUIReadOnly?: (Scalars['Boolean'] | null),isNullable?: (Scalars['Boolean'] | null),isUnique?: (Scalars['Boolean'] | null),defaultValue?: (Scalars['JSON'] | null),options?: (Scalars['JSON'] | null),settings?: (Scalars['JSON'] | null),isLabelSyncedWithName?: (Scalars['Boolean'] | null),objectMetadataId: Scalars['UUID'],isRemoteCreation?: (Scalars['Boolean'] | null),relationCreationPayload?: (Scalars['JSON'] | null),morphRelationsCreationPayload?: (Scalars['JSON'][] | null)}
export interface CreateFieldInput {type: FieldMetadataType,name: Scalars['String'],label: Scalars['String'],description?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),isCustom?: (Scalars['Boolean'] | null),isActive?: (Scalars['Boolean'] | null),isSystem?: (Scalars['Boolean'] | null),isUIReadOnly?: (Scalars['Boolean'] | null),isNullable?: (Scalars['Boolean'] | null),isUnique?: (Scalars['Boolean'] | null),defaultValue?: (Scalars['JSON'] | null),options?: (Scalars['JSON'] | null),settings?: (Scalars['JSON'] | null),objectMetadataId: Scalars['UUID'],isLabelSyncedWithName?: (Scalars['Boolean'] | null),isRemoteCreation?: (Scalars['Boolean'] | null),relationCreationPayload?: (Scalars['JSON'] | null),morphRelationsCreationPayload?: (Scalars['JSON'][] | null)}

export interface UpdateOneFieldMetadataInput {
/** The id of the record to update */
id: Scalars['UUID'],
/** The record to update */
update: UpdateFieldInput}

export interface UpdateFieldInput {universalIdentifier?: (Scalars['String'] | null),name?: (Scalars['String'] | null),label?: (Scalars['String'] | null),description?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),isActive?: (Scalars['Boolean'] | null),isSystem?: (Scalars['Boolean'] | null),isUIReadOnly?: (Scalars['Boolean'] | null),isNullable?: (Scalars['Boolean'] | null),isUnique?: (Scalars['Boolean'] | null),defaultValue?: (Scalars['JSON'] | null),options?: (Scalars['JSON'] | null),settings?: (Scalars['JSON'] | null),isLabelSyncedWithName?: (Scalars['Boolean'] | null),morphRelationsUpdatePayload?: (Scalars['JSON'][] | null)}
export interface UpdateFieldInput {universalIdentifier?: (Scalars['String'] | null),name?: (Scalars['String'] | null),label?: (Scalars['String'] | null),description?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),isActive?: (Scalars['Boolean'] | null),isSystem?: (Scalars['Boolean'] | null),isUIReadOnly?: (Scalars['Boolean'] | null),isNullable?: (Scalars['Boolean'] | null),isUnique?: (Scalars['Boolean'] | null),defaultValue?: (Scalars['JSON'] | null),options?: (Scalars['JSON'] | null),settings?: (Scalars['JSON'] | null),objectMetadataId?: (Scalars['UUID'] | null),isLabelSyncedWithName?: (Scalars['Boolean'] | null),morphRelationsUpdatePayload?: (Scalars['JSON'][] | null)}

export interface DeleteOneFieldInput {
/** The id of the field to delete. */
Expand Down Expand Up @@ -9425,6 +9427,7 @@ export const enumAllMetadataName = {
navigationMenuItem: 'navigationMenuItem' as const,
permissionFlag: 'permissionFlag' as const,
objectPermission: 'objectPermission' as const,
fieldPermission: 'fieldPermission' as const,
frontComponent: 'frontComponent' as const,
webhook: 'webhook' as const
}
Expand Down
15 changes: 12 additions & 3 deletions packages/twenty-client-sdk/src/metadata/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,9 @@ export default {
"settings": [
15
],
"objectMetadataId": [
3
],
"isLabelSyncedWithName": [
6
],
Expand Down Expand Up @@ -1164,6 +1167,9 @@ export default {
"isUIReadOnly": [
43
],
"objectMetadataId": [
42
],
"__typename": [
1
]
Expand Down Expand Up @@ -10745,12 +10751,12 @@ export default {
"settings": [
15
],
"isLabelSyncedWithName": [
6
],
"objectMetadataId": [
3
],
"isLabelSyncedWithName": [
6
],
"isRemoteCreation": [
6
],
Expand Down Expand Up @@ -10815,6 +10821,9 @@ export default {
"settings": [
15
],
"objectMetadataId": [
3
],
"isLabelSyncedWithName": [
6
],
Expand Down
4 changes: 4 additions & 0 deletions packages/twenty-front/src/generated-metadata/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ export enum AllMetadataName {
agent = 'agent',
commandMenuItem = 'commandMenuItem',
fieldMetadata = 'fieldMetadata',
fieldPermission = 'fieldPermission',
frontComponent = 'frontComponent',
index = 'index',
logicFunction = 'logicFunction',
Expand Down Expand Up @@ -1748,6 +1749,7 @@ export type Field = {
morphRelations?: Maybe<Array<Relation>>;
name: Scalars['String'];
object?: Maybe<Object>;
objectMetadataId: Scalars['UUID'];
options?: Maybe<Scalars['JSON']>;
relation?: Maybe<Relation>;
settings?: Maybe<Scalars['JSON']>;
Expand Down Expand Up @@ -1794,6 +1796,7 @@ export type FieldFilter = {
isCustom?: InputMaybe<BooleanFieldComparison>;
isSystem?: InputMaybe<BooleanFieldComparison>;
isUIReadOnly?: InputMaybe<BooleanFieldComparison>;
objectMetadataId?: InputMaybe<UuidFilterComparison>;
or?: InputMaybe<Array<FieldFilter>>;
};

Expand Down Expand Up @@ -5239,6 +5242,7 @@ export type UpdateFieldInput = {
label?: InputMaybe<Scalars['String']>;
morphRelationsUpdatePayload?: InputMaybe<Array<Scalars['JSON']>>;
name?: InputMaybe<Scalars['String']>;
objectMetadataId?: InputMaybe<Scalars['UUID']>;
options?: InputMaybe<Scalars['JSON']>;
settings?: InputMaybe<Scalars['JSON']>;
universalIdentifier?: InputMaybe<Scalars['String']>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const useMetadataErrorHandler = () => {
logicFunction: t`logic function`,
permissionFlag: t`permission flag`,
objectPermission: t`object permission`,
fieldPermission: t`field permission`,
role: t`role`,
roleTarget: t`role target`,
agent: t`agent`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ export type FieldMetadataItem = Omit<
| '__typename'
| 'applicationId'
| 'defaultValue'
| 'objectMetadataId'
| 'options'
| 'relation'
| 'morphRelations'
> & {
__typename?: string;
applicationId?: string;
objectMetadataId?: string;
defaultValue?: any;
options?: FieldMetadataItemOption[] | null;
relation?: FieldMetadataItemRelation | null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';

import { Command } from 'nest-commander';
import { DataSource, IsNull, type Repository } from 'typeorm';
import { v4 } from 'uuid';

import { isDefined } from 'twenty-shared/utils';

import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';

@Command({
name: 'upgrade:1-20:identify-field-permission-metadata',
description:
'Identify field permission metadata (backfill universalIdentifier and applicationId)',
})
export class IdentifyFieldPermissionMetadataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
private hasRunOnce = false;

constructor(
@InjectRepository(WorkspaceEntity)
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager,
protected readonly dataSourceService: DataSourceService,
@InjectDataSource()
private readonly coreDataSource: DataSource,
) {
super(workspaceRepository, twentyORMGlobalManager, dataSourceService);
}

override async runOnWorkspace({
options,
}: RunOnWorkspaceArgs): Promise<void> {
if (this.hasRunOnce) {
this.logger.log(
'Skipping has already been run once IdentifyFieldPermissionMetadataCommand',
);

return;
}

if (options.dryRun) {
return;
}

const queryRunner = this.coreDataSource.createQueryRunner();

await queryRunner.connect();
await queryRunner.startTransaction();

try {
const repository = queryRunner.manager.getRepository(
FieldPermissionEntity,
);
const withNullApplicationId = await repository.find({
where: { applicationId: IsNull() },
relations: ['role'],
});

const toUpdate = withNullApplicationId.filter((fieldPermission) =>
isDefined(fieldPermission.role?.applicationId),
);
const toRemove = withNullApplicationId.filter(
(fieldPermission) => !isDefined(fieldPermission.role?.applicationId),
);

for (const fieldPermission of toUpdate) {
fieldPermission.applicationId = fieldPermission.role!.applicationId;
fieldPermission.universalIdentifier =
fieldPermission.universalIdentifier ?? v4();
}

if (toUpdate.length > 0) {
await repository.save(toUpdate);
}
if (toRemove.length > 0) {
await repository.remove(toRemove);
}

const withNullUniversalIdentifier = await repository.find({
where: { universalIdentifier: IsNull() },
});

for (const fieldPermission of withNullUniversalIdentifier) {
fieldPermission.universalIdentifier = v4();
}

if (withNullUniversalIdentifier.length > 0) {
await repository.save(withNullUniversalIdentifier);
}

await queryRunner.commitTransaction();
this.logger.log(
'Successfully run IdentifyFieldPermissionMetadataCommand',
);
this.hasRunOnce = true;
} catch (error) {
await queryRunner.rollbackTransaction();
this.logger.error(
`Rolling back IdentifyFieldPermissionMetadataCommand: ${error.message}`,
);
throw error;
} finally {
await queryRunner.release();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';

import { Command } from 'nest-commander';
import { DataSource, type Repository } from 'typeorm';

import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner';
import { makeFieldPermissionUniversalIdentifierAndApplicationIdNotNullQueries } from 'src/database/typeorm/core/migrations/utils/1773400000000-make-field-permission-universal-identifier-and-application-id-not-null.util';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';

@Command({
name: 'upgrade:1-20:make-field-permission-universal-identifier-and-application-id-not-nullable-migration',
description:
'Set NOT NULL on fieldPermission universalIdentifier and applicationId, add unique index and FK (run identify-field-permission-metadata first)',
})
export class MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
private hasRunOnce = false;

constructor(
@InjectRepository(WorkspaceEntity)
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager,
protected readonly dataSourceService: DataSourceService,
@InjectDataSource()
private readonly coreDataSource: DataSource,
) {
super(workspaceRepository, twentyORMGlobalManager, dataSourceService);
}

override async runOnWorkspace({
options,
}: RunOnWorkspaceArgs): Promise<void> {
if (this.hasRunOnce) {
this.logger.log(
'Skipping has already been run once MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand',
);

return;
}

if (options.dryRun) {
return;
}

const queryRunner = this.coreDataSource.createQueryRunner();

await queryRunner.connect();
await queryRunner.startTransaction();

try {
await makeFieldPermissionUniversalIdentifierAndApplicationIdNotNullQueries(
queryRunner,
);

await queryRunner.commitTransaction();
this.logger.log(
'Successfully run MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand',
);
this.hasRunOnce = true;
} catch (error) {
await queryRunner.rollbackTransaction();
this.logger.error(
`Rolling back MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: ${error.message}`,
);
throw error;
} finally {
await queryRunner.release();
}
}
}
Loading
Loading