remove nestjs-query from user and workspace resolvers (#22766)

## What

Migrates the `user` and `workspace` core modules off
`@ptc-org/nestjs-query`. Both used `NestjsQueryGraphQLModule` only as
scaffolding — all CRUD was disabled and the real GraphQL API is already
served by the hand-written `UserResolver` / `WorkspaceResolver`.



<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22766?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. -->

---------

Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Abdul Rahman
2026-07-10 16:59:58 +05:30
committed by GitHub
parent ace16add6c
commit d23511ea5e
9 changed files with 45 additions and 161 deletions
@@ -3,7 +3,6 @@ import { InjectRepository } from '@nestjs/typeorm';
import assert from 'assert';
import { msg } from '@lingui/core/macro';
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { isNonEmptyString } from '@sniptt/guards';
import { SOURCE_LOCALE } from 'twenty-shared/translations';
import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils';
@@ -52,7 +51,7 @@ import { STANDARD_ROLE } from 'src/engine/workspace-manager/twenty-standard-appl
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
// oxlint-disable-next-line twenty/inject-workspace-repository
export class UserService extends TypeOrmQueryService<UserEntity> {
export class UserService {
constructor(
@InjectRepository(UserEntity)
private readonly userRepository: Repository<UserEntity>,
@@ -70,9 +69,7 @@ export class UserService extends TypeOrmQueryService<UserEntity> {
private readonly coreEntityCacheService: CoreEntityCacheService,
private readonly workspaceMemberTranspiler: WorkspaceMemberTranspiler,
private readonly twentyConfigService: TwentyConfigService,
) {
super(userRepository);
}
) {}
async refreshWorkspaceIfPendingOrOngoingCreation<
TWorkspace extends Pick<WorkspaceEntity, 'id' | 'activationStatus'>,
@@ -86,7 +83,9 @@ export class UserService extends TypeOrmQueryService<UserEntity> {
return workspace;
}
const freshWorkspace = await this.workspaceService.findById(workspace.id);
const freshWorkspace = await this.workspaceService.findOneWorkspaceById(
workspace.id,
);
return freshWorkspace ?? workspace;
}
@@ -1,41 +0,0 @@
import {
type AutoResolverOpts,
PagingStrategies,
type ReadResolverOpts,
} from '@ptc-org/nestjs-query-graphql';
import { UserEntity } from 'src/engine/core-modules/user/user.entity';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
export const userAutoResolverOpts: AutoResolverOpts<
// oxlint-disable-next-line typescript/no-explicit-any
any,
// oxlint-disable-next-line typescript/no-explicit-any
any,
unknown,
unknown,
// oxlint-disable-next-line typescript/no-explicit-any
ReadResolverOpts<any>,
PagingStrategies
>[] = [
{
EntityClass: UserEntity,
DTOClass: UserEntity,
enableTotalCount: true,
pagingStrategy: PagingStrategies.CURSOR,
read: {
many: { disabled: true },
one: { disabled: true },
},
create: {
many: { disabled: true },
one: { disabled: true },
},
update: {
many: { disabled: true },
one: { disabled: true },
},
delete: { many: { disabled: true }, one: { disabled: true } },
guards: [WorkspaceAuthGuard],
},
];
@@ -1,6 +1,5 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import { APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations';
import {
BeforeInsert,
@@ -36,7 +35,7 @@ registerEnumType(OnboardingStatus, {
where: '"deletedAt" IS NULL',
})
export class UserEntity {
@IDField(() => UUIDScalarType)
@Field(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@@ -1,9 +1,6 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql';
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { CoreEntityCacheModule } from 'src/engine/core-entity-cache/core-entity-cache.module';
import { WorkspaceDomainsModule } from 'src/engine/core-modules/domain/workspace-domains/workspace-domains.module';
@@ -23,26 +20,17 @@ import { UserEntity } from 'src/engine/core-modules/user/user.entity';
import { UserResolver } from 'src/engine/core-modules/user/user.resolver';
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
import { ConnectedAccountMetadataModule } from 'src/engine/metadata-modules/connected-account/connected-account-metadata.module';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { userAutoResolverOpts } from './user.auto-resolver-opts';
import { UserService } from './services/user.service';
@Module({
imports: [
NestjsQueryGraphQLModule.forFeature({
imports: [
NestjsQueryTypeOrmModule.forFeature([UserEntity]),
TypeORMModule,
FileModule,
],
resolvers: userAutoResolverOpts,
}),
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity]),
TypeOrmModule.forFeature([UserEntity]),
TypeORMModule,
FileModule,
WorkspaceModule,
OnboardingModule,
TypeOrmModule.forFeature([KeyValuePairEntity, UserWorkspaceEntity]),