Row level permissions - POC 1 (#16599)

## Context
This PR adds the core structure for RLS implementation:
- RLS data model
- RLS service layer
- RLS WorkspaceMigration and Syncable Entity + cache + Validations
- RLS resolver layer
- ORM layer with RLS Predicate to ORM WHERE clause conversion with
workspaceMember record transposition

Tests are missing though

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Establishes core row-level permissions infrastructure and enforcement
across the stack.
> 
> - Backend: new `rowLevelPermissionPredicate` and
`rowLevelPermissionPredicateGroup` entities, TypeORM migration, feature
flag `IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED`, flat-entity
maps/cache wiring, services and GraphQL resolvers for CRUD, and
inclusion of `workspaceMember` in auth context
> - ORM: applies row-level permission predicates to SELECT, DELETE, and
SOFT DELETE query builders; propagates context through
GlobalWorkspaceOrmManager/EntityManager
> - GraphQL: generated schema/types/queries/mutations for
creating/updating/deleting/fetching predicates and groups
> - Frontend: settings page adds a gated "Record-level" section
(placeholder) and metadata error handler labels for new entities
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fe955cc4588a92157afa6795fb574189a4be1e93. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
Weiko
2025-12-31 16:15:17 +01:00
committed by GitHub
parent 888a50c3be
commit 15b21570ae
120 changed files with 5649 additions and 29 deletions
@@ -11,6 +11,8 @@ import { FLAT_PAGE_LAYOUT_WIDGET_EDITABLE_PROPERTIES } from 'src/engine/metadata
import { FLAT_PAGE_LAYOUT_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-page-layout/constants/flat-page-layout-editable-properties.constant';
import { FLAT_ROLE_TARGET_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-role-target/constants/flat-role-target-editable-properties.constant';
import { FLAT_ROLE_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-role/constants/flat-role-editable-properties.constant';
import { FLAT_ROW_LEVEL_PERMISSION_PREDICATE_GROUP_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-row-level-permission-predicate-group/constants/flat-row-level-permission-predicate-group-editable-properties.constant';
import { FLAT_ROW_LEVEL_PERMISSION_PREDICATE_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-row-level-permission-predicate/constants/flat-row-level-permission-predicate-editable-properties.constant';
import { FLAT_VIEW_FIELD_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-field/constants/flat-view-field-editable-properties.constant';
import { FLAT_VIEW_FILTER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-filter/constants/flat-view-filter-editable-properties.constant';
import { FLAT_VIEW_GROUP_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-group/constants/flat-view-group-editable-properties.constant';
@@ -132,6 +134,20 @@ export const ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY = {
],
propertiesToStringify: [],
},
rowLevelPermissionPredicate: {
propertiesToCompare: [
...FLAT_ROW_LEVEL_PERMISSION_PREDICATE_EDITABLE_PROPERTIES,
'deletedAt',
],
propertiesToStringify: ['value'],
},
rowLevelPermissionPredicateGroup: {
propertiesToCompare: [
...FLAT_ROW_LEVEL_PERMISSION_PREDICATE_GROUP_EDITABLE_PROPERTIES,
'deletedAt',
],
propertiesToStringify: [],
},
} as const satisfies {
[P in AllMetadataName]: OneFlatEntityConfiguration<P>;
};
@@ -122,4 +122,6 @@ export const ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY = {
flatEntityForeignKeyAggregator: 'tabIds',
},
},
rowLevelPermissionPredicate: {},
rowLevelPermissionPredicateGroup: {},
} as const satisfies MetadataNameAndRelations;
@@ -126,6 +126,23 @@ export const ALL_METADATA_RELATION_PROPERTIES = {
objectMetadata: true,
application: true,
},
rowLevelPermissionPredicate: {
workspace: true,
role: true,
fieldMetadata: true,
workspaceMemberFieldMetadata: true,
objectMetadata: true,
rowLevelPermissionPredicateGroup: true,
application: true,
},
rowLevelPermissionPredicateGroup: {
workspace: true,
role: true,
parentRowLevelPermissionPredicateGroup: true,
childRowLevelPermissionPredicateGroups: true,
rowLevelPermissionPredicates: true,
application: true,
},
} as const satisfies {
[TName in AllMetadataName]: {
[P in ExtractEntityRelatedEntityProperties<MetadataEntity<TName>>]: true;
@@ -64,4 +64,13 @@ export const ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION = {
pageLayoutWidget: {
pageLayoutTab: true,
},
rowLevelPermissionPredicate: {
fieldMetadata: true,
objectMetadata: true,
role: true,
rowLevelPermissionPredicateGroup: true,
},
rowLevelPermissionPredicateGroup: {
role: true,
},
} as const satisfies MetadataRequiredForValidation;