Skip to content

fix(core): Optimize collection variants N+1 and persist catalog filters#4636

Open
RubenDarioGuerreroNeira wants to merge 1 commit into
vendurehq:masterfrom
RubenDarioGuerreroNeira:fix/collection-variants-n-plus-1-v3
Open

fix(core): Optimize collection variants N+1 and persist catalog filters#4636
RubenDarioGuerreroNeira wants to merge 1 commit into
vendurehq:masterfrom
RubenDarioGuerreroNeira:fix/collection-variants-n-plus-1-v3

Conversation

@RubenDarioGuerreroNeira
Copy link
Copy Markdown

This Pull Request introduces significant performance optimizations and stability improvements to the core Vendure
engine, specifically addressing the Collection variants N+1 problem and catalog filtering logic. This version (v3) has
been rewritten to resolve previous technical debt, ensuring O(n) complexity and better type safety.

Key Changes

  1. N+1 Optimization in CollectionService & Resolvers
  • New Method: Added getProductVariantsForCollections to CollectionService using getRawAndEntities(). This allows
    fetching all variants for multiple collections in a single database query.
  • High-Performance Mapping: Replaced O(n²) nested loops with Map and Set lookups, ensuring the mapping logic scales
    linearly with the number of variants.
  • Batching Support: Updated CollectionResolver (Admin) and CollectionEntityResolver to use RequestContextCache for
    preloading variants, significantly speeding up the Collection List view in the Admin UI.
  • Consistency: The new query explicitly filters out soft-deleted products and variants, maintaining system-wide data
    integrity.
  1. Catalog Filtering Enhancements in ListQueryBuilder
  • ManyToOne Support: Extended EXISTS subquery support to ManyToOne custom field relations.
  • JOIN Optimization: The ListQueryBuilder now intelligently skips unnecessary LEFT JOINs for ManyToOne relations if
    they are only used for filtering (and not sorting), drastically reducing SQL complexity for stores with many custom
    fields.
  • Robustness: Added better error logging and fallback mechanisms when an EXISTS subquery cannot be constructed.
  1. Core Stability & Type Safety
  • Startup Protection: Added @optional() to ModuleRef in ConfigModule with explicit null guards. This prevents
    potential "catastrophic" startup crashes in environments where the NestJS container might not be fully available
    (e.g., certain CLI tools or migrations).
  • Service Exposure: Made applyPricesAndTranslateVariants in ProductVariantService public to allow its use in custom
    batching optimizations within resolvers.
  1. Verification & Benchmarking
  • New Benchmark Spec: Created e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts.
  • Real Assertions: Unlike previous versions, this benchmark includes expect assertions to verify:
    • The correct number of EXISTS clauses are generated.
    • Redundant JOINs are indeed omitted for optimized filters.
    • The system falls back to JOINs correctly when sorting is required.

Why these changes?
Previous attempts at these optimizations lacked rigorous validation and had performance bottlenecks in the mapping logic. This PR provides a "production-ready" implementation that follows Vendure's architectural standards while providing a massive performance boost for catalog-heavy installations.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vendure-storybook Error Error May 4, 2026 3:33pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 9, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds request-scoped caching and prefetching for collection product variants: the admin CollectionResolver precomputes collection IDs and, when productVariants is selected, starts a cached query (CacheKey.CollectionVariants) via getProductVariantsForCollections. CollectionEntityResolver.productVariants uses that cached Map when compatible with requested relations and when no custom pagination options are provided, slicing results and applying pricing/translation. Also: new CacheKey and COLLECTION_VARIANTS_CACHE_RELATIONS constants; CollectionService.getProductVariantsForCollections implementation; ProductVariantService.applyPricesAndTranslateVariants made public; ListQueryBuilder and filter parsing enhanced to treat ManyToOne as to-many for EXISTS subqueries and to skip unnecessary JOINs; several files updated to remove StringValue type usage from ms() calls; ConfigModule accepts an optional ModuleRef and guards initialization.

Possibly related PRs

Suggested reviewers

  • michaelbromley
  • biggamesmallworld
  • oliverstreissi
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: optimizing collection variants N+1 query problem and catalog filtering logic, accurately reflecting the PR's primary objectives.
Description check ✅ Passed The description comprehensively covers all required template sections with detailed explanations of changes, including rationale and implementation details, though the breaking changes section is implicit (none identified).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (1)
packages/core/src/config/config.module.ts (1)

18-18: Type the optional dependency to match runtime behavior.

At line 18, @Optional() allows ModuleRef to be undefined at runtime, but the type annotation is non-nullable. Change to private moduleRef?: ModuleRef (or ModuleRef | undefined) to keep type-safety aligned with actual injection behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/config/config.module.ts` at line 18, The parameter
decorated with `@Optional`() (private moduleRef: ModuleRef) is typed as
non-nullable but can be undefined at runtime; update the constructor/property
declaration for moduleRef to be optional (e.g., private moduleRef?: ModuleRef or
private moduleRef: ModuleRef | undefined) so the type matches runtime injection
behavior and adjust any usages of moduleRef in ConfigModule to handle possible
undefined values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/api/resolvers/admin/collection.resolver.ts`:
- Around line 74-80: The preload branch is checking the wrong field name: change
the isFieldInSelection call from isFieldInSelection(info, 'variants') to
isFieldInSelection(info, 'productVariants') so the cache gets primed when the
GraphQL selection requests productVariants; update the branch that creates
variantsPromise via this.collectionService.getProductVariantsForCollections and
the subsequent this.requestContextCache.set(ctx, CacheKey.CollectionVariants) to
run under the corrected field check so the new preload path is exercised.

In `@packages/core/src/api/resolvers/entity/collection-entity.resolver.ts`:
- Around line 68-78: The fast-path uses
requestContextCache.get(CacheKey.CollectionVariants) and reuses a cached
Promise<Map<string, ProductVariant[]>> regardless of the requested relations,
causing incorrect/partially-hydrated variants; modify the logic so the cached
shortcut only applies when the requested relation set is the minimal/default set
(e.g., no extra variant relations) or change the cache key to include a stable
representation of the requested relations (e.g., serialize relations into the
key), and ensure productVariantService.getVariantsByCollectionId(...) is called
with the same relations when populating the cache so that
productVariantService.applyPricesAndTranslateVariants(...) always receives
fully-hydrated variants consistent with the query.
- Around line 66-82: The shortcut branch for cached collection variants bypasses
the normal pagination: it returns the full cached array and sets totalItems =
items.length, breaking the pagination contract. Change the branch (the
isDefaultOptions && apiType === 'admin' block that uses requestContextCache.get
and productVariantService.applyPricesAndTranslateVariants) to mirror the normal
getVariantsByCollectionId behaviour: compute the configured default list options
(the same defaults used elsewhere), determine the totalItems as the full cached
variants.length, slice the cached variants to the default limit before calling
applyPricesAndTranslateVariants, and return items (the sliced/transformed
variants) and totalItems equal to the full cached array length rather than
items.length. Ensure you use the same default options logic as
getVariantsByCollectionId to keep behaviour consistent.

In `@packages/core/src/config/config.module.ts`:
- Around line 40-42: The two early-return checks that currently use "if
(!this.moduleRef) { return; }" should emit a warning before returning so
operators know initialization was skipped; update both occurrences in
config.module.ts to log a clear message (e.g., "ConfigModule: moduleRef missing
— skipping initialization of strategies/operations") using the module's existing
logger (this.logger / this.log / similar) or console.warn if no logger is
available, and include which init branch was skipped to aid debugging.

In `@packages/core/src/service/helpers/list-query-builder/list-query-builder.ts`:
- Around line 404-409: The current branch logs a warning and returns when
building the EXISTS subquery for condition.isExistsCondition.customPropertyKey,
which silently drops the filter; change this to fail explicitly instead of
returning silently: replace the Logger.warn(...) + return with throwing a
descriptive Error (including condition.isExistsCondition.customPropertyKey and
any error details) so the caller knows the filter couldn't be applied, or
alternatively preserve the original predicate/JOIN path by invoking the existing
code path that applies the original predicate/JOIN (rather than skipping) —
adjust the code around the EXISTS handling (the block referencing
condition.isExistsCondition.customPropertyKey and Logger.warn) to either
re-apply the original condition/JOIN or throw a clear exception.

In `@packages/core/src/service/services/collection.service.ts`:
- Around line 1061-1079: The listQueryBuilder.build call in this method is
unintentionally limited by the global default pagination, causing the
multi-collection variant fetch to only include the first page; fix it by calling
listQueryBuilder.build with a copy of the incoming options that explicitly
disables pagination (e.g., set take and skip to undefined/null) before building
the ProductVariant query used by qb/getRawAndEntities so the subsequent grouping
into variantsByCollectionId sees the full result set; update the call site where
options is passed into listQueryBuilder.build (referencing
listQueryBuilder.build, ProductVariant, qb, and getRawAndEntities) to use the
adjusted options.

---

Nitpick comments:
In `@packages/core/src/config/config.module.ts`:
- Line 18: The parameter decorated with `@Optional`() (private moduleRef:
ModuleRef) is typed as non-nullable but can be undefined at runtime; update the
constructor/property declaration for moduleRef to be optional (e.g., private
moduleRef?: ModuleRef or private moduleRef: ModuleRef | undefined) so the type
matches runtime injection behavior and adjust any usages of moduleRef in
ConfigModule to handle possible undefined values.
🪄 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: 67391ccc-026c-4cbc-a549-5408129b43ea

📥 Commits

Reviewing files that changed from the base of the PR and between 4e50814 and 0396c48.

📒 Files selected for processing (9)
  • e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
  • packages/core/src/api/resolvers/entity/collection-entity.resolver.ts
  • packages/core/src/common/constants.ts
  • packages/core/src/config/config.module.ts
  • packages/core/src/service/helpers/list-query-builder/list-query-builder.ts
  • packages/core/src/service/helpers/list-query-builder/parse-filter-params.ts
  • packages/core/src/service/services/collection.service.ts
  • packages/core/src/service/services/product-variant.service.ts

Comment thread packages/core/src/api/resolvers/admin/collection.resolver.ts Outdated
Comment thread packages/core/src/api/resolvers/entity/collection-entity.resolver.ts Outdated
Comment thread packages/core/src/config/config.module.ts Outdated
Comment thread packages/core/src/service/services/collection.service.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/core/src/api/resolvers/entity/collection-entity.resolver.ts (1)

80-81: Consider extracting defaultRelationsForCache as a shared constant.

The cache is populated in collection.resolver.ts with ['taxCategory'] relations, and this resolver has a separate hardcoded copy. If either side changes independently, the compatibility check may incorrectly use stale cache data or unnecessarily bypass a valid cache.

🔧 Example: Define a shared constant

In a shared constants file (e.g., common/constants.ts):

export const COLLECTION_VARIANTS_CACHE_RELATIONS = ['taxCategory'] as const;

Then import and use in both:

  • collection.resolver.ts when populating the cache
  • collection-entity.resolver.ts for the compatibility check
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/api/resolvers/entity/collection-entity.resolver.ts` around
lines 80 - 81, Extract the hardcoded defaultRelationsForCache used in the
isCacheCompatible check into a shared exported constant (e.g.,
COLLECTION_VARIANTS_CACHE_RELATIONS) and import that constant here and in the
place that populates the collection cache; replace the inline array in
collection-entity.resolver.ts with the imported constant and update
isCacheCompatible to use it so both cache population and compatibility checks
reference the same source of truth (ensure the constant is typed as
readonly/const tuple if desired).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/core/src/api/resolvers/entity/collection-entity.resolver.ts`:
- Around line 80-81: Extract the hardcoded defaultRelationsForCache used in the
isCacheCompatible check into a shared exported constant (e.g.,
COLLECTION_VARIANTS_CACHE_RELATIONS) and import that constant here and in the
place that populates the collection cache; replace the inline array in
collection-entity.resolver.ts with the imported constant and update
isCacheCompatible to use it so both cache population and compatibility checks
reference the same source of truth (ensure the constant is typed as
readonly/const tuple if desired).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bd49a918-f7ec-4247-887a-8f9fe51df216

📥 Commits

Reviewing files that changed from the base of the PR and between 0396c48 and fac3fb7.

📒 Files selected for processing (11)
  • packages/core/src/api/middleware/auth-guard.ts
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
  • packages/core/src/api/resolvers/entity/collection-entity.resolver.ts
  • packages/core/src/config/auth/default-verification-token-strategy.ts
  • packages/core/src/config/config.module.ts
  • packages/core/src/config/order/order-by-code-access-strategy.ts
  • packages/core/src/plugin/default-scheduler-plugin/default-scheduler-strategy.ts
  • packages/core/src/service/helpers/list-query-builder/list-query-builder.ts
  • packages/core/src/service/helpers/settings-store/settings-store.service.ts
  • packages/core/src/service/services/collection.service.ts
  • packages/core/src/service/services/session.service.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/core/src/config/auth/default-verification-token-strategy.ts
  • packages/core/src/api/middleware/auth-guard.ts
  • packages/core/src/service/helpers/settings-store/settings-store.service.ts
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/core/src/service/helpers/list-query-builder/list-query-builder.ts
  • packages/core/src/config/config.module.ts
  • packages/core/src/service/services/collection.service.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (5)
packages/stellate-plugin/lib/src/service/stellate.service.d.ts (2)

55-55: Keep purge() consistently async.
Line 55 returning Promise<void> | undefined forces unnecessary branching in consumers; prefer always returning Promise<void> (use Promise.resolve() for no-op paths).

Proposed declaration update
-    purge(type: CachedType, keys?: ID[], keyName?: string): Promise<void> | undefined;
+    purge(type: CachedType, keys?: ID[], keyName?: string): Promise<void>;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stellate-plugin/lib/src/service/stellate.service.d.ts` at line 55,
The purge declaration currently returns Promise<void> | undefined which forces
callers to handle a non-async branch; change the signature of purge(type:
CachedType, keys?: ID[], keyName?: string) to always return Promise<void>, and
update the implementation of StellateService.purge (and any overrides) to return
Promise.resolve() for no-op branches or otherwise return a Promise so callers
can uniformly await it; reference the purge method and the CachedType/ID/keyName
parameters when making the change.

3-10: CachedType is over-widened by | string.
On Lines 3-10, the trailing | string effectively collapses literal-type safety.

Proposed type-shape refinement
+type KnownCachedType =
+    | 'Product'
+    | 'ProductVariant'
+    | 'Collection'
+    | 'SearchResponse'
+    | 'SearchResult'
+    | 'SearchResponseCacheIdentifier';
-type CachedType =
-    | 'Product'
-    | 'ProductVariant'
-    | 'Collection'
-    | 'SearchResponse'
-    | 'SearchResult'
-    | 'SearchResponseCacheIdentifier'
-    | string;
+type CachedType = KnownCachedType | (string & {});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stellate-plugin/lib/src/service/stellate.service.d.ts` around lines
3 - 10, The union type CachedType is over-widened by the trailing "| string",
which defeats literal-type safety; remove the "| string" from the CachedType
definition (or alternatively split into two distinct types such as a strict
literal union named CachedType and a separate alias for arbitrary strings) so
callers get the intended literal types ('Product', 'ProductVariant',
'Collection', 'SearchResponse', 'SearchResult', 'SearchResponseCacheIdentifier')
and maintain type-safety in the code paths that depend on CachedType.
packages/stellate-plugin/lib/src/api/search-response.resolver.d.ts (1)

3-5: Tighten cacheIdentifier return typing (avoid any).
Line 4 exposes collectionSlug: any, which removes type-safety from this public API.

Proposed declaration update
 export declare class SearchResponseFieldResolver {
     cacheIdentifier(info: GraphQLResolveInfo): {
-        collectionSlug: any;
+        collectionSlug: string | null;
     };
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stellate-plugin/lib/src/api/search-response.resolver.d.ts` around
lines 3 - 5, The public method cacheIdentifier currently returns {
collectionSlug: any } which removes type-safety; update its return type to a
concrete string-based type (e.g. { collectionSlug: string } or {
collectionSlug?: string | null } depending on whether collectionSlug can be
absent) in the cacheIdentifier declaration so callers get proper typings; adjust
any internal code in the cacheIdentifier implementation to guarantee/convert to
that string type rather than returning any.
packages/payments-plugin/package/mollie/mollie.plugin.d.ts (1)

1-3: Remove deep dependency import; ListParameters is not publicly exported by Mollie.

Line 1 imports from @mollie/api-client/dist/types/binders/methods/parameters, which is a non-public implementation path not exposed in Mollie's official public API. The type does not exist in any stable public entrypoint (e.g., package root), so importing from the root won't work as an alternative.

Consider defining ListParameters locally within this module to avoid relying on Mollie's internal implementation details, which may change across versions. Alternatively, document the risk explicitly if the deep import must be retained.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/payments-plugin/package/mollie/mollie.plugin.d.ts` around lines 1 -
3, Remove the deep import of ListParameters from `@mollie/api-client` and replace
it by defining a local type that captures only the fields you actually need;
specifically delete the import of ListParameters and update the
AdditionalEnabledPaymentMethodsParams alias to use a locally declared interface
(e.g., declare interface MollieListParameters { /* include resource?: string and
other needed props */ }) or a minimal Partial/Omit-based local type, then use
Partial<Omit<MollieListParameters, 'resource'>> for
AdditionalEnabledPaymentMethodsParams so the module no longer depends on
Mollie’s internal path.
packages/elasticsearch-plugin/lib/src/indexing/indexer.controller.d.ts (1)

16-27: Reuse the shared ReindexMessageResponse type.

The same public shape is already exported from packages/elasticsearch-plugin/lib/src/types.d.ts (Lines 200-204). Keeping a second copy here makes the declaration surface drift-prone for no real benefit.

♻️ Proposed cleanup
 import {
     BulkOperation,
     BulkOperationDoc,
     ProductChannelMessageData,
+    ReindexMessageResponse,
     ReindexMessageData,
     UpdateAssetMessageData,
     UpdateProductMessageData,
     UpdateVariantMessageData,
     UpdateVariantsByIdMessageData,
     VariantChannelMessageData,
     VariantIndexItem,
 } from '../types';
 export declare const defaultProductRelations: Array<EntityRelationPaths<Product>>;
 export declare const defaultVariantRelations: Array<EntityRelationPaths<ProductVariant>>;
-export interface ReindexMessageResponse {
-    total: number;
-    completed: number;
-    duration: number;
-}
 type BulkVariantOperation = {

Also applies to: 30-34

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/elasticsearch-plugin/lib/src/indexing/indexer.controller.d.ts`
around lines 16 - 27, Replace the duplicated local ReindexMessageResponse shape
with the shared exported type from the package types module: import and use
ReindexMessageResponse from '../types' instead of redefining it in
indexer.controller.d.ts (apply the same replacement for the other duplicated
declarations referenced around the file, e.g., the block at the second
occurrence). Update any references in this file to point to the imported
ReindexMessageResponse symbol so the file reuses the single canonical type.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/elasticsearch-plugin/lib/src/options.d.ts`:
- Around line 484-485: Fix the typo in the JSDoc for the mapQuery option: update
the comment describing mapQuery (the doc above the mapQuery symbol) to remove
the duplicated word "the" so the sentence reads "This config option allows the
modification of the whole (already built) search query..." and keep the rest of
the description unchanged.

In `@packages/payments-plugin/package/mollie/mollie.plugin.d.ts`:
- Around line 104-105: Fix the documentation typos: correct the malformed inline
code punctuation around redirectUrl in the PaymentMethod description (replace
the stray double backticks so it reads `redirectUrl`) and fix the misspelling
`automaticallreleased` to `automatically released` (search for the same phrase
in the mollie plugin docs where that typo appears, e.g., near the
PaymentMethod/redirectUrl text). Ensure the inline code formatting uses single
backticks and the spelling reads "automatically released".

In `@packages/payments-plugin/package/stripe/metadata-sanitize.d.ts`:
- Around line 4-5: Fix the JSDoc typo in metadata-sanitize.d.ts: change
"Santitize metadata to ensure it follow Stripe's instructions" to a
grammatically correct sentence (e.g., "Sanitize metadata to ensure it follows
Stripe's instructions") in the JSDoc comment above the exported function
(sanitizeMetadata) so public API docs read correctly; also scan the file for the
same typo and update any other occurrences in the JSDoc.

In `@packages/payments-plugin/package/stripe/stripe-client.d.ts`:
- Around line 3-7: The class docstring is misleading about secret exposure:
update the comment for VendureStripeClient to state that the API key is stored
privately (apiKey is a private field) and only the webhook secret
(webhookSecret) is exposed/accessible, so it doesn't imply the API key is
exposed; reference VendureStripeClient, apiKey, and webhookSecret when making
this wording change.

---

Nitpick comments:
In `@packages/elasticsearch-plugin/lib/src/indexing/indexer.controller.d.ts`:
- Around line 16-27: Replace the duplicated local ReindexMessageResponse shape
with the shared exported type from the package types module: import and use
ReindexMessageResponse from '../types' instead of redefining it in
indexer.controller.d.ts (apply the same replacement for the other duplicated
declarations referenced around the file, e.g., the block at the second
occurrence). Update any references in this file to point to the imported
ReindexMessageResponse symbol so the file reuses the single canonical type.

In `@packages/payments-plugin/package/mollie/mollie.plugin.d.ts`:
- Around line 1-3: Remove the deep import of ListParameters from
`@mollie/api-client` and replace it by defining a local type that captures only
the fields you actually need; specifically delete the import of ListParameters
and update the AdditionalEnabledPaymentMethodsParams alias to use a locally
declared interface (e.g., declare interface MollieListParameters { /* include
resource?: string and other needed props */ }) or a minimal Partial/Omit-based
local type, then use Partial<Omit<MollieListParameters, 'resource'>> for
AdditionalEnabledPaymentMethodsParams so the module no longer depends on
Mollie’s internal path.

In `@packages/stellate-plugin/lib/src/api/search-response.resolver.d.ts`:
- Around line 3-5: The public method cacheIdentifier currently returns {
collectionSlug: any } which removes type-safety; update its return type to a
concrete string-based type (e.g. { collectionSlug: string } or {
collectionSlug?: string | null } depending on whether collectionSlug can be
absent) in the cacheIdentifier declaration so callers get proper typings; adjust
any internal code in the cacheIdentifier implementation to guarantee/convert to
that string type rather than returning any.

In `@packages/stellate-plugin/lib/src/service/stellate.service.d.ts`:
- Line 55: The purge declaration currently returns Promise<void> | undefined
which forces callers to handle a non-async branch; change the signature of
purge(type: CachedType, keys?: ID[], keyName?: string) to always return
Promise<void>, and update the implementation of StellateService.purge (and any
overrides) to return Promise.resolve() for no-op branches or otherwise return a
Promise so callers can uniformly await it; reference the purge method and the
CachedType/ID/keyName parameters when making the change.
- Around line 3-10: The union type CachedType is over-widened by the trailing "|
string", which defeats literal-type safety; remove the "| string" from the
CachedType definition (or alternatively split into two distinct types such as a
strict literal union named CachedType and a separate alias for arbitrary
strings) so callers get the intended literal types ('Product', 'ProductVariant',
'Collection', 'SearchResponse', 'SearchResult', 'SearchResponseCacheIdentifier')
and maintain type-safety in the code paths that depend on CachedType.
🪄 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: 36be10c2-9088-4849-922c-926ff0678d7a

📥 Commits

Reviewing files that changed from the base of the PR and between fac3fb7 and c248af5.

📒 Files selected for processing (61)
  • .gemini/vendure_gemini_backup/settings.json
  • packages/admin-ui/src/karma.conf.js
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
  • packages/core/src/api/resolvers/entity/collection-entity.resolver.ts
  • packages/core/src/common/constants.ts
  • packages/elasticsearch-plugin/lib/index.d.ts
  • packages/elasticsearch-plugin/lib/src/api/api-extensions.d.ts
  • packages/elasticsearch-plugin/lib/src/api/custom-mappings.resolver.d.ts
  • packages/elasticsearch-plugin/lib/src/api/custom-script-fields.resolver.d.ts
  • packages/elasticsearch-plugin/lib/src/api/elasticsearch-resolver.d.ts
  • packages/elasticsearch-plugin/lib/src/build-elastic-body.d.ts
  • packages/elasticsearch-plugin/lib/src/constants.d.ts
  • packages/elasticsearch-plugin/lib/src/elasticsearch.health.d.ts
  • packages/elasticsearch-plugin/lib/src/elasticsearch.service.d.ts
  • packages/elasticsearch-plugin/lib/src/indexing/elasticsearch-index.service.d.ts
  • packages/elasticsearch-plugin/lib/src/indexing/indexer.controller.d.ts
  • packages/elasticsearch-plugin/lib/src/indexing/indexing-utils.d.ts
  • packages/elasticsearch-plugin/lib/src/options.d.ts
  • packages/elasticsearch-plugin/lib/src/plugin.d.ts
  • packages/elasticsearch-plugin/lib/src/types.d.ts
  • packages/payments-plugin/package/braintree/braintree-common.d.ts
  • packages/payments-plugin/package/braintree/braintree.handler.d.ts
  • packages/payments-plugin/package/braintree/braintree.plugin.d.ts
  • packages/payments-plugin/package/braintree/braintree.resolver.d.ts
  • packages/payments-plugin/package/braintree/constants.d.ts
  • packages/payments-plugin/package/braintree/index.d.ts
  • packages/payments-plugin/package/braintree/types.d.ts
  • packages/payments-plugin/package/index.d.ts
  • packages/payments-plugin/package/mollie/api-extensions.d.ts
  • packages/payments-plugin/package/mollie/constants.d.ts
  • packages/payments-plugin/package/mollie/graphql/generated-shop-types.d.ts
  • packages/payments-plugin/package/mollie/index.d.ts
  • packages/payments-plugin/package/mollie/mollie.common-resolver.d.ts
  • packages/payments-plugin/package/mollie/mollie.controller.d.ts
  • packages/payments-plugin/package/mollie/mollie.handler.d.ts
  • packages/payments-plugin/package/mollie/mollie.helpers.d.ts
  • packages/payments-plugin/package/mollie/mollie.plugin.d.ts
  • packages/payments-plugin/package/mollie/mollie.service.d.ts
  • packages/payments-plugin/package/mollie/mollie.shop-resolver.d.ts
  • packages/payments-plugin/package/mollie/types.d.ts
  • packages/payments-plugin/package/stripe/constants.d.ts
  • packages/payments-plugin/package/stripe/index.d.ts
  • packages/payments-plugin/package/stripe/metadata-sanitize.d.ts
  • packages/payments-plugin/package/stripe/raw-body.middleware.d.ts
  • packages/payments-plugin/package/stripe/stripe-client.d.ts
  • packages/payments-plugin/package/stripe/stripe-utils.d.ts
  • packages/payments-plugin/package/stripe/stripe.controller.d.ts
  • packages/payments-plugin/package/stripe/stripe.handler.d.ts
  • packages/payments-plugin/package/stripe/stripe.plugin.d.ts
  • packages/payments-plugin/package/stripe/stripe.resolver.d.ts
  • packages/payments-plugin/package/stripe/stripe.service.d.ts
  • packages/payments-plugin/package/stripe/types.d.ts
  • packages/stellate-plugin/lib/index.d.ts
  • packages/stellate-plugin/lib/src/api/api-extensions.d.ts
  • packages/stellate-plugin/lib/src/api/search-response.resolver.d.ts
  • packages/stellate-plugin/lib/src/constants.d.ts
  • packages/stellate-plugin/lib/src/default-purge-rules.d.ts
  • packages/stellate-plugin/lib/src/purge-rule.d.ts
  • packages/stellate-plugin/lib/src/service/stellate.service.d.ts
  • packages/stellate-plugin/lib/src/stellate-plugin.d.ts
  • packages/stellate-plugin/lib/src/types.d.ts
💤 Files with no reviewable changes (1)
  • packages/admin-ui/src/karma.conf.js
✅ Files skipped from review due to trivial changes (15)
  • packages/payments-plugin/package/index.d.ts
  • packages/elasticsearch-plugin/lib/index.d.ts
  • packages/payments-plugin/package/braintree/constants.d.ts
  • packages/payments-plugin/package/stripe/raw-body.middleware.d.ts
  • packages/payments-plugin/package/stripe/index.d.ts
  • packages/payments-plugin/package/braintree/index.d.ts
  • .gemini/vendure_gemini_backup/settings.json
  • packages/payments-plugin/package/mollie/index.d.ts
  • packages/elasticsearch-plugin/lib/src/constants.d.ts
  • packages/elasticsearch-plugin/lib/src/build-elastic-body.d.ts
  • packages/payments-plugin/package/mollie/types.d.ts
  • packages/payments-plugin/package/braintree/braintree.plugin.d.ts
  • packages/payments-plugin/package/braintree/braintree-common.d.ts
  • packages/stellate-plugin/lib/src/types.d.ts
  • packages/elasticsearch-plugin/lib/src/plugin.d.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
  • packages/core/src/api/resolvers/entity/collection-entity.resolver.ts

Comment on lines +484 to +485
* This config option allows the the modification of the whole (already built) search query. This allows
* for e.g. wildcard / fuzzy searches on the index.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix minor doc typo in mapQuery description.

Line 484 currently says “allows the the modification”; remove the duplicated “the”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/elasticsearch-plugin/lib/src/options.d.ts` around lines 484 - 485,
Fix the typo in the JSDoc for the mapQuery option: update the comment describing
mapQuery (the doc above the mapQuery symbol) to remove the duplicated word "the"
so the sentence reads "This config option allows the modification of the whole
(already built) search query..." and keep the rest of the description unchanged.

Comment on lines +104 to +105
* PaymentMethod was given the code "mollie-payment-method". The `redirectUrl``is the url that is used to redirect the end-user
* back to your storefront after completing the payment.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix documentation typos in public plugin docs.

Line 104 has malformed inline code punctuation, and Line 168 has a typo (automaticallreleased).

Suggested doc fix
- * PaymentMethod was given the code "mollie-payment-method". The `redirectUrl``is the url that is used to redirect the end-user
+ * PaymentMethod was given the code "mollie-payment-method". The `redirectUrl` is the URL that is used to redirect the end-user
...
- * Make sure to capture a payment within 28 days, after that the payment will be automaticallreleased.
+ * Make sure to capture a payment within 28 days, after that the payment will be automatically released.

Also applies to: 168-168

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/payments-plugin/package/mollie/mollie.plugin.d.ts` around lines 104
- 105, Fix the documentation typos: correct the malformed inline code
punctuation around redirectUrl in the PaymentMethod description (replace the
stray double backticks so it reads `redirectUrl`) and fix the misspelling
`automaticallreleased` to `automatically released` (search for the same phrase
in the mollie plugin docs where that typo appears, e.g., near the
PaymentMethod/redirectUrl text). Ensure the inline code formatting uses single
backticks and the spelling reads "automatically released".

Comment on lines +4 to +5
* Santitize metadata to ensure it follow Stripe's instructions
*
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix JSDoc typo/grammar in description.
Line 4 says “Santitize … it follow”; please correct wording for public API docs quality.

Suggested doc fix
- * Santitize metadata to ensure it follow Stripe's instructions
+ * Sanitize metadata to ensure it follows Stripe's instructions
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* Santitize metadata to ensure it follow Stripe's instructions
*
* Sanitize metadata to ensure it follows Stripe's instructions
*
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/payments-plugin/package/stripe/metadata-sanitize.d.ts` around lines
4 - 5, Fix the JSDoc typo in metadata-sanitize.d.ts: change "Santitize metadata
to ensure it follow Stripe's instructions" to a grammatically correct sentence
(e.g., "Sanitize metadata to ensure it follows Stripe's instructions") in the
JSDoc comment above the exported function (sanitizeMetadata) so public API docs
read correctly; also scan the file for the same typo and update any other
occurrences in the JSDoc.

Comment on lines +3 to +7
* Wrapper around the Stripe client that exposes ApiKey and WebhookSecret
*/
export declare class VendureStripeClient extends Stripe {
private apiKey;
webhookSecret: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Docstring currently overstates API key exposure.

Line 3 says the wrapper exposes the API key, but Line 6 declares apiKey as private. Please align the comment to avoid confusion about secret exposure.

✏️ Suggested wording fix
- * Wrapper around the Stripe client that exposes ApiKey and WebhookSecret
+ * Wrapper around the Stripe client that stores the API key internally
+ * and exposes the webhook secret for webhook verification.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* Wrapper around the Stripe client that exposes ApiKey and WebhookSecret
*/
export declare class VendureStripeClient extends Stripe {
private apiKey;
webhookSecret: string;
* Wrapper around the Stripe client that stores the API key internally
* and exposes the webhook secret for webhook verification.
*/
export declare class VendureStripeClient extends Stripe {
private apiKey;
webhookSecret: string;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/payments-plugin/package/stripe/stripe-client.d.ts` around lines 3 -
7, The class docstring is misleading about secret exposure: update the comment
for VendureStripeClient to state that the API key is stored privately (apiKey is
a private field) and only the webhook secret (webhookSecret) is
exposed/accessible, so it doesn't imply the API key is exposed; reference
VendureStripeClient, apiKey, and webhookSecret when making this wording change.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/core/src/service/services/collection.service.ts (1)

1077-1086: Consider using innerJoin instead of leftJoin for the product relation.

The comment states "We explicitly join with the product to ensure we filter out soft-deleted products", but using leftJoin could include orphaned variants where product is NULL. Since you're filtering with product.deletedAt IS NULL (which would exclude NULL products anyway), an innerJoin would be more semantically correct and slightly more efficient.

♻️ Suggested change
-        qb.leftJoin('productvariant.product', 'product')
+        qb.innerJoin('productvariant.product', 'product')
             .innerJoin('productvariant.collections', 'collection', 'collection.id IN (:...collectionIds)', {
                 collectionIds,
             })
             .andWhere('product.deletedAt IS NULL')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/service/services/collection.service.ts` around lines 1077 -
1086, The current query uses qb.leftJoin('productvariant.product', 'product')
which can allow null products; change this to an inner join so orphaned variants
are excluded at the join level: replace the leftJoin on productvariant.product
with an innerJoin and keep the existing
innerJoin('productvariant.collections','collection',...) and the
andWhere('product.deletedAt IS NULL') and addSelect lines unchanged; update
references to qb.leftJoin -> qb.innerJoin for the product relation
(function/variable: qb, relation: productvariant.product, predicate:
product.deletedAt IS NULL, aliases: product, collectionId, variantId).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/core/src/service/services/collection.service.ts`:
- Around line 1077-1086: The current query uses
qb.leftJoin('productvariant.product', 'product') which can allow null products;
change this to an inner join so orphaned variants are excluded at the join
level: replace the leftJoin on productvariant.product with an innerJoin and keep
the existing innerJoin('productvariant.collections','collection',...) and the
andWhere('product.deletedAt IS NULL') and addSelect lines unchanged; update
references to qb.leftJoin -> qb.innerJoin for the product relation
(function/variable: qb, relation: productvariant.product, predicate:
product.deletedAt IS NULL, aliases: product, collectionId, variantId).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 711e3433-9ce5-4076-acd2-2ed6d2f600ff

📥 Commits

Reviewing files that changed from the base of the PR and between c248af5 and ba2ac94.

📒 Files selected for processing (14)
  • packages/core/src/api/middleware/auth-guard.ts
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
  • packages/core/src/api/resolvers/entity/collection-entity.resolver.ts
  • packages/core/src/common/constants.ts
  • packages/core/src/config/auth/default-verification-token-strategy.ts
  • packages/core/src/config/config.module.ts
  • packages/core/src/config/order/order-by-code-access-strategy.ts
  • packages/core/src/plugin/default-scheduler-plugin/default-scheduler-strategy.ts
  • packages/core/src/service/helpers/list-query-builder/list-query-builder.ts
  • packages/core/src/service/helpers/list-query-builder/parse-filter-params.ts
  • packages/core/src/service/helpers/settings-store/settings-store.service.ts
  • packages/core/src/service/services/collection.service.ts
  • packages/core/src/service/services/product-variant.service.ts
  • packages/core/src/service/services/session.service.ts
✅ Files skipped from review due to trivial changes (6)
  • packages/core/src/config/auth/default-verification-token-strategy.ts
  • packages/core/src/config/order/order-by-code-access-strategy.ts
  • packages/core/src/service/helpers/settings-store/settings-store.service.ts
  • packages/core/src/plugin/default-scheduler-plugin/default-scheduler-strategy.ts
  • packages/core/src/service/services/session.service.ts
  • packages/core/src/common/constants.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/core/src/api/middleware/auth-guard.ts
  • packages/core/src/api/resolvers/admin/collection.resolver.ts
  • packages/core/src/service/helpers/list-query-builder/parse-filter-params.ts
  • packages/core/src/service/services/product-variant.service.ts
  • packages/core/src/config/config.module.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts (2)

40-45: Query capture predicate is too loose and mutation of shared capturedQueries is racy across tests.

query.includes('SELECT') && query.includes('"product"') will match unrelated statements (e.g. product_variant, product_translation, product_option_group — all contain the substring product, and with MySQL backticks `product_variant` also contains `product` as a substring is false, but the double-quoted case "product_variant" does not contain "product"; however "product_translation" likewise does not — so this is actually narrower than it looks). More importantly, the check allows any capitalization/casing mismatch to slip through and, since capturedQueries is module-scoped and only reset inside each it before issuing the query, any background queries from server.init or auth (asSuperAdmin) prior to the first test can persist; and if tests ever run concurrently, captures from one test can bleed into another.

Consider (a) scoping the filter to exact table identifiers ("product" / `product` as full quoted identifiers with word boundaries), and (b) ensuring the reset is tied to the test lifecycle (e.g. beforeEach) rather than ad-hoc before each adminClient.query.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts` around lines 40 - 45,
The current predicate that pushes SQL into capturedQueries (the check using
query.includes('SELECT') && (query.includes('"product"') ||
query.includes('`product`'))) is too loose and capturedQueries is module-scoped
causing racy cross-test leakage; change the filter in the capture handler to
match full quoted table identifiers using a stricter regex/word-boundary match
for exact identifiers like "product" or `product` (and ensure SELECT is matched
case-insensitively), and move the capturedQueries reset into the test lifecycle
(use beforeEach to reinitialize capturedQueries before each test) instead of
ad-hoc before calling adminClient.query or relying on server.init/asSuperAdmin
timing.

67-67: Hardcoded fixture path couples e2e-common to packages/core internal structure.

The relative path path.join(__dirname, '../../packages/core/e2e/fixtures/e2e-products-minimal.csv') breaks the established pattern where each package maintains its own fixtures directory. This approach is fragile: reorganizing packages/core/e2e/fixtures/ or running this spec from a different working directory silently fails during the 240s timeout.

Either add a fixture under e2e-common/fixtures/ to match the pattern used by other packages (asset-server-plugin, cli, core, dashboard, job-queue-plugin), or export a fixtures-path helper from @vendure/testing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts` at line 67, The
hardcoded reference to a fixture inside packages/core ties e2e-common to core;
update the productsCsvPath usage in benchmark-list-query.e2e-spec.ts (the
productsCsvPath variable) to follow the shared-fixtures pattern: either add
e2e-products-minimal.csv into e2e-common/fixtures and point productsCsvPath to
that fixtures directory (e.g. use path.join(__dirname, '../fixtures/...')), or
instead add and use a fixtures-path helper exported from `@vendure/testing` and
replace the direct path with that helper so the test no longer depends on
packages/core internal layout.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts`:
- Around line 93-100: The test uses _and with two eq conditions on the same
field (testManyToManyId) which can never match; update the filter in
benchmark-list-query.e2e-spec.ts to use two distinct FacetValue IDs that are
known to be assigned to the same Product in the fixtures (e.g., replace the
duplicate eq '1' and '2' with the actual pair that co-occur on a product), and
add assertions after the query to verify totalItems and items content (assert
the expected product id(s) and count) so the test fails if the query collapses
to a single EXISTS or otherwise returns semantically incorrect results while
still passing structural SQL checks.
- Around line 102-174: The tests name the variable lastQuery but use
capturedQueries.find which returns the first match; change each test's lookup
(the three blocks referencing lastQuery) to select the final matching SQL
statement—either by using Array.prototype.findLast (or reverse-iterating
capturedQueries) or by tightening the predicate to only match the items SELECT
(e.g., exclude "SELECT COUNT" or require "SELECT" with columns) so the assertion
on capturedQueries/lastQuery in the filter and sort tests (references:
capturedQueries, lastQuery) targets the actual items query and not the
COUNT/earlier statements.

---

Nitpick comments:
In `@e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts`:
- Around line 40-45: The current predicate that pushes SQL into capturedQueries
(the check using query.includes('SELECT') && (query.includes('"product"') ||
query.includes('`product`'))) is too loose and capturedQueries is module-scoped
causing racy cross-test leakage; change the filter in the capture handler to
match full quoted table identifiers using a stricter regex/word-boundary match
for exact identifiers like "product" or `product` (and ensure SELECT is matched
case-insensitively), and move the capturedQueries reset into the test lifecycle
(use beforeEach to reinitialize capturedQueries before each test) instead of
ad-hoc before calling adminClient.query or relying on server.init/asSuperAdmin
timing.
- Line 67: The hardcoded reference to a fixture inside packages/core ties
e2e-common to core; update the productsCsvPath usage in
benchmark-list-query.e2e-spec.ts (the productsCsvPath variable) to follow the
shared-fixtures pattern: either add e2e-products-minimal.csv into
e2e-common/fixtures and point productsCsvPath to that fixtures directory (e.g.
use path.join(__dirname, '../fixtures/...')), or instead add and use a
fixtures-path helper exported from `@vendure/testing` and replace the direct path
with that helper so the test no longer depends on packages/core internal layout.
🪄 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: 3b0957a4-0a70-45c4-b973-6c0f8dd0c85d

📥 Commits

Reviewing files that changed from the base of the PR and between ba2ac94 and a79acfa.

📒 Files selected for processing (5)
  • .gemini/settings.json
  • .gemini/vendure_gemini_backup/settings.json
  • .gitignore
  • e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts
  • packages/core/src/api/middleware/auth-guard.ts
✅ Files skipped from review due to trivial changes (4)
  • .gemini/vendure_gemini_backup/settings.json
  • packages/core/src/api/middleware/auth-guard.ts
  • .gemini/settings.json
  • .gitignore

Comment thread e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts
Comment thread e2e-common/benchmarks/benchmark-list-query.e2e-spec.ts Outdated
@michaelbromley
Copy link
Copy Markdown
Member

Hi, before I can properly review this, it needs to be cleaned up to include only the changes related to the fix.

@RubenDarioGuerreroNeira
Copy link
Copy Markdown
Author

Hi @michaelbromley, I have cleaned up the PR as requested. I removed all unrelated changes, including minor
formatting tweaks, accidental config files, and internal tool settings. The PR now only includes the core logic
for the N+1 optimization of collection variants and the catalog filter persistence, along with the corresponding
benchmark test. Ready for your review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants