fix: all npm vulnerabilities#89
Conversation
WalkthroughMonorepo-wide updates: dependency bumps and overrides, react-router → react-router-dom import replacements to react-router, async conversion of email template rendering (and callers/types), small API fixes (JWT typing, Stripe null return, json parse cast), sync email template id added, and regenerated GraphQL types with stricter resolver signatures and expanded frontend typings. Changes
*Many individual web files updated; see diff for full list of modified app/component/provider pages. Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
2 issues found across 12 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/web/package.json">
<violation number="1" location="apps/web/package.json:45">
P0: Major version bump from `react-router-dom` v6 to v7 without corresponding code changes. React Router v7 has significant breaking changes from v6 (it merged with Remix). The codebase heavily uses v6 APIs (`createBrowserRouter`, `RouterProvider`, `redirect`, `useNavigate`, `useSearchParams`, `Link`, `Outlet`, etc.) across many files. This bump will very likely break the application at build or runtime. Consider following the [official v6→v7 migration guide](https://reactrouter.com/upgrading/v6) or pin to a safe v6 patch instead.</violation>
<violation number="2" location="apps/web/package.json:69">
P0: Major version bump to Vite 7 while `vite-plugin-eslint` (^1.8.1) remains unchanged. `vite-plugin-eslint` is unmaintained and used in `vite.config.ts`. It is very unlikely to be compatible with Vite 7. `@vitejs/plugin-react` (^4.3.4) may also need a major version update for Vite 7 compatibility. This will likely break the build. Consider removing `vite-plugin-eslint` (using ESLint separately) and verifying plugin compatibility, or pin to a safe Vite 6 patch.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
apps/api/src/app/billing/resolvers/mutations/login-to-stripe.mutation.ts (1)
18-18: Prefer??over||for explicit null coalescing.The intent — ensuring
nullis returned instead ofundefinedfor GraphQL resolver correctness — is valid. However,||falls back tonullfor any falsy value (including an empty string""), whereas??only handlesnull | undefined, which is the actual semantic here.♻️ Proposed refactor
- return session?.url || null; + return session?.url ?? null;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/src/app/billing/resolvers/mutations/login-to-stripe.mutation.ts` at line 18, The current return uses the falsy operator on session?.url (return session?.url || null) which incorrectly converts empty strings to null; change it to the nullish coalescing operator so it returns session?.url ?? null instead, preserving empty-string values while still converting undefined to null for the GraphQL resolver.apps/api/src/prisma.ts (1)
90-94: Explicitas Tcast is correct but remains unchecked at runtime.The added
as Ton theJSON.parsebranch is a pure compile-time change that makes both branches of the ternary consistently typed — no runtime impact. However,JsonValueincludesnull, booleans, numbers, and arrays; for any of those,isObjectreturnsfalseand the code falls intoJSON.parse(value as string). IfJSON.parsereturns something that is notRecord<string, any>(e.g.,null, a primitive, or an array), theas Tcast silently lies to the type system and callers get unexpected runtime values with no TypeScript error.Consider a lightweight runtime guard, even if just an assertion:
🛡️ Optional runtime guard
export const jsonObject = <T extends Record<string, any>>( value: string | object | JsonValue ): T => { - return isObject(value) ? (value as T) : (JSON.parse(value as string) as T); + if (isObject(value)) return value as T; + const parsed = JSON.parse(value as string); + if (!isObject(parsed)) throw new TypeError(`jsonObject: expected an object, got ${typeof parsed}`); + return parsed as T; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/src/prisma.ts` around lines 90 - 94, The jsonObject function currently casts JSON.parse(...) to T without verifying the runtime shape; modify jsonObject (and use the existing isObject) to perform a runtime check after parsing: parse the string, assert/throw if the result is not an object (e.g., null or Array) so you never return a non-object as T, and only return the parsed value cast to T once the shape-check passes; update the JSON.parse branch to include this lightweight guard and a clear error message referencing jsonObject/isObject/JsonValue.apps/api/src/app/auth/services/auth.service.ts (1)
64-67:as SignOptionsblanket cast may silently accept an incompatibleexpiresIntype.Casting the whole options object literal suppresses any type mismatch on
config.auth.jwt.expiresIn. If the config type is wider thanSignOptions['expiresIn'](e.g.string | undefined), the cast hides it. Prefer narrowing the cast to the value only, or constraining the config type at its definition.♻️ Tighter alternative
const accessToken = jwt.sign(payload, config.auth.jwt.secret, { - expiresIn: config.auth.jwt.expiresIn, - } as SignOptions); + expiresIn: config.auth.jwt.expiresIn as SignOptions["expiresIn"], + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/src/app/auth/services/auth.service.ts` around lines 64 - 67, The code in signJwtToken uses a blanket cast on the options object which can mask an incompatible type for config.auth.jwt.expiresIn; update signJwtToken so you do not cast the entire object to SignOptions — instead validate or coerce config.auth.jwt.expiresIn to a SignOptions['expiresIn'] (e.g. ensure it's string | number and not undefined) and only cast or pass the validated value (or provide a typed local variable like const expiresIn: SignOptions['expiresIn'] = /* validated value */) into jwt.sign; alternatively tighten the config type at its source so config.auth.jwt.expiresIn already matches SignOptions['expiresIn'].apps/web/package.json (1)
45-45:react-router-domis deprecated in v7 — consider migrating toreact-router.In v7,
react-router-domis no longer needed as the packages have been unified. React Router v7 re-exports everything fromreact-router, makingreact-router-doma compatibility shim. You can safely uninstallreact-router-domfrompackage.jsonand update all imports to usereact-routerinstead (79 imports across the codebase). Runtime behavior is identical, but the official upgrade guide recommends this migration. Individual import changes are straightforward; start by installingreact-routerand systematically updating import statements fromreact-router-domtoreact-router.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/package.json` at line 45, package.json currently lists the deprecated dependency "react-router-dom"; remove "react-router-dom" from dependencies, install "react-router" instead, and update all import sites that reference react-router-dom to import from react-router (search for "react-router-dom" and replace with "react-router"); ensure the app builds and run tests to catch any remaining compatibility shims or named-export differences and update any usage tied to BrowserRouter/HashRouter wrappers by importing the same symbols from react-router if needed.
🤖 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/web/package.json`:
- Line 69: The engines.node range is too permissive for Vite 7 (vite in
package.json) and may allow Node 20.x < 20.19 which Vite 7 doesn't support;
update the root package.json "engines.node" value to a strict minimum such as
">=20.19.0 || >=22.12.0" (or ">=20.19" if you prefer short form) so Node.js
versions below 20.19 are excluded and Vite 7 will run reliably.
---
Nitpick comments:
In `@apps/api/src/app/auth/services/auth.service.ts`:
- Around line 64-67: The code in signJwtToken uses a blanket cast on the options
object which can mask an incompatible type for config.auth.jwt.expiresIn; update
signJwtToken so you do not cast the entire object to SignOptions — instead
validate or coerce config.auth.jwt.expiresIn to a SignOptions['expiresIn'] (e.g.
ensure it's string | number and not undefined) and only cast or pass the
validated value (or provide a typed local variable like const expiresIn:
SignOptions['expiresIn'] = /* validated value */) into jwt.sign; alternatively
tighten the config type at its source so config.auth.jwt.expiresIn already
matches SignOptions['expiresIn'].
In `@apps/api/src/app/billing/resolvers/mutations/login-to-stripe.mutation.ts`:
- Line 18: The current return uses the falsy operator on session?.url (return
session?.url || null) which incorrectly converts empty strings to null; change
it to the nullish coalescing operator so it returns session?.url ?? null
instead, preserving empty-string values while still converting undefined to null
for the GraphQL resolver.
In `@apps/api/src/prisma.ts`:
- Around line 90-94: The jsonObject function currently casts JSON.parse(...) to
T without verifying the runtime shape; modify jsonObject (and use the existing
isObject) to perform a runtime check after parsing: parse the string,
assert/throw if the result is not an object (e.g., null or Array) so you never
return a non-object as T, and only return the parsed value cast to T once the
shape-check passes; update the JSON.parse branch to include this lightweight
guard and a clear error message referencing jsonObject/isObject/JsonValue.
In `@apps/web/package.json`:
- Line 45: package.json currently lists the deprecated dependency
"react-router-dom"; remove "react-router-dom" from dependencies, install
"react-router" instead, and update all import sites that reference
react-router-dom to import from react-router (search for "react-router-dom" and
replace with "react-router"); ensure the app builds and run tests to catch any
remaining compatibility shims or named-export differences and update any usage
tied to BrowserRouter/HashRouter wrappers by importing the same symbols from
react-router if needed.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/graphql-types/api.ts (1)
1445-1451:⚠️ Potential issue | 🔴 Critical
AsyncIterablecauses compilation failure — add"lib": ["ES2018"]topackages/graphql-types/tsconfig.json.Line 1450 references
AsyncIterable, which requires ES2018+ library support. Thepackages/graphql-types/tsconfig.jsonlacks both"lib"and"target"compiler options, causing TypeScript to default to ES3 and fail with:Cannot find name 'AsyncIterable'. Do you need to change your target library?Add
"lib": ["ES2018"](or higher) to thecompilerOptionsinpackages/graphql-types/tsconfig.json. The auto-generated code from GraphQL codegen requires this.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/graphql-types/api.ts` around lines 1445 - 1451, The generated type SubscriptionSubscribeFn uses AsyncIterable which requires ES2018+ lib support; update the package's tsconfig compilerOptions to include "lib": ["ES2018"] (or a higher ES version) so TypeScript recognizes AsyncIterable (alternatively set a target that provides the appropriate libs). Ensure the change is saved to the package's tsconfig.json under compilerOptions so GraphQL codegen output like SubscriptionSubscribeFn and related AsyncIterable references compile correctly.apps/web/src/api/environments.api.ts (1)
55-62:⚠️ Potential issue | 🟠 MajorChange
optionsto a required parameter to enforce TypeScript validation ofinitialPageParamandgetNextPageParam.The current signature
options?: Optional<...>allows callers to omit the entire parameter, bypassing TypeScript's type checking for the required fields withinUseInfiniteQueryOptions. In TanStack Query v5,initialPageParamis mandatory and has no implicit default; omitting it causes infinite scroll to fail silently at runtime.The
Optional<UseInfiniteQueryOptions<...>, "queryKey">type correctly removes thequeryKeyrequirement, but only if the parameter itself is passed. Making the parameter optional defeats this enforcement. Remove the?:from the parameter to require callers to provide options:🔧 Fix
export const useEnvironmentsInfiniteQuery = ( args: EnvironmentsQueryVariables, - options?: Optional< + options: Optional< UseInfiniteQueryOptions< EnvironmentsQuery, DefaultError, InfiniteData<EnvironmentsQuery> >, "queryKey" >, ) =>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/api/environments.api.ts` around lines 55 - 62, The options parameter is currently optional which allows callers to omit required fields like initialPageParam and getNextPageParam; make the parameter required by removing the optional marker so the signature uses options: Optional<UseInfiniteQueryOptions<EnvironmentsQuery, DefaultError, InfiniteData<EnvironmentsQuery>>, "queryKey"> (i.e., delete the "?:") in the function that declares options so TypeScript enforces supplying initialPageParam/getNextPageParam (update any call sites as needed to pass an options object).
🧹 Nitpick comments (2)
packages/graphql-types/frontend/gql.ts (1)
16-86: LGTM — typedDocumentsmap is a clean improvement.The
type Documentsconstraint ondocumentsgives each string-literal key the preciseTypedDocumentNode<Query, Variables>type (viatypeof types.XDocument), which propagates correctly through the(typeof documents)[source]overload return types. All 69 operation entries are consistent across the type map, the runtime map, and the overloads.One optional improvement:
type Documentsis currently module-local. Exporting it allows downstream consumers to reference the full map type without resorting totypeof documents.♻️ Optional: export the `Documents` type
-type Documents = { +export type Documents = {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/graphql-types/frontend/gql.ts` around lines 16 - 86, The Documents type is currently module-local; export it so downstream consumers can reference the full map type without using typeof documents—update the declaration of the type named Documents (in packages/graphql-types/frontend/gql.ts) to be exported (i.e., export type Documents = { ... }) and ensure any imports elsewhere that should reference this mapped type use the exported Documents symbol.apps/web/src/api/environments.api.ts (1)
24-24: Import change is valid; type design is permissive but currently used correctly.The import of
Optionalfromutility-typesinstead of@tanstack/react-queryis appropriate. TheOptional<T, K>type fromutility-types(which expands toOmit<T, K> & Partial<Pick<T, K>>) is semantically equivalent and reflects thatOptionalis no longer exported from TanStack Query v5.The optional parameter design in
useEnvironmentsInfiniteQueryis permissive—it allows callers to omitoptionsentirely, even thoughinitialPageParamandgetNextPageParamare required withinUseInfiniteQueryOptionsfor v5. However, the actual caller inapps/web/src/app/systems/environments/page.tsx(lines 39–52) explicitly provides both fields, so there is no current breakage. If other callers omit the parameter, the hook would fail at runtime. Consider tightening the type signature tooptions:(required) or usingPartial<UseInfiniteQueryOptions>(likeuseEnvironmentOptionsQuerydoes) to prevent this footgun.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/api/environments.api.ts` at line 24, The hook currently imports Optional from utility-types and declares useEnvironmentsInfiniteQuery with a permissive optional options parameter which can omit required infinite-query fields; update the hook signature to prevent runtime footguns by either making the options parameter required (i.e., require UseInfiniteQueryOptions with initialPageParam and getNextPageParam) or change its type to Partial<UseInfiniteQueryOptions> (matching the pattern used in useEnvironmentOptionsQuery) so callers must explicitly provide or intentionally omit those required fields; modify the function declaration for useEnvironmentsInfiniteQuery and its type import usage accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@apps/web/src/api/environments.api.ts`:
- Around line 55-62: The options parameter is currently optional which allows
callers to omit required fields like initialPageParam and getNextPageParam; make
the parameter required by removing the optional marker so the signature uses
options: Optional<UseInfiniteQueryOptions<EnvironmentsQuery, DefaultError,
InfiniteData<EnvironmentsQuery>>, "queryKey"> (i.e., delete the "?:") in the
function that declares options so TypeScript enforces supplying
initialPageParam/getNextPageParam (update any call sites as needed to pass an
options object).
In `@packages/graphql-types/api.ts`:
- Around line 1445-1451: The generated type SubscriptionSubscribeFn uses
AsyncIterable which requires ES2018+ lib support; update the package's tsconfig
compilerOptions to include "lib": ["ES2018"] (or a higher ES version) so
TypeScript recognizes AsyncIterable (alternatively set a target that provides
the appropriate libs). Ensure the change is saved to the package's tsconfig.json
under compilerOptions so GraphQL codegen output like SubscriptionSubscribeFn and
related AsyncIterable references compile correctly.
---
Nitpick comments:
In `@apps/web/src/api/environments.api.ts`:
- Line 24: The hook currently imports Optional from utility-types and declares
useEnvironmentsInfiniteQuery with a permissive optional options parameter which
can omit required infinite-query fields; update the hook signature to prevent
runtime footguns by either making the options parameter required (i.e., require
UseInfiniteQueryOptions with initialPageParam and getNextPageParam) or change
its type to Partial<UseInfiniteQueryOptions> (matching the pattern used in
useEnvironmentOptionsQuery) so callers must explicitly provide or intentionally
omit those required fields; modify the function declaration for
useEnvironmentsInfiniteQuery and its type import usage accordingly.
In `@packages/graphql-types/frontend/gql.ts`:
- Around line 16-86: The Documents type is currently module-local; export it so
downstream consumers can reference the full map type without using typeof
documents—update the declaration of the type named Documents (in
packages/graphql-types/frontend/gql.ts) to be exported (i.e., export type
Documents = { ... }) and ensure any imports elsewhere that should reference this
mapped type use the exported Documents symbol.
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 (1)
apps/api/package.json (1)
32-32:⚠️ Potential issue | 🟡 MinorUpgrade
@bull-board/expressto a version with explicit Express 5 support.
@bull-board/express@^6.7.10does not explicitly declare Express 5 support. The bull-board project added Express 5 as optional support around v6.5.4, but v6.7.10 (released Feb 27, 2025) makes no mention of Express 5 in its release notes. Versions v6.12.7+ declare dual support (express: ^4.21.1 || ^5.0.0), and v6.19.0+ targets Express 5 directly. Either upgrade to v6.19.0+ or v6.12.7+ to ensure explicit Express 5 compatibility, or verify the v6.7.10 peer dependencies support Express 5 before shipping.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/package.json` at line 32, The package.json currently pins "@bull-board/express": "^6.7.10" which does not explicitly declare Express 5 support; update the dependency entry for "@bull-board/express" to a version that declares Express 5 compatibility (for example set the version to "6.19.0" or "6.12.7" or higher), then reinstall dependencies and regenerate the lockfile (npm/yarn/pnpm install) and run tests; ensure references to "@bull-board/express" in package.json and any CI install steps are updated so the new version is used.
🧹 Nitpick comments (2)
apps/api/src/app/email/services/email-template.service.ts (1)
13-17:idis a queue/job concern — consider separating it from the email template interface.The
idfield (used as a bullmq job deduplication key, e.g.,"initial-sync-complete") is orthogonal to whatBuildEmailTemplatedescribes — an email's type and rendering props. Coupling a queue-level concept here reduces interface cohesion and forces all template callers to be aware of job IDs.A cleaner design would carry
idat the job/envelope level only:// Queue job payload — keeps queue concerns separate interface SendEmailJob { id?: string; // bullmq deduplication key template: BuildEmailTemplate; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/src/app/email/services/email-template.service.ts` around lines 13 - 17, BuildEmailTemplate currently includes a queue-specific id which breaks cohesion; remove the id property from the BuildEmailTemplate interface (leaving EmailTemplate and EmailTemplateProps[EmailTemplate] intact) and introduce a separate SendEmailJob envelope that has an optional id?: string for bullmq deduplication and a template: BuildEmailTemplate field; then update any enqueueing or job-creation sites that currently pass an object shaped like BuildEmailTemplate to instead wrap it in SendEmailJob so queue concerns live only at the job/envelope level.apps/web/package.json (1)
70-70:vite-plugin-eslintremoval degrades real-time lint feedback during development.Removing the plugin means ESLint violations are no longer surfaced inline during
vite dev— only the standalonelintscript catches them. Consider a TypeScript-aware alternative such asvite-plugin-checker(which supports ESLint and TS diagnostics) to restore in-editor/dev-server lint feedback.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/package.json` at line 70, The removal of vite-plugin-eslint eliminated inline ESLint feedback during `vite dev`; restore dev-time linting by adding a TypeScript-aware dev plugin such as `vite-plugin-checker` as a devDependency in package.json (alongside keeping the existing `lint` script), then configure it in your Vite config file (vite.config.ts or vite.config.js) to enable ESLint and TypeScript diagnostics (reference the plugin name `vite-plugin-checker` and ensure you call its setup in the Vite plugins array), so the dev server surfaces ESLint/TS errors in real time.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@certs/devcert.js`:
- Around line 6-12: The catch block around require("devcert") should
discriminate MODULE_NOT_FOUND from other errors: when require("devcert") throws,
check err.code === 'MODULE_NOT_FOUND' (or that the error message indicates
missing module) and only then print the "devcert is not installed" message and
exit; for any other error from the module (syntax/runtime), rethrow or log the
actual error so the real failure is visible. Update the try/catch around the
require in devcert.js to inspect the thrown error (e.g., err) and handle the two
cases accordingly.
In `@package.json`:
- Line 37: The current override entry "ajv": ">=6.14.0" allows ajv v8 which
breaks packages expecting the v6 API; change the override value for the ajv
entry to constrain it to semver v6 (for example ">=6.14.0 <7.0.0" or "^6.14.0")
so transitive deps like eslint and `@eslint/eslintrc` continue to resolve ajv v6;
update the package.json override key "ajv" accordingly and run install to verify
no v7/v8 is pulled in.
- Line 36: The minimatch dependency is pinned with an open-ended range
("minimatch": ">=10.2.1") which can pull future major versions and break
transitive consumers; change that entry to the exact safe patch "10.2.2" and
then regenerate the lockfile (npm/yarn/pnpm install) so the lockfile and
node_modules reflect the pinned version; update whichever file contains the
dependency entry ("minimatch" in package.json) and commit the updated lockfile.
---
Outside diff comments:
In `@apps/api/package.json`:
- Line 32: The package.json currently pins "@bull-board/express": "^6.7.10"
which does not explicitly declare Express 5 support; update the dependency entry
for "@bull-board/express" to a version that declares Express 5 compatibility
(for example set the version to "6.19.0" or "6.12.7" or higher), then reinstall
dependencies and regenerate the lockfile (npm/yarn/pnpm install) and run tests;
ensure references to "@bull-board/express" in package.json and any CI install
steps are updated so the new version is used.
---
Nitpick comments:
In `@apps/api/src/app/email/services/email-template.service.ts`:
- Around line 13-17: BuildEmailTemplate currently includes a queue-specific id
which breaks cohesion; remove the id property from the BuildEmailTemplate
interface (leaving EmailTemplate and EmailTemplateProps[EmailTemplate] intact)
and introduce a separate SendEmailJob envelope that has an optional id?: string
for bullmq deduplication and a template: BuildEmailTemplate field; then update
any enqueueing or job-creation sites that currently pass an object shaped like
BuildEmailTemplate to instead wrap it in SendEmailJob so queue concerns live
only at the job/envelope level.
In `@apps/web/package.json`:
- Line 70: The removal of vite-plugin-eslint eliminated inline ESLint feedback
during `vite dev`; restore dev-time linting by adding a TypeScript-aware dev
plugin such as `vite-plugin-checker` as a devDependency in package.json
(alongside keeping the existing `lint` script), then configure it in your Vite
config file (vite.config.ts or vite.config.js) to enable ESLint and TypeScript
diagnostics (reference the plugin name `vite-plugin-checker` and ensure you call
its setup in the Vite plugins array), so the dev server surfaces ESLint/TS
errors in real time.
Greptile Summary
This PR addresses npm security vulnerabilities by upgrading multiple dependencies to their latest versions, including major version updates for Express (v4→v5), React Router (v6→v7), Vite (v6→v7), and numerous other packages.
Key Changes:
react-router-domv6 toreact-routerv7 across all web app componentsioredis,minimatch, andajvto resolve transitive vulnerabilitiesvite-plugin-eslintand madedevcertan optional global dependencyIssues Found:
idfield added to email template object but not defined inBuildEmailTemplateinterface and not used by workerConfidence Score: 4/5
idfield is added to an email template object but isn't defined in the interface or used by the worker.apps/api/src/app/sync-batch/services/sync-batch.service.ts- contains TypeScript error that will cause compilation failureImportant Files Changed
react-router-domtoreact-router/domfor v7 compatibilityidfield to email template object, but field not defined in BuildEmailTemplate interfaceFlowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Dependency Updates] --> B[Frontend: React Router v6→v7] A --> C[Backend: Express v4→v5] A --> D[Build Tools: Vite v6→v7] A --> E[Email: Resend v3→v6] B --> B1[Change imports from<br/>react-router-dom to react-router] B --> B2[Update RouterProvider import<br/>from react-router/dom] B --> B3[Update all hooks & components<br/>useNavigate, useLocation, Link, etc.] C --> C1[Update jsonwebtoken types<br/>with SignOptions] C --> C2[Add explicit null return<br/>for Stripe mutation] D --> D1[Remove vite-plugin-eslint] D --> D2[Update Sentry plugin to v4] E --> E1[Update type aliases to<br/>CreateEmailOptions] E --> E2[Make renderEmailTemplate async] E --> E3[Add await in email worker] style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#ffe1e1 style D fill:#e1ffe1 style E fill:#f4e1ffLast reviewed commit: ca9d0e9