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
@@ -6,6 +6,8 @@ import { type FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/
import { type FlatRoleTargetByAgentIdMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-role-target-by-agent-id-maps.type';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/role-target/services/workspace-user-workspace-role-map-cache.service';
import { type FlatRowLevelPermissionPredicateGroupMaps } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group-maps.type';
import { type FlatRowLevelPermissionPredicateMaps } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-maps.type';
export const WORKSPACE_CACHE_KEYS_V2 = {
flatObjectMetadataMaps: 'flat-maps:object-metadata',
@@ -32,6 +34,10 @@ export const WORKSPACE_CACHE_KEYS_V2 = {
flatPageLayoutMaps: 'flat-maps:page-layout',
flatPageLayoutWidgetMaps: 'flat-maps:page-layout-widget',
flatPageLayoutTabMaps: 'flat-maps:flatPageLayoutTabMaps',
flatRowLevelPermissionPredicateMaps:
'flat-maps:row-level-permission-predicate',
flatRowLevelPermissionPredicateGroupMaps:
'flat-maps:row-level-permission-predicate-group',
} as const satisfies Record<WorkspaceCacheKeyName, string>;
export type AdditionalCacheDataMaps = {
@@ -42,6 +48,8 @@ export type AdditionalCacheDataMaps = {
flatApplicationMaps: FlatApplicationCacheMaps;
ORMEntityMetadatas: EntityMetadata[];
flatRoleTargetByAgentIdMaps: FlatRoleTargetByAgentIdMaps;
flatRowLevelPermissionPredicateMaps: FlatRowLevelPermissionPredicateMaps;
flatRowLevelPermissionPredicateGroupMaps: FlatRowLevelPermissionPredicateGroupMaps;
};
export type WorkspaceCacheDataMap = AllFlatEntityMaps & AdditionalCacheDataMaps;