remove nestjs-query from app-token and drop unused createOneAppToken mutation (#22765)

## What

Migrates `app-token` off `@ptc-org/nestjs-query` and removes the
auto-generated `createOneAppToken` mutation, which was unused dead API
surface.

## Why

The `createOneAppToken` mutation was reachable only from the schema — no
frontend query, SDK caller, or test used it. It was also non-functional
(its input couldn't set the token `value`), a leftover from
nestjs-query's default `create.one` being left enabled. Real app tokens
(refresh, password-reset, email-verification, invitation, OAuth,
enterprise) are all created directly via the repository in ~14 services,
none of which touched this mutation.

## Notes

- ⚠️ This removes `AppToken`, `createOneAppToken`,
`CreateAppTokenInput`, and `CreateOneAppTokenInput` from the `/metadata`
schema, so the **api-breaking-changes check will flag it**


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22765?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:14:13 +05:30
committed by GitHub
parent 9e20e2222a
commit 4ab36a630b
13 changed files with 701 additions and 980 deletions
@@ -1,42 +0,0 @@
import {
type AutoResolverOpts,
PagingStrategies,
type ReadResolverOpts,
} from '@ptc-org/nestjs-query-graphql';
import { AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
import { CreateAppTokenInput } from 'src/engine/core-modules/app-token/dtos/create-app-token.input';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
export const appTokenAutoResolverOpts: 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: AppTokenEntity,
DTOClass: AppTokenEntity,
CreateDTOClass: CreateAppTokenInput,
enableTotalCount: true,
pagingStrategy: PagingStrategies.CURSOR,
read: {
many: { disabled: true },
one: { disabled: true },
},
create: {
many: { disabled: true },
},
update: {
many: { disabled: true },
one: { disabled: true },
},
delete: { many: { disabled: true }, one: { disabled: true } },
guards: [WorkspaceAuthGuard],
},
];
@@ -1,6 +1,3 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { BeforeCreateOne, IDField } from '@ptc-org/nestjs-query-graphql';
import { isDefined } from 'twenty-shared/utils';
import {
BeforeInsert,
@@ -15,8 +12,6 @@ import {
UpdateDateColumn,
} from 'typeorm';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { BeforeCreateOneAppToken } from 'src/engine/core-modules/app-token/hooks/before-create-one-app-token.hook';
import { UserEntity } from 'src/engine/core-modules/user/user.entity';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
@@ -32,10 +27,7 @@ export enum AppTokenType {
}
@Entity({ name: 'appToken', schema: 'core' })
@ObjectType('AppToken')
@BeforeCreateOne(BeforeCreateOneAppToken)
export class AppTokenEntity {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@@ -57,14 +49,12 @@ export class AppTokenEntity {
@Column({ nullable: true, type: 'uuid' })
workspaceId: string | null;
@Field()
@Column({ nullable: false, type: 'text', default: AppTokenType.RefreshToken })
type: AppTokenType;
@Column({ nullable: true, type: 'text' })
value: string;
@Field()
@Column({ type: 'timestamptz' })
expiresAt: Date;
@@ -74,11 +64,9 @@ export class AppTokenEntity {
@Column({ nullable: true, type: 'timestamptz' })
revokedAt: Date | null;
@Field()
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@Field()
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@@ -1,19 +0,0 @@
import { Module } from '@nestjs/common';
import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql';
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
import { appTokenAutoResolverOpts } from 'src/engine/core-modules/app-token/app-token.auto-resolver-opts';
import { AppTokenService } from 'src/engine/core-modules/app-token/services/app-token.service';
@Module({
imports: [
NestjsQueryGraphQLModule.forFeature({
imports: [NestjsQueryTypeOrmModule.forFeature([AppTokenEntity])],
services: [AppTokenService],
resolvers: appTokenAutoResolverOpts,
}),
],
})
export class AppTokenModule {}
@@ -1,11 +0,0 @@
import { Field, InputType } from '@nestjs/graphql';
import { IsDate, IsNotEmpty } from 'class-validator';
@InputType()
export class CreateAppTokenInput {
@IsDate()
@IsNotEmpty()
@Field()
expiresAt: Date;
}
@@ -1,22 +0,0 @@
import {
type BeforeCreateOneHook,
type CreateOneInputType,
} from '@ptc-org/nestjs-query-graphql';
import { type AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
export class BeforeCreateOneAppToken<
T extends AppTokenEntity,
> implements BeforeCreateOneHook<T> {
async run(
instance: CreateOneInputType<T>,
// oxlint-disable-next-line typescript/no-explicit-any
context: any,
): Promise<CreateOneInputType<T>> {
const userId = context?.req?.user?.id;
instance.input.userId = userId;
return instance;
}
}
@@ -1,32 +0,0 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { AppTokenService } from 'src/engine/core-modules/app-token/services/app-token.service';
import { AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
describe('AppTokenService', () => {
let service: AppTokenService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
AppTokenService,
{
provide: getRepositoryToken(AppTokenEntity),
useValue: {
manager: {
connection: { driver: { options: { type: 'postgres' } } },
},
metadata: { columns: [] },
},
},
],
}).compile();
service = module.get<AppTokenService>(AppTokenService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
@@ -1,15 +0,0 @@
import { InjectRepository } from '@nestjs/typeorm';
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { Repository } from 'typeorm';
import { AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
export class AppTokenService extends TypeOrmQueryService<AppTokenEntity> {
constructor(
@InjectRepository(AppTokenEntity)
private readonly appTokenRepository: Repository<AppTokenEntity>,
) {
super(appTokenRepository);
}
}