chore(api-service, worker, ws): upgrade to nest js v11#10653
chore(api-service, worker, ws): upgrade to nest js v11#10653
Conversation
✅ Deploy Preview for dashboard-v2-novu-staging canceled.
|
|
Hey there and thank you for opening this pull request! 👋 We require pull request titles to follow specific formatting rules and it looks like your proposed title needs to be adjusted. Your PR title is: Requirements:
Expected format: Details: PR title must end with 'fixes TICKET-ID' (e.g., 'fixes NOV-123') or include ticket ID in branch name |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughMonorepo-wide updates: bumped NestJS 10→11 across packages, standardized Swagger optional decorators and object type metadata, adjusted Express query parsing to extended, refactored API key Passport strategy, switched runtime dynamic requires to static/typed imports in tests/EE helpers, and updated test runner/configs and SDK generated models/types. Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
|
Update Swagger ApiProperty decorators to emit enums as strings in the OpenAPI schema. Replace enum class types with type: String and add enumName where needed; also adjust the example for actionType to a string. Files updated: subscriber-notification-action.dto.ts (actionType) and feeds-response.dto.ts (ActorFeedItemDto.type, NotificationFeedItemDto.channel). This ensures correct schema generation and consistent string examples in the API docs.
@novu/agent-toolkit
@novu/framework
novu
@novu/providers
@novu/shared
commit: |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/shared/package.json (1)
35-45:⚠️ Potential issue | 🟠 MajorExport map shape must use nested
typeswithin condition-specific entries, not siblingtypes.The current flat structure causes both CJS and ESM consumers to resolve the same
.d.tsfile, creating type mismatches. Nesttypesinsiderequireandimportconditions, and provide condition-specific declarations (.d.ctsfor CJS,.d.tsfor ESM) aspackages/frameworkdoes. This follows TypeScript 4.7+ export field guidance and ensures correct type resolution for both module kinds.Per coding guidelines,
packages/shared/**requires extra care—changes affect the entire monorepo and must maintain backward compatibility. Verify semver implications before applying this fix.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/shared/package.json` around lines 35 - 45, The exports map in package.json currently places "types" as a sibling to "require" and "import", causing both CJS and ESM consumers to resolve the same .d.ts; update the "exports" object (including the "./" and "./utils" entries) to nest "types" inside each condition-specific entry so "require" points to a CJS declaration (e.g. .d.cts) and "import" points to an ESM declaration (e.g. .d.ts), mirroring packages/framework's shape; ensure you add/emit the corresponding .d.cts and .d.ts outputs and run type checks, and confirm this change is semver-safe for the monorepo before merging.libs/application-generic/src/dtos/step-filter-dto.ts (1)
131-141:⚠️ Potential issue | 🟠 MajorFix optionality decorators:
isNegatedandtypeare optional but use@ApiPropertyinstead of@ApiPropertyOptional.Lines 117–118 and 120–124 declare optional properties with
?but use@ApiProperty. Change to@ApiPropertyOptionalto align with the DTO optionality guidelines:
- Line 118:
isNegated?: boolean→ use@ApiPropertyOptional()- Lines 120–124:
type?: BuilderFieldType→ use@ApiPropertyOptional({...})while preserving theenumandenumNamepropertiesThe
childrenproperty at line 131–141 is correctly decorated as required with@ApiProperty.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/application-generic/src/dtos/step-filter-dto.ts` around lines 131 - 141, The optional properties isNegated and type in the DTO are decorated with `@ApiProperty` but should use `@ApiPropertyOptional`; update the decorator on isNegated to `@ApiPropertyOptional`() and change the decorator on type to `@ApiPropertyOptional`({ enum: BuilderFieldType, enumName: 'BuilderFieldType' }) while preserving the optional ? in their declarations; leave the children property (children: FilterPartsDto[]) and its `@ApiProperty` decorator unchanged.enterprise/packages/shared-services/package.json (1)
1-47:⚠️ Potential issue | 🟡 MinorPlease confirm the mirrored enterprise PR is opened and linked.
This PR updates
enterprise/...; please add the correspondingnovuhq/packages-enterprisePR link (branched fromnext) in the description for traceability/release sync.Based on learnings: When changes touch
enterprise/directory, also open a matching PR innovuhq/packages-enterpriserepository on a branch fromnext.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@enterprise/packages/shared-services/package.json` around lines 1 - 47, This change touches enterprise/ (package `@novu/ee-shared-services`); open a mirrored PR in the novuhq/packages-enterprise repo branched from next and add that PR URL to this PR description for traceability; ensure the enterprise PR branch is created from next, mention the corresponding package (`@novu/ee-shared-services`) in the enterprise PR title/body, and paste the enterprise PR link into this PR description.
🧹 Nitpick comments (3)
libs/application-generic/src/decorators/user-session.decorator.ts (1)
5-5: Prefer a typedgetType()check overas string.Nest documents GraphQL context detection via a typed
getType<...>()call; casting the result tostringjust suppresses the Nest 11 typing without preserving the contract. A union generic keeps the comparison typed and self-documenting. (docs.nestjs.com)♻️ Suggested change
- if ((ctx.getType() as string) === 'graphql') { + if (ctx.getType<'http' | 'ws' | 'rpc' | 'graphql'>() === 'graphql') {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/application-generic/src/decorators/user-session.decorator.ts` at line 5, Replace the unchecked cast "(ctx.getType() as string) === 'graphql'" in the user-session decorator with a typed getType call so the comparison is type-safe: call ctx.getType<'graphql' | 'http' | 'rpc'>() (or the minimal union your app uses) and compare the returned value to 'graphql' in the decorator function that receives the ExecutionContext (ctx) so the check is properly typed and self-documenting.apps/worker/src/app/shared/response.interceptor.ts (1)
13-14: LGTM - type cast aligns with NestJS 11 changes.The explicit cast
(context.getType() as string)is necessary in NestJS 11 wheregetType()returns a more specific type. This pattern is consistently applied across both API and worker response interceptors.Consider adding explicit type annotation for improved clarity:
♻️ Optional: Add explicit type annotation
- intercept(context, next: CallHandler): Observable<Response<T>> { + intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {With import:
-import { CallHandler, Injectable, NestInterceptor } from '@nestjs/common'; +import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/worker/src/app/shared/response.interceptor.ts` around lines 13 - 14, The intercept method lacks an explicit type for the first parameter; update the signature to intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> and add the ExecutionContext import from '@nestjs/common' so the existing cast (context.getType() as string) is clearly typed and consistent with other interceptors (reference symbols: intercept, ExecutionContext, CallHandler, Response<T>).apps/ws/package.json (1)
25-33: Migrateapp.flushLogs()as part of the NestJS 11 bump.In
apps/ws/src/bootstrap.ts(line 25),app.flushLogs()is deprecated in NestJS 11. Update the bootstrap logging setup to use the native NestJS 11 flow.Also applies to: 63-65
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/ws/package.json` around lines 25 - 33, Replace deprecated app.flushLogs() calls in bootstrap.ts with NestJS 11 native logging configuration: remove any app.flushLogs() invocations and instead configure logging when creating the app (pass the logger option to NestFactory.create or call Logger.overrideLogger(...) before bootstrap completes) and ensure logs are flushed by awaiting app.init() / app.listen(...) normally; update both occurrences that reference app.flushLogs() so logging is driven by NestFactory.create and Logger.overrideLogger rather than the removed app.flushLogs() method.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/api/src/app/shared/dtos/subscriptions/create-subscriptions.dto.ts`:
- Around line 42-48: The DTO property enabled is only marked `@IsOptional`() so
non-boolean values like "false" or 1 pass validation; add the class-validator
boolean check by applying `@IsBoolean`() to the enabled property (keep
`@IsOptional`() and `@ApiPropertyOptional`) and update imports in
create-subscriptions.dto.ts to include IsBoolean so the DTO enforces a true
boolean type at validation time.
In `@apps/api/src/config/cors.config.ts`:
- Around line 2-8: The exported CORS delegate is incorrectly typed and uses the
global Fetch Request; import Request from 'express' and change the export
signature to use Nest's CorsOptionsDelegate<Request> so the function signature
matches (replace the current Parameters<INestApplication['enableCors']>[0] with
CorsOptionsDelegate<Request]); update the top imports to include Request from
'express' and ensure the exported symbol corsOptionsDelegate keeps the same
implementation but with the new type so tests no longer need `@ts-expect-error` or
the null-as-Error cast.
In `@apps/ws/src/bootstrap.ts`:
- Around line 18-19: The token extraction is vulnerable to array values when
Express query parser is 'extended'; update the extractToken function in
ws.gateway.ts to explicitly check typeof token === 'string' (and non-empty)
before returning it, and ensure places that call jwtService.verify (e.g., in
handleConnection / validateConnection) only receive a string token — treat
arrays or non-string values as invalid (return null or undefined) so the
existing falsy/null checks (token === 'null') handle them instead of letting
arrays reach jwtService.verify.
---
Outside diff comments:
In `@enterprise/packages/shared-services/package.json`:
- Around line 1-47: This change touches enterprise/ (package
`@novu/ee-shared-services`); open a mirrored PR in the novuhq/packages-enterprise
repo branched from next and add that PR URL to this PR description for
traceability; ensure the enterprise PR branch is created from next, mention the
corresponding package (`@novu/ee-shared-services`) in the enterprise PR
title/body, and paste the enterprise PR link into this PR description.
In `@libs/application-generic/src/dtos/step-filter-dto.ts`:
- Around line 131-141: The optional properties isNegated and type in the DTO are
decorated with `@ApiProperty` but should use `@ApiPropertyOptional`; update the
decorator on isNegated to `@ApiPropertyOptional`() and change the decorator on
type to `@ApiPropertyOptional`({ enum: BuilderFieldType, enumName:
'BuilderFieldType' }) while preserving the optional ? in their declarations;
leave the children property (children: FilterPartsDto[]) and its `@ApiProperty`
decorator unchanged.
In `@packages/shared/package.json`:
- Around line 35-45: The exports map in package.json currently places "types" as
a sibling to "require" and "import", causing both CJS and ESM consumers to
resolve the same .d.ts; update the "exports" object (including the "./" and
"./utils" entries) to nest "types" inside each condition-specific entry so
"require" points to a CJS declaration (e.g. .d.cts) and "import" points to an
ESM declaration (e.g. .d.ts), mirroring packages/framework's shape; ensure you
add/emit the corresponding .d.cts and .d.ts outputs and run type checks, and
confirm this change is semver-safe for the monorepo before merging.
---
Nitpick comments:
In `@apps/worker/src/app/shared/response.interceptor.ts`:
- Around line 13-14: The intercept method lacks an explicit type for the first
parameter; update the signature to intercept(context: ExecutionContext, next:
CallHandler): Observable<Response<T>> and add the ExecutionContext import from
'@nestjs/common' so the existing cast (context.getType() as string) is clearly
typed and consistent with other interceptors (reference symbols: intercept,
ExecutionContext, CallHandler, Response<T>).
In `@apps/ws/package.json`:
- Around line 25-33: Replace deprecated app.flushLogs() calls in bootstrap.ts
with NestJS 11 native logging configuration: remove any app.flushLogs()
invocations and instead configure logging when creating the app (pass the logger
option to NestFactory.create or call Logger.overrideLogger(...) before bootstrap
completes) and ensure logs are flushed by awaiting app.init() / app.listen(...)
normally; update both occurrences that reference app.flushLogs() so logging is
driven by NestFactory.create and Logger.overrideLogger rather than the removed
app.flushLogs() method.
In `@libs/application-generic/src/decorators/user-session.decorator.ts`:
- Line 5: Replace the unchecked cast "(ctx.getType() as string) === 'graphql'"
in the user-session decorator with a typed getType call so the comparison is
type-safe: call ctx.getType<'graphql' | 'http' | 'rpc'>() (or the minimal union
your app uses) and compare the returned value to 'graphql' in the decorator
function that receives the ExecutionContext (ctx) so the check is properly typed
and self-documenting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 1f036fc3-5a0a-4006-b5ca-6eb84042f43c
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (45)
.sourceapps/api/package.jsonapps/api/scripts/generate-metadata.tsapps/api/src/app/auth/framework/community.user.auth.guard.tsapps/api/src/app/auth/services/passport/apikey.strategy.tsapps/api/src/app/contexts/dtos/create-context-request.dto.tsapps/api/src/app/contexts/dtos/update-context-request.dto.tsapps/api/src/app/events/dtos/trigger-event-request.dto.tsapps/api/src/app/events/dtos/trigger-event-to-all-request.dto.tsapps/api/src/app/layouts-v2/dtos/generate-layout-preview-response.dto.tsapps/api/src/app/notifications/dtos/activities-response.dto.tsapps/api/src/app/shared/dtos/subscriptions/create-subscriptions-response.dto.tsapps/api/src/app/shared/dtos/subscriptions/create-subscriptions.dto.tsapps/api/src/app/shared/framework/response.interceptor.tsapps/api/src/app/shared/framework/user.decorator.tsapps/api/src/app/subscribers-v2/dtos/get-subscriber-notifications-response.dto.tsapps/api/src/app/widgets/dtos/feeds-response.dto.tsapps/api/src/bootstrap.tsapps/api/src/config/cors.config.tsapps/api/src/error-dto.tsapps/webhook/src/shared/framework/user.decorator.tsapps/worker/package.jsonapps/worker/src/app/shared/response.interceptor.tsapps/worker/src/bootstrap.tsapps/ws/package.jsonapps/ws/src/bootstrap.tsenterprise/packages/ai/package.jsonenterprise/packages/api/package.jsonenterprise/packages/auth/package.jsonenterprise/packages/billing/package.jsonenterprise/packages/shared-services/package.jsonenterprise/packages/translation/package.jsonlibs/application-generic/package.jsonlibs/application-generic/src/decorators/context-payload.decorator.tslibs/application-generic/src/decorators/user-session.decorator.tslibs/application-generic/src/dtos/step-filter-dto.tslibs/application-generic/src/dtos/workflow/generate-preview-response.dto.tslibs/application-generic/src/webhooks/dtos/webhook-payload.dto.tslibs/application-generic/tsconfig.jsonlibs/application-generic/tsconfig.module.jsonlibs/dal/package.jsonlibs/notifications/package.jsonpackage.jsonpackages/framework/package.jsonpackages/shared/package.json
|
@cursoragent fix the failing tests api e2e |
|
Here is what was wrong and what I changed. Root causes
Files touched
Committed as Note: A full shard run is long in this environment; after these fixes, bootstrap proceeds past Swagger and listens once. If anything still fails in CI, grab the first failing test name from the shard log. |
…eps) - Remove invalid Node --no-experimental-strip-types from api mocha scripts and .mocharc - Stop loading e2e/setup.ts twice (mocharc + shard script) to avoid EADDRINUSE on PORT - Fix Nest Swagger v11 circular schema on ButtonTypeEnum path params via ParseEnumPipe + string reflection - Declare @novu/ee-auth and @novu/application-generic on @novu/testing for dynamic requires Co-authored-by: Dima Grossman <dima@grossman.io>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/api/package.json`:
- Around line 49-57: Remove the unused nest-raven dependency from
apps/api/package.json (delete the "nest-raven@10.1.0" entry) because it requires
`@nestjs/common` v10 and will break peer deps after upgrading to NestJS 11; also
check for any imports/usages of nest-raven in the codebase (search for
"nest-raven") and delete them if present. For Sentry, locate any references to
"@sentry/nestjs" (package.json and any imports like SentryModule or
SentryService) and either disable the Sentry integration or plan/make a
migration to a version that supports NestJS 11 before merging. Ensure
package.json and lockfile are updated (run install) after removing the
dependency.
- Line 34: The npm script "test:e2e:novu-v0" is passing --file e2e/setup.ts
explicitly which duplicates the "file": ["e2e/setup.ts"] already defined in
.mocharc.json and causes the setup to run twice; edit the "test:e2e:novu-v0"
script to remove the `--file e2e/setup.ts` flag so Mocha uses the configuration
from .mocharc.json and the e2e/setup.ts file is loaded only once.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3bab3e29-67cf-4fec-b46c-f18ab651e451
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
apps/api/.mocharc.jsonapps/api/package.jsonapps/api/scripts/run-novu-v2-e2e-shard.cjsapps/api/src/app/subscribers-v2/subscribers.controller.tsapps/api/src/app/subscribers/subscribersV1.controller.tslibs/testing/package.json
💤 Files with no reviewable changes (2)
- apps/api/.mocharc.json
- apps/api/scripts/run-novu-v2-e2e-shard.cjs
✅ Files skipped from review due to trivial changes (1)
- libs/testing/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/api/src/app/subscribers/subscribersV1.controller.ts
- apps/api/src/app/subscribers-v2/subscribers.controller.ts
| "@nestjs/axios": "4.0.1", | ||
| "@nestjs/common": "11.1.18", | ||
| "@nestjs/core": "11.1.18", | ||
| "@nestjs/jwt": "11.0.2", | ||
| "@nestjs/passport": "11.0.5", | ||
| "@nestjs/platform-express": "11.1.18", | ||
| "@nestjs/swagger": "11.2.6", | ||
| "@nestjs/terminus": "11.1.1", | ||
| "@nestjs/throttler": "6.5.0", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== nest-raven usage in apps/api =="
rg -n -C2 "from ['\"]nest-raven['\"]|\\bRaven(Module|Interceptor)\\b" apps/api || true
echo
python - <<'PY'
import json, pathlib
pkg = json.loads(pathlib.Path("apps/api/package.json").read_text())
for name in ("@nestjs/common", "@nestjs/core", "nest-raven", "@sentry/nestjs"):
value = pkg.get("dependencies", {}).get(name) or pkg.get("devDependencies", {}).get(name)
print(f"{name}: {value}")
PY
echo
npm view "nest-raven@10.1.0" peerDependencies --json
npm view "@sentry/nestjs@8.49.0" peerDependencies --jsonRepository: novuhq/novu
Length of output: 1060
Remove the unused nest-raven dependency; it doesn't support NestJS 11.
The nest-raven@10.1.0 package has a peer dependency constraint of @nestjs/common@^10.0.0, which excludes NestJS 11. Since nest-raven is not imported anywhere in the codebase, it should be removed to avoid a broken peer dependency after this upgrade.
Additionally, @sentry/nestjs@8.49.0 also does not yet support NestJS 11 (max supported is v10). Verify that Sentry integration is either disabled or plan a migration to a compatible version before merging.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/api/package.json` around lines 49 - 57, Remove the unused nest-raven
dependency from apps/api/package.json (delete the "nest-raven@10.1.0" entry)
because it requires `@nestjs/common` v10 and will break peer deps after upgrading
to NestJS 11; also check for any imports/usages of nest-raven in the codebase
(search for "nest-raven") and delete them if present. For Sentry, locate any
references to "@sentry/nestjs" (package.json and any imports like SentryModule
or SentryService) and either disable the Sentry integration or plan/make a
migration to a version that supports NestJS 11 before merging. Ensure
package.json and lockfile are updated (run install) after removing the
dependency.
Add a generated UiComponentEnum model (zod native enum + ClosedEnum type) under libs/internal-sdk/src/models/components and export it from the components index. Also comment out the call to patchOpenEnumSchemas in the Swagger SDK document publishing flow to skip enum schema patching during SDK generation.
Simplify and clean up several areas: - Swagger: Add pascalSchemaNameToSpeakeasyNameOverride and enable patchOpenEnumSchemas to set x-speakeasy-unknown-values and x-speakeasy-name-override for UiComponentEnum (maps PascalCase to snake_case for Speakeasy). - WS gateway: Simplify extractToken to read from handshake.auth or handshake.query directly and add a string type assertion when verifying the JWT. - Preferences usecases: Remove InMemoryLRUCacheService import/usage and cache invalidation from UpsertPreferences, adjust constructor accordingly, and simplify upsert flow to return updated/created preference directly. In MergePreferences, return mergedPreferences.type instead of computing a separate mergedType. These changes reduce complexity, remove stale cache logic, and ensure proper enum name overrides for SDK generation.
There was a problem hiding this comment.
Pull request overview
Upgrades the monorepo’s NestJS ecosystem from v10 to v11, aligning Swagger/type usage with NestJS v11 expectations, updating bootstraps for Express v5 query parsing, and refreshing generated internal SDK types/queries to match the updated API surface.
Changes:
- Bumps NestJS dependencies/peers/dev deps to v11 across apps/libs/packages (plus related tooling updates).
- Updates API bootstraps to use
NestExpressApplicationand restores Express v4-style nested query parsing viaapp.set('query parser', 'extended'). - Refactors Swagger decorators/types and updates generated internal SDK (models + react-query helpers), plus Mocha/Jest config adjustments.
Reviewed changes
Copilot reviewed 135 out of 150 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/package.json | Fixes exports.types paths to .d.ts outputs. |
| packages/framework/package.json | Updates Nest peer/dev dependency constraints for v11 compatibility. |
| package.json | Updates pnpm overrides (Nest v11) and build dependency allow/ignore lists. |
| libs/testing/src/ee/ee.repository.factory.ts | Introduces dynamic require() helper to avoid Nx-inferred dependency edges. |
| libs/notifications/package.json | Switches TS declaration field from typings to types. |
| libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.ts | Adds components import and updates query key parameter typing. |
| libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.ts | Adds feedId to query key inputs and imports components. |
| libs/internal-sdk/src/react-query/subscribersNotificationsList.ts | Adds components import and updates query key parameter typing. |
| libs/internal-sdk/src/react-query/subscribersNotificationsList.core.ts | Adds tags to query key inputs and imports components. |
| libs/internal-sdk/src/react-query/subscribersNotificationsFeed.ts | Adds components import and updates query key parameter typing. |
| libs/internal-sdk/src/react-query/subscribersNotificationsFeed.core.ts | Adds feedIdentifier to query key inputs and imports components. |
| libs/internal-sdk/src/react-query/channelEndpointsUpdate.ts | Renames mutation key segments for channel endpoints. |
| libs/internal-sdk/src/react-query/channelEndpointsRetrieve.ts | Renames query key segments for channel endpoints retrieve invalidation. |
| libs/internal-sdk/src/react-query/channelEndpointsRetrieve.core.ts | Renames query key segments for channel endpoints retrieve. |
| libs/internal-sdk/src/react-query/channelEndpointsList.ts | Renames query key segments for channel endpoints list invalidation. |
| libs/internal-sdk/src/react-query/channelEndpointsList.core.ts | Renames query key segments for channel endpoints list. |
| libs/internal-sdk/src/react-query/channelEndpointsDelete.ts | Renames mutation key segments for channel endpoints delete. |
| libs/internal-sdk/src/react-query/channelEndpointsCreate.ts | Renames mutation key segments for channel endpoints create. |
| libs/internal-sdk/src/react-query/channelConnectionsUpdate.ts | Renames mutation key segments for channel connections. |
| libs/internal-sdk/src/react-query/channelConnectionsRetrieve.ts | Renames query key segments for channel connections retrieve invalidation. |
| libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts | Renames query key segments for channel connections retrieve. |
| libs/internal-sdk/src/react-query/channelConnectionsList.ts | Renames query key segments for channel connections list invalidation. |
| libs/internal-sdk/src/react-query/channelConnectionsList.core.ts | Renames query key segments for channel connections list. |
| libs/internal-sdk/src/react-query/channelConnectionsDelete.ts | Renames mutation key segments for channel connections delete. |
| libs/internal-sdk/src/react-query/channelConnectionsCreate.ts | Renames mutation key segments for channel connections create. |
| libs/internal-sdk/src/models/operations/subscribersv1controllermarkactionasseen.ts | Adds a closed enum for action type and enforces it in outbound schema. |
| libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts | Adds feedId query param typing/schema for unseen count. |
| libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts | Adds feedIdentifier query param typing/schema for notifications feed. |
| libs/internal-sdk/src/models/operations/subscriberscontrollergetsubscribernotifications.ts | Adds tags query param typing/schema for notifications list. |
| libs/internal-sdk/src/models/operations/messagescontrollergetmessages.ts | Removes redundant comment for channel query param. |
| libs/internal-sdk/src/models/components/workflowresponsedto.ts | Fixes field description wording (“workflow” vs “layout”). |
| libs/internal-sdk/src/models/components/workflowlistresponsedto.ts | Improves wording for status/origin descriptions. |
| libs/internal-sdk/src/models/components/updateworkflowdto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/uischemaproperty.ts | Inlines UI component enum as an open enum and updates inbound schema wiring. |
| libs/internal-sdk/src/models/components/uicomponentenum.ts | Removes generated standalone UI component enum file (inlined elsewhere). |
| libs/internal-sdk/src/models/components/triggereventtoallrequestdto.ts | Improves wording for severity override description. |
| libs/internal-sdk/src/models/components/triggereventrequestdto.ts | Improves wording for severity override description. |
| libs/internal-sdk/src/models/components/throttlestepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/syncresultdto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/syncedworkflowdto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/subscriptionpreferencedto.ts | Improves severity wording. |
| libs/internal-sdk/src/models/components/subscriberpreferenceoverridedto.ts | Improves channel override wording. |
| libs/internal-sdk/src/models/components/stepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/smsstepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/skippedworkflowdto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/severitylevelenum.ts | Updates severity enum docs text. |
| libs/internal-sdk/src/models/components/resourcetopublishdto.ts | Fixes resource type description wording. |
| libs/internal-sdk/src/models/components/resourceoriginenum.ts | Fixes origin enum docs text. |
| libs/internal-sdk/src/models/components/resourcediffresultdto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/resourcediffdto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/resourcedependencydto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/pushstepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/providersidenum.ts | Adjusts provider ID docs text. |
| libs/internal-sdk/src/models/components/object.ts | Adds a generated “object” component type used by operations/react-query typings. |
| libs/internal-sdk/src/models/components/notificationworkflowdto.ts | Improves severity wording. |
| libs/internal-sdk/src/models/components/notificationfeeditemdto.ts | Improves channel field wording. |
| libs/internal-sdk/src/models/components/messagebutton.ts | Improves button type wording. |
| libs/internal-sdk/src/models/components/index.ts | Exports new object component and removes uicomponentenum export. |
| libs/internal-sdk/src/models/components/inboxnotificationdto.ts | Improves wording for channelType/severity docs. |
| libs/internal-sdk/src/models/components/inappstepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/httprequeststepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/getpreferencesresponsedto.ts | Improves severity wording. |
| libs/internal-sdk/src/models/components/failedworkflowdto.ts | Fixes resourceType description wording. |
| libs/internal-sdk/src/models/components/emailstepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/digeststepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/delaystepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/delaycontroldto.ts | Renames conflicting Type to DelayControlDtoType and updates schemas. |
| libs/internal-sdk/src/models/components/customstepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/createworkflowdto.ts | Adjusts __source handling and outbound schema defaulting/optional behavior. |
| libs/internal-sdk/src/models/components/createlayoutdto.ts | Adjusts __source handling and outbound schema defaulting/optional behavior. |
| libs/internal-sdk/src/models/components/chatstepresponsedto.ts | Fixes origin description wording. |
| libs/internal-sdk/src/models/components/channeltypeenum.ts | Removes redundant comment for channel type enum. |
| libs/internal-sdk/src/models/components/buttontypeenum.ts | Improves button type docs text. |
| libs/internal-sdk/src/models/components/activitynotificationtemplateresponsedto.ts | Fixes origin wording. |
| libs/internal-sdk/src/models/components/activitynotificationresponsedto.ts | Adds docs for channels and improves severity wording. |
| libs/internal-sdk/src/models/components/activitynotificationexecutiondetailresponsedto.ts | Improves providerId wording. |
| libs/internal-sdk/src/lib/config.ts | Bumps Speakeasy generator metadata version/user-agent. |
| libs/internal-sdk/src/funcs/subscribersNotificationsUnseenCount.ts | Adds feedId to query encoding. |
| libs/internal-sdk/src/funcs/subscribersNotificationsList.ts | Adds tags to query encoding. |
| libs/internal-sdk/src/funcs/subscribersNotificationsFeed.ts | Adds feedIdentifier to query encoding. |
| libs/dal/package.json | Updates Nest peer dependency to v11. |
| libs/application-generic/tsconfig.module.json | Excludes specs from module build. |
| libs/application-generic/tsconfig.json | Excludes specs from compilation. |
| libs/application-generic/src/webhooks/dtos/webhook-payload.dto.ts | Updates Swagger typing/casts to satisfy v11 types. |
| libs/application-generic/src/dtos/workflow/generate-preview-response.dto.ts | Updates Swagger typing/casts to satisfy v11 types. |
| libs/application-generic/src/dtos/ui-schema-property.dto.ts | Adjusts Swagger enum declaration for UI components. |
| libs/application-generic/src/dtos/step-filter-dto.ts | Updates Swagger typing/casts to satisfy v11 types. |
| libs/application-generic/src/dtos/layout/create-layout.dto.ts | Switches to ApiPropertyOptional for optional source field. |
| libs/application-generic/src/decorators/user-session.decorator.ts | Improves typing for ctx.getType() narrowing. |
| libs/application-generic/src/decorators/context-payload.decorator.ts | Uses public ApiPropertyOptions typing and casts options object. |
| libs/application-generic/package.json | Upgrades Nest peer deps to v11; switches typings to types; removes workspace dep on @novu/testing. |
| libs/application-generic/jest.config.js | Adds moduleNameMapper for @novu/testing to source for tests. |
| enterprise/packages/translation/package.json | Upgrades Nest peer deps to v11. |
| enterprise/packages/shared-services/package.json | Moves @novu/dal to dependencies and upgrades Nest peer deps to v11; switches typings to types. |
| enterprise/packages/billing/package.json | Upgrades Nest peer deps to v11 (and throttler version). |
| enterprise/packages/auth/package.json | Upgrades Nest peer deps to v11. |
| enterprise/packages/api/package.json | Upgrades Nest peer/dev deps to v11 and swagger version. |
| enterprise/packages/ai/package.json | Upgrades Nest testing/swagger versions. |
| apps/ws/src/bootstrap.ts | Uses NestExpressApplication type and sets Express query parser to extended. |
| apps/ws/package.json | Upgrades Nest deps/dev deps to v11 and serve-static v5. |
| apps/worker/src/bootstrap.ts | Uses NestExpressApplication type and sets Express query parser to extended. |
| apps/worker/src/app/shared/response.interceptor.ts | Improves interceptor typing and GraphQL context check typing. |
| apps/worker/package.json | Upgrades Nest deps/dev deps to v11 (axios/schedule/etc). |
| apps/webhook/src/shared/framework/user.decorator.ts | Adjusts GraphQL context type checks with explicit casting. |
| apps/api/src/error-dto.ts | Updates Swagger decorators/options to v11 conventions and object typing. |
| apps/api/src/config/load-test-env.ts | Adds shared dotenv loader for Mocha unit tests. |
| apps/api/src/config/cors.config.ts | Refines CORS delegate typing and removes incorrect callback typing/casting. |
| apps/api/src/config/cors.config.spec.ts | Updates tests to use typed Request casts instead of ts-expect-error. |
| apps/api/src/bootstrap.ts | Uses NestExpressApplication type and sets Express query parser to extended. |
| apps/api/src/app/workflows-v2/dtos/create-workflow.dto.ts | Switches to ApiPropertyOptional for optional source. |
| apps/api/src/app/widgets/pipes/limit-pipe/limit-pipe.spec.ts | Replaces enum with as const object for metadata typing. |
| apps/api/src/app/widgets/dtos/message-response.dto.ts | Adds explicit Swagger type: String for enum fields. |
| apps/api/src/app/widgets/dtos/feeds-response.dto.ts | Adds explicit Swagger type: String and updates optional object fields to type: Object. |
| apps/api/src/app/subscribers/usecases/chat-oauth-callback/is-not-empty.spec.ts | Refactors test setup to apply decorator manually and remove unused vars. |
| apps/api/src/app/subscribers/subscribersV1.controller.ts | Adds ParseEnumPipe + ApiParam enum for action type. |
| apps/api/src/app/subscribers-v2/subscribers.controller.ts | Adds ParseEnumPipe + tightens Swagger enum listing for actionType. |
| apps/api/src/app/subscribers-v2/dtos/subscriber-notification-action.dto.ts | Updates Swagger enum declaration and example typing. |
| apps/api/src/app/subscribers-v2/dtos/get-subscriber-notifications-response.dto.ts | Updates Swagger object typing/cast for filter. |
| apps/api/src/app/shared/framework/user.decorator.ts | Adjusts GraphQL context type checks with explicit casting. |
| apps/api/src/app/shared/framework/response.interceptor.ts | Adjusts GraphQL context type checks with explicit casting. |
| apps/api/src/app/shared/dtos/subscriptions/create-subscriptions.dto.ts | Switches optional fields to ApiPropertyOptional and uses type: Object. |
| apps/api/src/app/shared/dtos/subscriptions/create-subscriptions-response.dto.ts | Uses type: Object for optional JSON-logic condition. |
| apps/api/src/app/notifications/dtos/activities-response.dto.ts | Uses type: Object for optional object-like fields in Swagger. |
| apps/api/src/app/message-template/message-template.module.ts | Adds forwardRef for ChangeModule import to address DI cycle. |
| apps/api/src/app/layouts-v2/dtos/generate-layout-preview-response.dto.ts | Updates Swagger object typing/casts to satisfy v11 types. |
| apps/api/src/app/events/dtos/trigger-event-to-all-request.dto.ts | Updates Swagger payload typing to Object and cleans required flags. |
| apps/api/src/app/events/dtos/trigger-event-request.dto.ts | Updates Swagger typing to ApiPropertyOptional + type: Object for optional fields. |
| apps/api/src/app/environments-v1/dtos/create-environment-request.dto.ts | Normalizes hex color example casing. |
| apps/api/src/app/contexts/dtos/update-context-request.dto.ts | Uses type: Object for Swagger context data field. |
| apps/api/src/app/contexts/dtos/create-context-request.dto.ts | Switches optional context data to ApiPropertyOptional and type: Object. |
| apps/api/src/app/billing/e2e/verify-customer.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/get-subscription.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/get-prices.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/get-portal-link.e2e-ee.ts | Switches EE billing require pattern to direct imports/constructors. |
| apps/api/src/app/billing/e2e/get-platform-notification-usage.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/customer-subscription-deleted.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/customer-subscription-created.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/create-usage-records.e2e-ee.ts | Switches EE billing require pattern to direct imports (incl. stripe types). |
| apps/api/src/app/billing/e2e/create-subscription.e2e-ee.ts | Switches EE billing require pattern to direct imports (incl. stripe types). |
| apps/api/src/app/billing/e2e/create-checkout-session.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/billing/e2e/checkout-session-completed.e2e-ee.ts | Switches EE billing require pattern to direct imports. |
| apps/api/src/app/auth/services/passport/apikey.strategy.ts | Refactors header API key strategy to use validate() per Nest Passport conventions. |
| apps/api/src/app/auth/framework/community.user.auth.guard.ts | Updates return type to non-generic IAuthModuleOptions. |
| apps/api/scripts/run-novu-v2-e2e-shard.cjs | Adds mocha config usage and adjusts e2e runner arguments. |
| apps/api/scripts/generate-metadata.ts | Updates Nest CLI plugin import path for v11. |
| apps/api/package.json | Upgrades Nest deps/dev deps to v11; revises mocha commands and env loading for tests/e2e. |
| apps/api/.mocharc.json | Updates requires to include env loader and adjusts file globs. |
| apps/api/.mocharc.e2e.json | Adds dedicated e2e mocha config file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export type ObjectT = {}; | ||
|
|
||
| /** @internal */ | ||
| export type ObjectT$Outbound = {}; | ||
|
|
||
| /** @internal */ | ||
| export const ObjectT$outboundSchema: z.ZodType< | ||
| ObjectT$Outbound, | ||
| z.ZodTypeDef, | ||
| ObjectT | ||
| > = z.object({}); |
There was a problem hiding this comment.
ObjectT is defined as {} with a z.object({}) schema, which only accepts plain objects. In this PR it’s used for request/query params like feedId, feedIdentifier, and tags that are documented/handled server-side as string | string[] (and sometimes more complex unions). This will cause the SDK’s outbound Zod validation to reject valid inputs (strings/arrays) before sending requests. Consider changing ObjectT to model an arbitrary JSON value (e.g., unknown/any with z.unknown()/z.any()), or better, generate explicit unions for these params (e.g., string | string[] for feedId).
| '--require', | ||
| './swc-register.js', |
There was a problem hiding this comment.
run-novu-v2-e2e-shard.cjs now passes --config .mocharc.e2e.json (which already requires @swc-node/register) and also adds --require ./swc-register.js (which registers ts-node + a SWC pirates hook). Having both transpilation hooks active can lead to double-compilation, hard-to-debug loader precedence issues, and extra startup cost. Prefer using a single TS loader (either keep @swc-node/register in the config and drop ./swc-register.js, or remove the config require and keep the custom loader).
| '--require', | |
| './swc-register.js', |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
libs/internal-sdk/src/models/operations/subscribersv1controllermarkactionasseen.ts (1)
1-3:⚠️ Potential issue | 🟠 MajorGenerated SDK artifact appears directly edited.
This file is marked as generated (
DO NOT EDIT). Please apply this change in the source API/spec and regeneratelibs/internal-sdkoutputs to prevent drift/overwrite in the next codegen run.As per coding guidelines, "libs/internal-sdk/**: Never edit auto-generated files in libs/internal-sdk".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/internal-sdk/src/models/operations/subscribersv1controllermarkactionasseen.ts` around lines 1 - 3, This change was made to a generated file (subscribersv1controllermarkactionasseen.ts) which must not be edited directly; instead update the upstream API/spec (the OpenAPI/Swagger source where the operation "SubscribersV1Controller.markActionAsSeen" or the corresponding path/operationId is defined) with the desired change, then run the project's codegen/build process to regenerate the libs/internal-sdk artifacts so the updated subscribersv1controllermarkactionasseen.ts is produced automatically; do not commit manual edits to the generated file.libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.ts (1)
1-3:⚠️ Potential issue | 🟠 MajorRegenerate this file from source instead of manually editing.
This file is marked as auto-generated by Speakeasy (
DO NOT EDIT), but it contains direct modifications. Per coding guidelines,libs/internal-sdk/**files must never be manually edited—regenerate from the OpenAPI spec or source specification instead.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.ts` around lines 1 - 3, The file docs indicate it is auto-generated (libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.ts) and must not be edited manually; instead regenerate this file from the source OpenAPI/spec by running the Speakeasy code generator (or the project's generation script) that produces the libs/internal-sdk artifacts, verify the regenerated subscribersNotificationsUnseenCount.core.ts contains your intended changes, and commit the generated output; do not make direct edits to the generated file—update the source spec and re-run the generator.
🧹 Nitpick comments (2)
libs/testing/src/ee/ee.repository.factory.ts (1)
13-21: Refactor to keyed return types or overloads to strengthen type safety.The
as Tcasts allow mismatched generic/className pairs to type-check (e.g.,getEERepository<UserRepository>('OrganizationRepository')). While verification shows no current mismatches in the codebase, using keyed return types or function overloads would prevent this type of error at compile time rather than relying on runtime correctness.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/testing/src/ee/ee.repository.factory.ts` around lines 13 - 21, The current getEERepository<T> uses unchecked casts (as T) which allow mismatched generic/className pairs; change the API to a keyed return type or explicit overloads so the return type is tied to the className literal — e.g., replace getEERepository<T>(className: ...) with either (1) function overloads: getEERepository('OrganizationRepository'): OrganizationRepository; getEERepository('MemberRepository'): MemberRepository; getEERepository('UserRepository'): UserRepository; or (2) a mapped type signature like getEERepository<K extends 'OrganizationRepository'|'MemberRepository'|'UserRepository'>(className: K): K extends 'OrganizationRepository' ? OrganizationRepository : K extends 'MemberRepository' ? MemberRepository : UserRepository; then remove the as T casts and return the concrete calls to getEEOrganizationRepository(), getEEMemberRepository(), and getEEUserRepository() directly.apps/api/src/app/billing/e2e/create-checkout-session.e2e-ee.ts (1)
27-29: Remove unreachable "module exists" guard after static importLine 27 check is redundant: when using static imports like
import { CreateCheckoutSession }, module loading fails before tests run if the export doesn't exist. The guard will never evaluate to true.Suggested cleanup
- if (!CreateCheckoutSession) { - throw new Error("CreateCheckoutSession doesn't exist"); - }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/src/app/billing/e2e/create-checkout-session.e2e-ee.ts` around lines 27 - 29, The redundant runtime guard checking CreateCheckoutSession after a static import should be removed: delete the if-block that throws an error for CreateCheckoutSession since static imports guarantee the export exists at load time (the module would fail to load before tests run); locate the check referencing CreateCheckoutSession in the test file and remove that conditional and its throw to clean up unreachable code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/api/src/app/billing/e2e/create-subscription.e2e-ee.ts`:
- Line 7: The test deep-imports internal symbols StripeSubscriptionStatusEnum
and StripeUsageTypeEnum from '@novu/ee-billing/src/stripe/types' which is
fragile; instead add re-exports for those enums in the public entrypoint of the
`@novu/ee-billing` package (e.g., export { StripeSubscriptionStatusEnum,
StripeUsageTypeEnum } from './src/stripe/types' in the package's main index) and
update the test import in create-subscription.e2e-ee.ts to import them from
'@novu/ee-billing' so the test uses the package public API.
In
`@libs/internal-sdk/src/models/operations/subscriberscontrollergetsubscribernotifications.ts`:
- Around line 29-32: The generated validator for the tags field is wrong (it
currently uses an empty z.object which rejects valid input); update the
Speakeasy/OpenAPI source schema for the tags property (the one that produces
components.ObjectT / the tags field in the subscribers controller model) to be a
union that accepts either string[] (OR) or an object shaped as { and: Array<{
or: string[] }> } (AND of OR-groups); then regenerate the SDK so the generated
type and schema (the tags type and its validator used in the subscribers
controller) validate string[] and { and: [{ or: string[] }, ...] } correctly
instead of z.object({}).
In
`@libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts`:
- Line 16: The ObjectT schema is too strict (z.object({}) outbound) causing
filter objects for feedIdentifier, feedId, and tags to be stripped; update the
upstream OpenAPI components.ObjectT schema to allow passthrough properties
(e.g., add additionalProperties: true or define the expected properties) so
outboundSchema isn't an empty object, then regenerate the Speakeasy client so
SubscribersV1ControllerGetNotificationsFeedRequest.feedIdentifier,
SubscribersV1ControllerGetUnseenCountRequest.feedId, and
SubscribersControllerGetSubscriberNotificationsRequest.tags preserve their
contents.
In
`@libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts`:
- Around line 14-17: The generated model's feedId property is incorrectly typed
as components.ObjectT (empty object); update the source OpenAPI/Speakeasy
specification for the subscribersv1controllergetunseencount schema so feedId is
defined as either a single string or an array of strings (e.g., use oneOf:
[{type: "string"}, {type: "array", items: {type: "string"}}] or equivalent
Speakeasy schema), not components.ObjectT; regenerate the SDK so the generated
property feedId and its schema reflect string/array-of-strings instead of {}.
In `@libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts`:
- Line 81: This file
(libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts) is
auto-generated and must not be manually edited; revert any manual changes and
instead update the Speakeasy generator inputs/templates that produce the
"ChannelConnections" export (and any related schema/config) and then re-run the
code generation pipeline so the updated output is regenerated with the DO NOT
EDIT marker intact.
---
Outside diff comments:
In
`@libs/internal-sdk/src/models/operations/subscribersv1controllermarkactionasseen.ts`:
- Around line 1-3: This change was made to a generated file
(subscribersv1controllermarkactionasseen.ts) which must not be edited directly;
instead update the upstream API/spec (the OpenAPI/Swagger source where the
operation "SubscribersV1Controller.markActionAsSeen" or the corresponding
path/operationId is defined) with the desired change, then run the project's
codegen/build process to regenerate the libs/internal-sdk artifacts so the
updated subscribersv1controllermarkactionasseen.ts is produced automatically; do
not commit manual edits to the generated file.
In
`@libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.ts`:
- Around line 1-3: The file docs indicate it is auto-generated
(libs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.ts)
and must not be edited manually; instead regenerate this file from the source
OpenAPI/spec by running the Speakeasy code generator (or the project's
generation script) that produces the libs/internal-sdk artifacts, verify the
regenerated subscribersNotificationsUnseenCount.core.ts contains your intended
changes, and commit the generated output; do not make direct edits to the
generated file—update the source spec and re-run the generator.
---
Nitpick comments:
In `@apps/api/src/app/billing/e2e/create-checkout-session.e2e-ee.ts`:
- Around line 27-29: The redundant runtime guard checking CreateCheckoutSession
after a static import should be removed: delete the if-block that throws an
error for CreateCheckoutSession since static imports guarantee the export exists
at load time (the module would fail to load before tests run); locate the check
referencing CreateCheckoutSession in the test file and remove that conditional
and its throw to clean up unreachable code.
In `@libs/testing/src/ee/ee.repository.factory.ts`:
- Around line 13-21: The current getEERepository<T> uses unchecked casts (as T)
which allow mismatched generic/className pairs; change the API to a keyed return
type or explicit overloads so the return type is tied to the className literal —
e.g., replace getEERepository<T>(className: ...) with either (1) function
overloads: getEERepository('OrganizationRepository'): OrganizationRepository;
getEERepository('MemberRepository'): MemberRepository;
getEERepository('UserRepository'): UserRepository; or (2) a mapped type
signature like getEERepository<K extends
'OrganizationRepository'|'MemberRepository'|'UserRepository'>(className: K): K
extends 'OrganizationRepository' ? OrganizationRepository : K extends
'MemberRepository' ? MemberRepository : UserRepository; then remove the as T
casts and return the concrete calls to getEEOrganizationRepository(),
getEEMemberRepository(), and getEEUserRepository() directly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 43a5d499-699d-426b-bd71-ef8c3d675775
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (106)
.sourceapps/api/.mocharc.e2e.jsonapps/api/.mocharc.jsonapps/api/package.jsonapps/api/scripts/run-novu-v2-e2e-shard.cjsapps/api/src/app/billing/e2e/checkout-session-completed.e2e-ee.tsapps/api/src/app/billing/e2e/create-checkout-session.e2e-ee.tsapps/api/src/app/billing/e2e/create-subscription.e2e-ee.tsapps/api/src/app/billing/e2e/create-usage-records.e2e-ee.tsapps/api/src/app/billing/e2e/customer-subscription-created.e2e-ee.tsapps/api/src/app/billing/e2e/customer-subscription-deleted.e2e-ee.tsapps/api/src/app/billing/e2e/get-platform-notification-usage.e2e-ee.tsapps/api/src/app/billing/e2e/get-portal-link.e2e-ee.tsapps/api/src/app/billing/e2e/get-prices.e2e-ee.tsapps/api/src/app/billing/e2e/get-subscription.e2e-ee.tsapps/api/src/app/billing/e2e/verify-customer.e2e-ee.tsapps/api/src/app/environments-v1/dtos/create-environment-request.dto.tsapps/api/src/app/message-template/message-template.module.tsapps/api/src/app/subscribers/usecases/chat-oauth-callback/is-not-empty.spec.tsapps/api/src/app/widgets/pipes/limit-pipe/limit-pipe.spec.tsapps/api/src/app/workflows-v2/dtos/create-workflow.dto.tsapps/api/src/config/cors.config.spec.tsapps/api/src/config/cors.config.tsapps/api/src/config/load-test-env.tsapps/worker/src/app/shared/response.interceptor.tslibs/application-generic/jest.config.jslibs/application-generic/package.jsonlibs/application-generic/src/decorators/user-session.decorator.tslibs/application-generic/src/dtos/layout/create-layout.dto.tslibs/application-generic/src/dtos/ui-schema-property.dto.tslibs/internal-sdk/src/funcs/subscribersNotificationsFeed.tslibs/internal-sdk/src/funcs/subscribersNotificationsList.tslibs/internal-sdk/src/funcs/subscribersNotificationsUnseenCount.tslibs/internal-sdk/src/lib/config.tslibs/internal-sdk/src/models/components/activitynotificationexecutiondetailresponsedto.tslibs/internal-sdk/src/models/components/activitynotificationresponsedto.tslibs/internal-sdk/src/models/components/activitynotificationtemplateresponsedto.tslibs/internal-sdk/src/models/components/buttontypeenum.tslibs/internal-sdk/src/models/components/channeltypeenum.tslibs/internal-sdk/src/models/components/chatstepresponsedto.tslibs/internal-sdk/src/models/components/createlayoutdto.tslibs/internal-sdk/src/models/components/createworkflowdto.tslibs/internal-sdk/src/models/components/customstepresponsedto.tslibs/internal-sdk/src/models/components/delaycontroldto.tslibs/internal-sdk/src/models/components/delaystepresponsedto.tslibs/internal-sdk/src/models/components/digeststepresponsedto.tslibs/internal-sdk/src/models/components/emailstepresponsedto.tslibs/internal-sdk/src/models/components/failedworkflowdto.tslibs/internal-sdk/src/models/components/getpreferencesresponsedto.tslibs/internal-sdk/src/models/components/httprequeststepresponsedto.tslibs/internal-sdk/src/models/components/inappstepresponsedto.tslibs/internal-sdk/src/models/components/inboxnotificationdto.tslibs/internal-sdk/src/models/components/index.tslibs/internal-sdk/src/models/components/messagebutton.tslibs/internal-sdk/src/models/components/notificationfeeditemdto.tslibs/internal-sdk/src/models/components/notificationworkflowdto.tslibs/internal-sdk/src/models/components/object.tslibs/internal-sdk/src/models/components/providersidenum.tslibs/internal-sdk/src/models/components/pushstepresponsedto.tslibs/internal-sdk/src/models/components/resourcedependencydto.tslibs/internal-sdk/src/models/components/resourcediffdto.tslibs/internal-sdk/src/models/components/resourcediffresultdto.tslibs/internal-sdk/src/models/components/resourceoriginenum.tslibs/internal-sdk/src/models/components/resourcetopublishdto.tslibs/internal-sdk/src/models/components/severitylevelenum.tslibs/internal-sdk/src/models/components/skippedworkflowdto.tslibs/internal-sdk/src/models/components/smsstepresponsedto.tslibs/internal-sdk/src/models/components/stepresponsedto.tslibs/internal-sdk/src/models/components/subscriberpreferenceoverridedto.tslibs/internal-sdk/src/models/components/subscriptionpreferencedto.tslibs/internal-sdk/src/models/components/syncedworkflowdto.tslibs/internal-sdk/src/models/components/syncresultdto.tslibs/internal-sdk/src/models/components/throttlestepresponsedto.tslibs/internal-sdk/src/models/components/triggereventrequestdto.tslibs/internal-sdk/src/models/components/triggereventtoallrequestdto.tslibs/internal-sdk/src/models/components/uicomponentenum.tslibs/internal-sdk/src/models/components/uischemaproperty.tslibs/internal-sdk/src/models/components/updateworkflowdto.tslibs/internal-sdk/src/models/components/workflowlistresponsedto.tslibs/internal-sdk/src/models/components/workflowresponsedto.tslibs/internal-sdk/src/models/operations/messagescontrollergetmessages.tslibs/internal-sdk/src/models/operations/subscriberscontrollergetsubscribernotifications.tslibs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.tslibs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.tslibs/internal-sdk/src/models/operations/subscribersv1controllermarkactionasseen.tslibs/internal-sdk/src/react-query/channelConnectionsCreate.tslibs/internal-sdk/src/react-query/channelConnectionsDelete.tslibs/internal-sdk/src/react-query/channelConnectionsList.core.tslibs/internal-sdk/src/react-query/channelConnectionsList.tslibs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.tslibs/internal-sdk/src/react-query/channelConnectionsRetrieve.tslibs/internal-sdk/src/react-query/channelConnectionsUpdate.tslibs/internal-sdk/src/react-query/channelEndpointsCreate.tslibs/internal-sdk/src/react-query/channelEndpointsDelete.tslibs/internal-sdk/src/react-query/channelEndpointsList.core.tslibs/internal-sdk/src/react-query/channelEndpointsList.tslibs/internal-sdk/src/react-query/channelEndpointsRetrieve.core.tslibs/internal-sdk/src/react-query/channelEndpointsRetrieve.tslibs/internal-sdk/src/react-query/channelEndpointsUpdate.tslibs/internal-sdk/src/react-query/subscribersNotificationsFeed.core.tslibs/internal-sdk/src/react-query/subscribersNotificationsFeed.tslibs/internal-sdk/src/react-query/subscribersNotificationsList.core.tslibs/internal-sdk/src/react-query/subscribersNotificationsList.tslibs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.core.tslibs/internal-sdk/src/react-query/subscribersNotificationsUnseenCount.tslibs/testing/src/ee/ee.repository.factory.ts
💤 Files with no reviewable changes (3)
- libs/internal-sdk/src/models/operations/messagescontrollergetmessages.ts
- libs/internal-sdk/src/models/components/channeltypeenum.ts
- libs/internal-sdk/src/models/components/uicomponentenum.ts
✅ Files skipped from review due to trivial changes (49)
- apps/api/.mocharc.e2e.json
- libs/internal-sdk/src/models/components/httprequeststepresponsedto.ts
- apps/api/src/app/environments-v1/dtos/create-environment-request.dto.ts
- apps/api/src/app/billing/e2e/customer-subscription-created.e2e-ee.ts
- libs/internal-sdk/src/models/components/failedworkflowdto.ts
- libs/internal-sdk/src/models/components/messagebutton.ts
- libs/internal-sdk/src/models/components/chatstepresponsedto.ts
- libs/internal-sdk/src/models/components/stepresponsedto.ts
- libs/internal-sdk/src/models/components/skippedworkflowdto.ts
- apps/api/src/app/widgets/pipes/limit-pipe/limit-pipe.spec.ts
- libs/internal-sdk/src/models/components/updateworkflowdto.ts
- libs/internal-sdk/src/models/components/pushstepresponsedto.ts
- apps/api/src/app/billing/e2e/verify-customer.e2e-ee.ts
- apps/api/src/app/billing/e2e/checkout-session-completed.e2e-ee.ts
- libs/internal-sdk/src/models/components/delaystepresponsedto.ts
- libs/internal-sdk/src/models/components/resourcediffresultdto.ts
- libs/internal-sdk/src/models/components/severitylevelenum.ts
- libs/internal-sdk/src/models/components/digeststepresponsedto.ts
- libs/internal-sdk/src/models/components/syncedworkflowdto.ts
- libs/internal-sdk/src/models/components/buttontypeenum.ts
- libs/internal-sdk/src/models/components/inappstepresponsedto.ts
- libs/internal-sdk/src/models/components/providersidenum.ts
- libs/internal-sdk/src/models/components/getpreferencesresponsedto.ts
- libs/internal-sdk/src/models/components/resourcedependencydto.ts
- libs/internal-sdk/src/models/components/customstepresponsedto.ts
- libs/internal-sdk/src/models/components/notificationfeeditemdto.ts
- libs/internal-sdk/src/models/components/emailstepresponsedto.ts
- libs/internal-sdk/src/models/components/subscriberpreferenceoverridedto.ts
- libs/internal-sdk/src/models/components/triggereventrequestdto.ts
- libs/internal-sdk/src/models/components/syncresultdto.ts
- libs/internal-sdk/src/models/components/resourcediffdto.ts
- libs/internal-sdk/src/models/components/workflowresponsedto.ts
- libs/application-generic/jest.config.js
- libs/internal-sdk/src/models/components/triggereventtoallrequestdto.ts
- libs/internal-sdk/src/models/components/smsstepresponsedto.ts
- libs/internal-sdk/src/models/components/subscriptionpreferencedto.ts
- libs/internal-sdk/src/models/components/inboxnotificationdto.ts
- apps/api/src/config/load-test-env.ts
- libs/application-generic/src/decorators/user-session.decorator.ts
- libs/internal-sdk/src/models/components/object.ts
- libs/internal-sdk/src/models/components/activitynotificationexecutiondetailresponsedto.ts
- libs/internal-sdk/src/models/components/resourceoriginenum.ts
- libs/internal-sdk/src/models/components/activitynotificationtemplateresponsedto.ts
- libs/internal-sdk/src/models/components/workflowlistresponsedto.ts
- libs/internal-sdk/src/lib/config.ts
- libs/internal-sdk/src/models/components/notificationworkflowdto.ts
- libs/internal-sdk/src/models/components/activitynotificationresponsedto.ts
- libs/internal-sdk/src/models/components/resourcetopublishdto.ts
- libs/internal-sdk/src/models/components/throttlestepresponsedto.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- .source
- apps/api/scripts/run-novu-v2-e2e-shard.cjs
- apps/api/.mocharc.json
- apps/worker/src/app/shared/response.interceptor.ts
- libs/application-generic/package.json
- apps/api/package.json
- apps/api/src/config/cors.config.ts
| GetPrices, | ||
| UpdateServiceLevel, | ||
| } from '@novu/ee-billing'; | ||
| import { StripeSubscriptionStatusEnum, StripeUsageTypeEnum } from '@novu/ee-billing/src/stripe/types'; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
EE_PKG="$(fd -a package.json | rg '/ee-billing/package.json$' | head -n1)"
echo "ee-billing package file: $EE_PKG"
jq '{name, exports, main, module, types}' "$EE_PKG"
EE_DIR="$(dirname "$EE_PKG")"
echo "Checking enum declarations/exports in ee-billing..."
rg -n "enum Stripe(SubscriptionStatusEnum|UsageTypeEnum)|export .*Stripe(SubscriptionStatusEnum|UsageTypeEnum)" "$EE_DIR/src" -g '*.ts'
echo "Checking deep-import usage in billing e2e tests..."
rg -n "@novu/ee-billing/src/stripe/types" apps/api/src/app/billing/e2e -g '*.ts'Repository: novuhq/novu
Length of output: 37
🏁 Script executed:
# Step 1: Find ee-billing package location
find . -type f -name "package.json" | grep -E "ee-billing" | head -5Repository: novuhq/novu
Length of output: 37
🏁 Script executed:
# Step 2: Search more broadly for billing packages and workspace configuration
find . -type f -name "pnpm-workspace.yaml" -o -name "package.json" | head -3
ls -la | head -20Repository: novuhq/novu
Length of output: 1358
🏁 Script executed:
# Step 3: Check the test file and search for enum definitions
cat -n apps/api/src/app/billing/e2e/create-subscription.e2e-ee.ts | head -30
# Also search for StripeSubscriptionStatusEnum definition
rg "StripeSubscriptionStatusEnum|StripeUsageTypeEnum" -g '*.ts' | head -20Repository: novuhq/novu
Length of output: 2591
🏁 Script executed:
# Step 4: Find ee-billing package location and check its exports
find . -type d -name "*ee-billing*" | grep -v node_modules | grep -v ".git"
# Also check tsconfig for path mappings
cat tsconfig.base.json 2>/dev/null | jq '.compilerOptions.paths | select(. != null) | keys[] | select(contains("ee-billing"))' 2>/dev/null || echo "Checking alternate tsconfig..."Repository: novuhq/novu
Length of output: 37
🏁 Script executed:
# Step 4b: Broader search for the actual location
ls -la libs/ 2>/dev/null | head -20 || echo "No libs directory"
ls -la packages/ 2>/dev/null | head -20 || echo "No packages directory"
# Search directly for stripe/types file
find . -path "*/stripe/types.ts" -not -path "*/node_modules/*" -not -path "*/.git/*"Repository: novuhq/novu
Length of output: 1556
🏁 Script executed:
# Step 5: Check packages/novu structure for ee-billing
ls -la packages/novu/ | head -20
# Search for stripe/types.ts
find . -path "*/stripe/types.ts" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null
find . -name "types.ts" -path "*/stripe/*" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/nullRepository: novuhq/novu
Length of output: 795
🏁 Script executed:
# Step 6: Explore packages/novu/src structure
ls -la packages/novu/src/
# Find stripe/types.ts more directly
find packages/novu -name "types.ts" 2>/dev/null | head -10
# Also search for StripeSubscriptionStatusEnum definition
rg "StripeSubscriptionStatusEnum|StripeUsageTypeEnum" packages/novu/ -g '*.ts' 2>/dev/null | head -15Repository: novuhq/novu
Length of output: 809
🏁 Script executed:
# Step 7: Search for `@novu/ee-billing` references and StripeSubscriptionStatusEnum definition
rg "@novu/ee-billing" --type json | head -10
# Search for where StripeSubscriptionStatusEnum is defined
rg "enum StripeSubscriptionStatusEnum|export.*StripeSubscriptionStatusEnum" -g '*.ts' 2>/dev/null | head -10
# Check for any ee-billing directories
find . -type d -name "*ee*billing*" -not -path "*/node_modules/*" -not -path "*/.git/*"Repository: novuhq/novu
Length of output: 321
🏁 Script executed:
# Step 8: Explore enterprise/packages/billing structure
ls -la enterprise/packages/billing/
ls -la enterprise/packages/billing/src/ 2>/dev/null || echo "No src directory"
# Check for stripe/types.ts
find enterprise/packages/billing -name "types.ts" -path "*/stripe/*" 2>/dev/null
# Check package.json exports
cat enterprise/packages/billing/package.json | jq '{name, exports, main, types, files}' 2>/dev/nullRepository: novuhq/novu
Length of output: 758
🏁 Script executed:
# Step 9: Find the actual source and check index.ts
find . -type d -path "*/.source/billing/src" -not -path "*/node_modules/*"
# Also check relative path from enterprise/packages/billing
ls -la enterprise/packages/billing/../../../.source/billing/src/ 2>/dev/null || echo "Path not found"
# Try to find .source directory
find . -type d -name ".source" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -5Repository: novuhq/novu
Length of output: 79
🏁 Script executed:
# Step 10: Check .source/billing/src structure
ls -la .source/billing/src/ 2>/dev/null || echo "Directory structure not found"
# List all files in .source/billing
find .source/billing -type f -name "*.ts" | head -20
# Check if index.ts exists and what it exports
cat .source/billing/src/index.ts 2>/dev/null | head -50Repository: novuhq/novu
Length of output: 152
🏁 Script executed:
# Step 11: Check .source directory
ls -la .source/ | head -30
# Search for stripe directory anywhere
find . -type d -name "stripe" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null
# Search for any stripe/types.ts anywhere
find . -type f -path "*/stripe/types.ts" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null
# Also search for StripeSubscriptionStatusEnum definition
rg "enum StripeSubscriptionStatusEnum" -g '*.ts' 2>/dev/nullRepository: novuhq/novu
Length of output: 167
🏁 Script executed:
# Step 12: Check enterprise/packages/billing directly for any files
find enterprise/packages/billing -type f -name "*.ts" | head -20
# Search for stripe in entire repo more carefully
find . -type d -name "stripe" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null
# Search for StripeSubscriptionStatusEnum or StripeUsageTypeEnum definition more broadly
rg "StripeSubscriptionStatusEnum|StripeUsageTypeEnum" -g '*.ts' --type-list 2>/dev/null | grep -v "import\|from" | head -20
# Check actual dist output if it exists
find enterprise/packages/billing/dist -type f 2>/dev/null | head -10Repository: novuhq/novu
Length of output: 37
🏁 Script executed:
# Step 13: Check for submodules and gitignore
cat .gitmodules 2>/dev/null | grep -i billing || echo "No billing submodule"
cat .gitignore | grep -i billing || echo "No billing in gitignore"
# Check enterprise/.gitignore
cat enterprise/.gitignore 2>/dev/null | grep -i billing || echo "No billing in enterprise/.gitignore"
# Check what package.json says about main field - follow the reference
cat enterprise/packages/billing/package.json | jq '.main'
# Check the full package.json
cat enterprise/packages/billing/package.jsonRepository: novuhq/novu
Length of output: 1907
🏁 Script executed:
# Step 14: Check the build script and source structure
cat enterprise/packages/billing/check-ee.mjs
# Also check if src is actually accessible (since symlink is broken, show what's in dist)
ls -la enterprise/packages/billing/dist/ 2>/dev/null | head -20
# Try to find the real source by checking if there's a different path
find . -path "*/billing/src/stripe/types.ts" -not -path "*/node_modules/*" 2>/dev/null
# Also check tsconfig to understand source mapping
cat enterprise/packages/billing/tsconfig.jsonRepository: novuhq/novu
Length of output: 1938
🏁 Script executed:
# Step 15: Search for index files and stripe enum exports in ee-billing context
rg "export.*Stripe(Subscription|Usage)" enterprise/packages/billing/ -g '*.ts' 2>/dev/null || echo "No exports found"
# Check if there's any src directory (maybe not symlinked but actual)
find enterprise/packages/billing -type d -name src 2>/dev/null
# Search entire repo for where StripeSubscriptionStatusEnum is defined and exported
rg "export.*(enum|const) Stripe(Subscription|Usage)" -g '*.ts' | head -20Repository: novuhq/novu
Length of output: 71
Avoid deep-importing @novu/ee-billing/src/... in this test
The import on line 7 pulls enums from an internal source path (@novu/ee-billing/src/stripe/types), which bypasses the package's public API. This approach is fragile because:
- The
srcdirectory is a symlink that may not exist in all build contexts - Only the
dist/output is published;srcis not distributed to consumers - The package has no explicit export maps, making the public API unclear
Suggested fix
-import { StripeSubscriptionStatusEnum, StripeUsageTypeEnum } from '@novu/ee-billing/src/stripe/types';
+import { StripeSubscriptionStatusEnum, StripeUsageTypeEnum } from '@novu/ee-billing';If these enums are not currently exported from the public entrypoint, re-export them from @novu/ee-billing's main index file.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/api/src/app/billing/e2e/create-subscription.e2e-ee.ts` at line 7, The
test deep-imports internal symbols StripeSubscriptionStatusEnum and
StripeUsageTypeEnum from '@novu/ee-billing/src/stripe/types' which is fragile;
instead add re-exports for those enums in the public entrypoint of the
`@novu/ee-billing` package (e.g., export { StripeSubscriptionStatusEnum,
StripeUsageTypeEnum } from './src/stripe/types' in the package's main index) and
update the test import in create-subscription.e2e-ee.ts to import them from
'@novu/ee-billing' so the test uses the package public API.
| /** | ||
| * Filter by workflow tags. Plain string[] is OR. Use { and: [{ or: string[] }, ...] } for AND of OR-groups (same as inbox). | ||
| */ | ||
| tags?: components.ObjectT | undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify documented shape vs validator shape
rg -n "Filter by workflow tags|string\\[\\]|tags\\?: components\\.ObjectT|tags: components\\.ObjectT\\$outboundSchema\\.optional" \
libs/internal-sdk/src/models/operations/subscriberscontrollergetsubscribernotifications.ts
sed -n '1,30p' libs/internal-sdk/src/models/components/object.tsRepository: novuhq/novu
Length of output: 721
Fix the source schema for tags — generated validator contradicts documented API shape.
This is an auto-generated file (Speakeasy). The schema at line 114 uses z.object({}) which rejects all inputs, but the JSDoc at line 30 documents valid inputs as string[] or { and: [{ or: string[] }, ...] }. Fix the source schema definition so Speakeasy regenerates this file with the correct validator.
The generated type and schema should accept:
string[]for OR logic{ and: Array<{ or: string[] }> }for AND of OR-groups
Also applies to lines 90, 114.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@libs/internal-sdk/src/models/operations/subscriberscontrollergetsubscribernotifications.ts`
around lines 29 - 32, The generated validator for the tags field is wrong (it
currently uses an empty z.object which rejects valid input); update the
Speakeasy/OpenAPI source schema for the tags property (the one that produces
components.ObjectT / the tags field in the subscribers controller model) to be a
union that accepts either string[] (OR) or an object shaped as { and: Array<{
or: string[] }> } (AND of OR-groups); then regenerate the SDK so the generated
type and schema (the tags type and its validator used in the subscribers
controller) validate string[] and { and: [{ or: string[] }, ...] } correctly
instead of z.object({}).
| subscriberId: string; | ||
| page?: number | undefined; | ||
| limit?: number | undefined; | ||
| feedIdentifier?: components.ObjectT | undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Confirm ObjectT schema shape
rg -n --type ts 'export const ObjectT\\$outboundSchema|z\\.object\\(\\{\\}\\)' libs/internal-sdk/src/models/components/object.ts
# 2) Find operations using ObjectT$outboundSchema for outbound query fields
rg -n --type ts 'ObjectT\\$outboundSchema\\.optional\\(\\)' libs/internal-sdk/src/models/operations
# 3) Find request funcs that serialize those fields into query params
rg -n --type ts '"(tags|feedId|feedIdentifier)"\\s*:\\s*payload\\.(tags|feedId|feedIdentifier)' libs/internal-sdk/src/funcsRepository: novuhq/novu
Length of output: 251
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Confirm ObjectT schema shape - search for ObjectT definition
echo "=== Looking for ObjectT definition ==="
find libs/internal-sdk/src/models/components -name "*object.ts" -o -name "*objectT.ts" 2>/dev/null | head -10
# 2) Search for ObjectT$outboundSchema usage more carefully
echo "=== Searching for ObjectT\$outboundSchema usage ==="
rg -n 'ObjectT.*outboundSchema' libs/internal-sdk/src/models/operations --type ts | head -20
# 3) Look at the specific file mentioned in the review
echo "=== Examining subscribersv1controllergetnotificationsfeed.ts ==="
wc -l libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts
# 4) Check if the file exists and get a specific range
if [ -f "libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts" ]; then
echo "=== Lines 10-70 of the file ==="
sed -n '10,70p' libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts
fiRepository: novuhq/novu
Length of output: 2752
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find the ObjectT definition file
echo "=== Finding ObjectT model file ==="
find libs/internal-sdk/src/models/components -type f -name "*.ts" | xargs rg -l "ObjectT.*outboundSchema" | head -5
# Check what z.object({}) looks like
echo "=== Searching for empty z.object patterns ==="
rg -n 'z\.object\(\)' libs/internal-sdk/src/models/components --type ts | head -10Repository: novuhq/novu
Length of output: 185
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the ObjectT definition file
echo "=== ObjectT definition ==="
cat libs/internal-sdk/src/models/components/object.ts
echo ""
echo "=== Checking subscribersNotificationsFeed.ts funcs ==="
if [ -f "libs/internal-sdk/src/funcs/subscribersNotificationsFeed.ts" ]; then
wc -l libs/internal-sdk/src/funcs/subscribersNotificationsFeed.ts
echo "=== Lines 100-120 ==="
sed -n '100,120p' libs/internal-sdk/src/funcs/subscribersNotificationsFeed.ts
fiRepository: novuhq/novu
Length of output: 1193
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check the tags field in subscriberscontrollergetsubscribernotifications.ts
echo "=== tags field in subscriberscontrollergetsubscribernotifications.ts ==="
sed -n '100,120p' libs/internal-sdk/src/models/operations/subscriberscontrollergetsubscribernotifications.ts
echo ""
echo "=== feedId field in subscribersv1controllergetunseencount.ts ==="
sed -n '40,60p' libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts
echo ""
# Check how these are used in funcs
echo "=== searching for tags and feedId in funcs files ==="
rg -n 'tags.*payload\.|feedId.*payload\.' libs/internal-sdk/src/funcs --type ts | head -10Repository: novuhq/novu
Length of output: 2043
🏁 Script executed:
#!/bin/bash
set -euo zipfail
# Let's verify the data loss issue by examining the ObjectT definition more carefully
# and see if there are any comments about this being a placeholder
echo "=== Checking if ObjectT is auto-generated and what it should be ==="
head -2 libs/internal-sdk/src/models/components/object.ts
# Check if this is marked as auto-generated
rg -B5 -A10 'export type ObjectT' libs/internal-sdk/src/models/components/object.tsRepository: novuhq/novu
Length of output: 107
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check if these files are marked as auto-generated
echo "=== Checking auto-generated markers ==="
head -5 libs/internal-sdk/src/models/components/object.ts
head -5 libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts
echo ""
echo "=== Looking for OpenAPI definition or source config ==="
find . -maxdepth 3 -type f \( -name "*.yaml" -o -name "*.yml" -o -name "*.json" \) | grep -i 'openapi\|swagger\|api' | head -10Repository: novuhq/novu
Length of output: 642
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check if ObjectT is used elsewhere and what the pattern suggests
echo "=== How many files use ObjectT ==="
rg -l 'components\.ObjectT' libs/internal-sdk/src --type ts | wc -l
echo ""
echo "=== Sample of ObjectT usage in different contexts ==="
rg -B2 'ObjectT\$outboundSchema' libs/internal-sdk/src/models/operations --type ts | head -30Repository: novuhq/novu
Length of output: 1293
feedIdentifier, feedId, and tags are at risk of being serialized as {} (filter data loss).
Because components.ObjectT$outboundSchema is z.object({}), filter objects passed to these fields are stripped during validation, causing downstream data loss in query parameters. Affected operations:
SubscribersV1ControllerGetNotificationsFeedRequest.feedIdentifier(line 16)SubscribersV1ControllerGetUnseenCountRequest.feedId(line 40)SubscribersControllerGetSubscriberNotificationsRequest.tags(line 114)
These are auto-generated files (Speakeasy). Fix the ObjectT definition in the upstream API specification to properly define the expected object schema with passthrough properties (e.g., additionalProperties: true in OpenAPI), then regenerate.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@libs/internal-sdk/src/models/operations/subscribersv1controllergetnotificationsfeed.ts`
at line 16, The ObjectT schema is too strict (z.object({}) outbound) causing
filter objects for feedIdentifier, feedId, and tags to be stripped; update the
upstream OpenAPI components.ObjectT schema to allow passthrough properties
(e.g., add additionalProperties: true or define the expected properties) so
outboundSchema isn't an empty object, then regenerate the Speakeasy client so
SubscribersV1ControllerGetNotificationsFeedRequest.feedIdentifier,
SubscribersV1ControllerGetUnseenCountRequest.feedId, and
SubscribersControllerGetSubscriberNotificationsRequest.tags preserve their
contents.
| /** | ||
| * Identifier for the feed. Can be a single string or an array of strings. | ||
| */ | ||
| feedId?: components.ObjectT | undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify feedId docs vs validator/type in this model
rg -n "feedId|single string|array of strings|ObjectT\\$outboundSchema" \
libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts
sed -n '1,30p' libs/internal-sdk/src/models/components/object.tsRepository: novuhq/novu
Length of output: 702
🏁 Script executed:
#!/bin/bash
# View the actual file content around the flagged lines
echo "=== Lines 1-20 (header and context) ==="
sed -n '1,20p' libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts
echo ""
echo "=== Lines 14-17 (feedId definition) ==="
sed -n '14,17p' libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts
echo ""
echo "=== Lines 38-42 (around line 40) ==="
sed -n '38,42p' libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts
echo ""
echo "=== Lines 52-56 (around line 54, schema) ==="
sed -n '52,56p' libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts
echo ""
echo "=== Full line count ==="
wc -l libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.tsRepository: novuhq/novu
Length of output: 1504
This file is auto-generated by Speakeasy; the issue must be fixed in the source specification, not here.
Line 15 documents feedId as accepting "a single string or an array of strings," but the type (line 17) and schema (line 54) use components.ObjectT ({}), which only validates empty objects. This causes runtime validation failures for valid inputs.
However, libs/internal-sdk/** contains auto-generated code and must not be edited directly. The fix must be applied to the source OpenAPI/Speakeasy specification that generates this file, not to the generated output.
Also applies to: lines 40, 54
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@libs/internal-sdk/src/models/operations/subscribersv1controllergetunseencount.ts`
around lines 14 - 17, The generated model's feedId property is incorrectly typed
as components.ObjectT (empty object); update the source OpenAPI/Speakeasy
specification for the subscribersv1controllergetunseencount schema so feedId is
defined as either a single string or an array of strings (e.g., use oneOf:
[{type: "string"}, {type: "array", items: {type: "string"}}] or equivalent
Speakeasy schema), not components.ObjectT; regenerate the SDK so the generated
property feedId and its schema reflect string/array-of-strings instead of {}.
| return [ | ||
| "@novu/api", | ||
| "Channel Connections", | ||
| "ChannelConnections", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts | head -20Repository: novuhq/novu
Length of output: 912
🏁 Script executed:
sed -n '70,90p' libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts | cat -nRepository: novuhq/novu
Length of output: 450
Update the auto-generated file through code generation, not manual edits.
This file is auto-generated by Speakeasy (DO NOT EDIT marker on line 2). Any changes to this file must be made by updating the generator inputs/templates and re-running code generation, rather than editing the file directly. This applies to all files under libs/internal-sdk/.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts` at line
81, This file
(libs/internal-sdk/src/react-query/channelConnectionsRetrieve.core.ts) is
auto-generated and must not be manually edited; revert any manual changes and
instead update the Speakeasy generator inputs/templates that produce the
"ChannelConnections" export (and any related schema/config) and then re-run the
code generation pipeline so the updated output is regenerated with the DO NOT
EDIT marker intact.


What changed? Why was the change needed?
What changed
Upgraded NestJS from 10.x to 11.x across the monorepo to stay current with framework changes and remove type/compatibility friction. Changes include dependency bumps, TypeScript typing and Swagger decorator adjustments, bootstrap changes to preserve Express v4-style query parsing, and minor runtime refactors to align with NestJS v11 APIs and improve type safety.
Affected areas
Key technical decisions
Testing
No large new test suites added; test config and small spec fixes were applied (Mocha config, load-test-env, cors config tests) to address failing API unit and e2e tests after the upgrade—verification is expected via existing unit and e2e test runs.
Screenshots
Expand for optional sections
Related enterprise PR
Special notes for your reviewer