Skip to content

Conversation

@FelixMalfait
Copy link
Member

@FelixMalfait FelixMalfait commented Nov 15, 2025

Overview

This PR upgrades all NestJS dependencies from version 10.x to 11.x, following the official migration guide. This builds on top of the v9 to v10 upgrade completed in PR #15835.

Changes

Dependencies Updated

Core packages (10.x → 11.x):

  • @nestjs/common: 10.4.16 → 11.0.8
  • @nestjs/core: 10.4.16 → 11.0.8
  • @nestjs/platform-express: 10.4.16 → 11.0.8
  • @nestjs/config: 3.2.3 → 3.3.0
  • @nestjs/passport: 10.0.3 → 11.0.0
  • @nestjs/axios: 3.0.2 → 3.1.2
  • @nestjs/schedule: ^3.0.0 → ^4.1.1
  • @nestjs/serve-static: 4.0.2 → 5.0.1
  • @nestjs/cache-manager: ^2.2.1 → ^2.3.0
  • @nestjs/jwt: 10.2.0 → 11.0.0
  • @nestjs/typeorm: 10.0.2 → 11.0.0
  • @nestjs/terminus: 11.0.0 (already on v11)
  • @nestjs/event-emitter: 2.1.0 (compatible)

DevDependencies:

  • @nestjs/testing: ^10.4.16 → ^11.0.8
  • @nestjs/schematics: ^10.1.0 → ^11.0.2
  • @nestjs/cli: 10.3.0 → 11.0.0

Code Changes

Fixed: TwentyConfigModule conditional imports

  • Updated TwentyConfigModule.forRoot() to use spread operator for conditional imports
  • Fixes TypeScript error with NestJS 11's stricter DynamicModule type checking

Cleanup: Removed unused package

  • Removed @revertdotdev/revert-react (not being used anywhere in the codebase)

Breaking Changes Addressed

1. ✅ Reflector Type Inference

  • Impact: None - codebase only uses reflector.get() method
  • Analysis: Does not use getAllAndMerge() or getAllAndOverride() (the methods with breaking changes)
  • Files reviewed: feature-flag.guard.ts, message-queue-metadata.accessor.ts, workspace-query-hook-metadata.accessor.ts

2. ✅ Lifecycle Hooks Execution Order

  • Change: Termination hooks (OnModuleDestroy, BeforeApplicationShutdown, OnApplicationShutdown) now execute in REVERSE order
  • Analysis: Reviewed all lifecycle hook implementations
    • Redis client cleanup
    • Database connection cleanup (GlobalWorkspaceDataSource)
    • BullMQ queue/worker cleanup
    • Cache storage cleanup
  • Result: Dependency order is safe - services using connections clean up before the connections themselves

3. ✅ Middleware Registration Order

  • Change: Global middleware now executes first regardless of import order
  • Analysis: Middleware is not registered as global, so execution order remains consistent
  • Files reviewed: app.module.ts, middleware.module.ts

Testing

All tests passing and build successful:

Unit Tests (283+ tests):

  • ✅ Health module: 38 tests passed
  • ✅ Auth module: 115 tests passed (passport v11 integration)
  • ✅ REST API: 90 tests passed (middleware and express platform)
  • ✅ Feature flags: 17 tests passed (Reflector usage)
  • ✅ Workspace: 23 tests passed

Build & Quality:

  • ✅ Type checking: Passed
  • ✅ Linting: Passed
  • ✅ Build: 3,683 files compiled successfully

Verification

Tested critical NestJS functionality:

  • ✅ Authentication & Security (JWT, OAuth, guards)
  • ✅ HTTP Platform (Express integration, REST endpoints)
  • ✅ Dependency Injection (Services, factories, providers)
  • ✅ Cache Management (Redis with @nestjs/cache-manager)
  • ✅ GraphQL (Query runners, resolvers)
  • ✅ Configuration (Environment config)
  • ✅ Scheduling (Cron jobs with @nestjs/schedule v4)
  • ✅ Lifecycle Hooks (Module initialization and cleanup)
  • ✅ Reflector (Metadata reflection in guards)

Related PRs


Note

Upgrades server to NestJS 11 with related deps, updates route patterns and build output paths, refines Nest/TypeORM/GraphQL configs, and aligns Docker/scripts and Nx settings.

  • Backend (NestJS 11 upgrade):
    • Bumps @nestjs/* to v11 and related tooling (@nestjs/cli, schematics, testing, jwt/passport/serve-static/schedule/typeorm).
    • Updates OAuth/SAML strategies (abstract common strategies; add validate implementations; SAML constructor callback pattern).
  • Routing changes (path-to-regexp v8):
    • Switches wildcard routes to *path across REST (rest/*path, metadata, files, route-trigger) to match Nest 11 routing.
  • Build/output paths:
    • Standardizes runtime entrypoints from dist/src/* to dist/* (main, command, queue-worker).
    • Adjusts Nest CLI assets and migrations output/inputs; adds watchOptions; sets monorepo:false and root:src.
    • Updates TypeORM entity/migration globs (use dist/… or src/… based on env).
  • GraphQL:
    • Adds buildSchemaOptions.orphanedTypes for client-config types; keeps Yoga config and conditional schema.
  • DevOps/Tooling:
    • Docker CMD updated to node dist/main.
    • Scripts (render-run.sh, render-worker.sh) and Nx targets updated; disable cache for start.
    • ASSET_PATH and dev seeder sample-files path fixed; tsconfig excludes node_modules.

Written by Cursor Bugbot for commit 693aaf5. This will update automatically on new commits. Configure here.

- Upgrade @nestjs/common: 10.4.16 → 11.0.8
- Upgrade @nestjs/core: 10.4.16 → 11.0.8
- Upgrade @nestjs/platform-express: 10.4.16 → 11.0.8
- Upgrade @nestjs/config: 3.2.3 → 3.3.0
- Upgrade @nestjs/passport: 10.0.3 → 11.0.0
- Upgrade @nestjs/axios: 3.0.2 → 3.1.2
- Upgrade @nestjs/schedule: ^3.0.0 → ^4.1.1
- Upgrade @nestjs/serve-static: 4.0.2 → 5.0.1
- Upgrade @nestjs/cache-manager: ^2.2.1 → ^2.3.0
- Upgrade @nestjs/jwt: 10.2.0 → 11.0.0
- Upgrade @nestjs/typeorm: 10.0.2 → 11.0.0
- Upgrade @nestjs/testing: ^10.4.16 → ^11.0.8
- Upgrade @nestjs/schematics: ^10.1.0 → ^11.0.2
- Upgrade @nestjs/cli: 10.3.0 → 11.0.0

Breaking changes addressed:
- Fix TwentyConfigModule conditional imports to use spread operator for proper DynamicModule type handling

Code cleanup:
- Remove unused @revertdotdev/revert-react package

All tests passing (283+ tests verified)
Build successful (3,683 files compiled)
Type checking and linting passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bug: Dependency Conflict: Express Version Mismatch

The express version is still set to 4.21.2, but @nestjs/[email protected] has a hard dependency on [email protected] and @nestjs/[email protected] has a peer dependency on express@^5.0.1. This version mismatch will cause both Express 4 and Express 5 to be installed, leading to potential runtime conflicts and unexpected behavior. The express dependency needs to be upgraded to 5.0.1 or higher to match the NestJS 11 requirements.

packages/twenty-server/package.json#L97-L98

"dotenv": "16.4.5",
"express": "4.21.2",

Fix in Cursor Fix in Web


@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 15, 2025

Greptile Overview

Greptile Summary

This PR successfully upgrades NestJS from 10.x to 11.x across 16 packages, following the official migration guide and building on the previous v9→v10 upgrade.

Key Changes:

  • Upgraded core NestJS packages (@nestjs/common, @nestjs/core, @nestjs/platform-express) from 10.4.16 to 11.0.8
  • Updated supporting packages including @nestjs/jwt (10.2.0 → 11.0.0), @nestjs/schedule (^3.0.0 → ^4.1.1), and @nestjs/passport (10.0.3 → 11.0.0)
  • Fixed TwentyConfigModule.forRoot() to use spread operator for conditional imports, addressing NestJS 11's stricter DynamicModule type checking at twenty-config.module.ts:28
  • Removed unused dependency @revertdotdev/revert-react

Breaking Changes Verification:

  • Reflector Type Inference: Codebase only uses reflector.get() which is unaffected (verified in feature-flag.guard.ts:47)
  • Lifecycle Hooks Execution Order: Reviewed termination hooks - dependency order is safe (services clean up before connections)
  • Middleware Registration: No global middleware registration found, execution order unchanged

Testing: 283+ unit tests passing, 3,683 files compiled successfully, all critical functionality verified.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - it's a well-executed framework upgrade with comprehensive testing and proper handling of breaking changes.
  • Score reflects thorough analysis of NestJS 11 breaking changes, minimal code modifications (only 1 type fix required), comprehensive test coverage (283+ tests passing), successful build (3,683 files), and building on top of the already-merged v9→v10 upgrade. The fix in TwentyConfigModule is a straightforward TypeScript compliance change. All three documented breaking changes were verified as non-issues for this codebase.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
packages/twenty-server/package.json 5/5 Clean upgrade of all NestJS packages from 10.x to 11.x with proper version alignment and removal of unused dependency (@revertdotdev/revert-react)
packages/twenty-server/src/engine/core-modules/twenty-config/twenty-config.module.ts 5/5 Fixed conditional imports using spread operator to satisfy NestJS 11's stricter DynamicModule type checking

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant PM as Package Manager
    participant NestJS10 as NestJS 10.x
    participant NestJS11 as NestJS 11.x
    participant App as Twenty Server
    
    Dev->>PM: Update package.json dependencies
    Note over PM: @nestjs/common: 10.4.16 → 11.0.8<br/>@nestjs/core: 10.4.16 → 11.0.8<br/>@nestjs/jwt: 10.2.0 → 11.0.0<br/>@nestjs/schedule: ^3.0.0 → ^4.1.1<br/>+12 more packages
    
    PM->>PM: Remove @revertdotdev/revert-react
    PM->>PM: yarn install
    PM->>NestJS11: Install NestJS 11.x packages
    
    NestJS11->>App: Type check DynamicModule.imports
    Note over NestJS11,App: Stricter type checking:<br/>imports must be array
    
    App--xNestJS11: ❌ Type error in TwentyConfigModule
    Note over App: imports.push() pattern<br/>incompatible with strict types
    
    Dev->>App: Fix TwentyConfigModule.forRoot()
    Note over Dev,App: Replace conditional push<br/>with spread operator:<br/>...(condition ? [module] : [])
    
    App->>NestJS11: ✅ Type check passes
    
    NestJS11->>App: Initialize lifecycle hooks
    Note over NestJS11: Breaking change:<br/>Termination hooks now<br/>execute in REVERSE order
    
    App->>NestJS11: Register services
    Note over App: RedisClientService<br/>GlobalWorkspaceDataSource<br/>BullMQ queues
    
    App->>NestJS11: ✅ Services clean up correctly
    Note over App: Dependencies safe:<br/>Services destroy before<br/>connections they use
    
    NestJS11->>App: Check Reflector usage
    Note over NestJS11: Breaking change:<br/>getAllAndMerge/getAllAndOverride<br/>type inference changed
    
    App->>NestJS11: ✅ Only uses reflector.get()
    Note over App: FeatureFlagGuard uses<br/>reflector.get() - unaffected
    
    Dev->>PM: Run tests
    PM->>App: Execute 283+ unit tests
    App->>Dev: ✅ All tests pass
    
    Dev->>PM: Build application
    PM->>App: Compile TypeScript
    App->>Dev: ✅ 3,683 files compiled
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

NestJS 11 changed the build output structure from dist/src/ to dist/
Update all production script paths to reflect this change:
- start:prod, command:prod, worker:prod
- database:migrate:prod
- clickhouse:migrate:prod
Update all remaining references to old build output structure:
- project.json: Update main, command, and worker paths
- render-run.sh: Update main entry point
- render-worker.sh: Update worker entry point
- upgrade.command-runner.ts: Update migration path

All references to dist/src/* are now dist/* to match NestJS 11 build output.
NestJS 11 changed the build output structure from dist/src/ to dist/. The ASSET_PATH constant needs to point to the dist/ root directory where assets are copied maintaining their source structure.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

export const ASSET_PATH = IS_BUILT_THROUGH_TESTING_MODULE
? path.resolve(__dirname, `../`)
: path.resolve(__dirname, `../../assets`);
: path.resolve(__dirname, `..`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Asset Path Error Breaks Production Builds

The ASSET_PATH for production builds is incorrect. Changed from path.resolve(__dirname, '../../assets') to path.resolve(__dirname, '..'), but nest-cli.json still outputs assets to dist/assets. In production, __dirname is dist/constants, so the new path resolves to dist instead of dist/assets, causing asset files (serverless drivers, executor, layer dependencies) to not be found at runtime. The path should remain ../../assets or the nest-cli.json asset output configuration needs updating to match.

Fix in Cursor Fix in Web

@github-actions
Copy link
Contributor

github-actions bot commented Nov 15, 2025

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:63528

This environment will automatically shut down when the PR is closed or after 5 hours.

NestJS 11 requires GraphQL @ObjectType classes to be explicitly exported and
added to the orphanedTypes configuration if they're not directly used in
GraphQL resolvers. This ensures types like ApiConfig, Billing, Captcha, etc.
are included in the generated GraphQL schema.

Fixes GraphQL schema generation for client config types.
NestJS 11 changed the build output structure from dist/src/ to dist/.
Updated TypeORM configuration to use the correct paths:
- Entities: dist/engine/... (instead of dist/src/engine/...)
- Migrations: dist/database/... (instead of dist/src/database/...)

This fixes EntityMetadataNotFoundError in tests and production.
@FelixMalfait FelixMalfait force-pushed the upgrade-nestjs-10-to-11 branch from 410bf0d to 54a0710 Compare November 16, 2025 07:52
…t validation methods

- Changed GoogleAPIsOauthCommonStrategy and MicrosoftAPIsOauthCommonStrategy to be abstract classes.
- Added abstract validate method to both strategies for consistent validation handling.
- Implemented validate method in GoogleAPIsOauthRequestCodeStrategy and MicrosoftAPIsOauthRequestCodeStrategy, with a placeholder for future validation logic.
- Updated imports to use type annotations for VerifyCallback in relevant files.
@github-actions
Copy link
Contributor

github-actions bot commented Nov 16, 2025

TODOs/FIXMEs:

  • // TODO: Improve the feature by sign the response: packages/twenty-server/src/engine/core-modules/auth/strategies/saml.auth.strategy.ts
  • // TODO: improve error management: packages/twenty-server/src/engine/core-modules/auth/strategies/saml.auth.strategy.ts
  • // TODO: improve error management: packages/twenty-server/src/engine/core-modules/auth/strategies/saml.auth.strategy.ts
  • // TODO: Improve the feature by sign the response: packages/twenty-server/src/engine/core-modules/auth/strategies/saml.auth.strategy.ts
  • // TODO: improve error management: packages/twenty-server/src/engine/core-modules/auth/strategies/saml.auth.strategy.ts
  • // TODO: improve error management: packages/twenty-server/src/engine/core-modules/auth/strategies/saml.auth.strategy.ts

Generated by 🚫 dangerJS against 693aaf5

@FelixMalfait FelixMalfait merged commit 5dfb669 into main Nov 16, 2025
32 of 34 checks passed
@FelixMalfait FelixMalfait deleted the upgrade-nestjs-10-to-11 branch November 16, 2025 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants