Skip to content

Los cambios de coderabbit - #64

Merged
CrisNAC merged 2 commits into
devfrom
OM-97-
Mar 27, 2026
Merged

CrisNAC merged 2 commits into
devfrom
OM-97-

Conversation

@Lianyang1234

@Lianyang1234 Lianyang1234 commented Mar 26, 2026 •

Copy link
Copy Markdown
Collaborator

Los cambios de coderabbit

Summary by CodeRabbit

Notas de Lanzamiento

  • Correcciones de Errores

    • Se mejoró el filtrado de productos por rango de precio. Ahora funciona correctamente tanto para productos regulares como para artículos en oferta.
  • Pruebas

    • Se agregaron nuevas pruebas de integración para validar que el filtrado por rango de precio en la API de productos opera de forma precisa.

@coderabbitai

coderabbitai Bot commented Mar 26, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Recorrido

Se actualiza la lógica de construcción de filtros en el servicio filterStoreProductsService para manejar restricciones de oferta/estado y rango de precios. Introduce normalizedIsOfferFilter para preservar el valor normalizado de isOffer e implementa un objeto effectivePriceRange que se aplica condicionalmente mediante ramas OR diferenciadas: productos sin oferta con price y productos en oferta con offer_price.

Cambios

Cohort / Archivo(s) Resumen
Lógica de filtrado de precios y ofertas
src/modules/commerce/commerces/store.service.js
Se refactoriza la construcción de filtros de rango de precios para aplicar condiciones OR separadas según el estado de oferta: productos sin oferta filtrados por price y productos en oferta filtrados por offer_price. Se introduce normalizedIsOfferFilter para preservar la entrada normalizada.
Validación de filtrado con e2e
tests/e2e/stores.test.js
Se añade prueba e2e para el endpoint GET /api/commerces/products/filter/:id que verifica la lógica de filtrado de precios efectivos, validando que la consulta a Prisma incluya cláusulas OR con ramas AND diferenciadas por tipo de producto (con/sin oferta).

Esfuerzo estimado de revisión de código

🎯 4 (Complejo) | ⏱️ ~50 minutos

PRs posiblemente relacionados

  • Filtro por ofertas #59: Ambas PRs modifican la lógica de filtrado de precios y ofertas en filterStoreProductsService, incluyendo cambios relacionados a campos is_offer/offer_price contra price y sus correspondientes pruebas.
  • OM-424: Refactorizando GET /commerces/products/filter/{id} #54: Ambas PRs afectan la misma función de servicio en src/modules/commerce/commerces/store.service.js; esta PR modifica la lógica interna de filtrado de precios y ofertas.

Revisores sugeridos

  • CrisNAC
  • SebaKisser

Poema 🐰

🥕 Con filtros renovados y ofertas brillando,
El conejo salta entre precios danzando,
Ofertas y productos en armonía se encuentran,
Con ramas de OR que juntas se aventuran,
¡La búsqueda perfecta ahora es realidad! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive El título 'Los cambios de coderabbit' es genérico y no describe específicamente los cambios realizados en el repositorio. Se recomienda usar un título más descriptivo que refleje el cambio principal, como 'Refactor filtrado de productos por precio en ofertas' o similar que especifique qué se modificó.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch OM-97-

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/e2e/stores.test.js (1)

170-207: Sumá cobertura para count y para isOffer=true/false.

Este caso solo cubre el camino donde no llega filtro de oferta y además inspecciona findMany, pero no count. Si se rompe la rama nueva que deja un solo lado del OR (?isOffer=true/false o ?is_offer=) o count queda armando otro where, el endpoint puede volver a 404 y este test seguir verde.

Podés cerrar el gap con casos como:

  • ?isOffer=true&price_min=10&price_max=15 → solo rama offer_price
  • ?is_offer=false&price_min=10&price_max=15 → solo rama price
  • misma verificación del where en prisma.products.count
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/e2e/stores.test.js` around lines 170 - 207, Add tests to cover the
missing branches and ensure both prisma.products.findMany and
prisma.products.count receive the correct where filter: add a request to
"/api/commerces/products/filter/1?isOffer=true&price_min=10&price_max=15" and
assert prisma.products.findMany and prisma.products.count are called with a
where that only contains the offer_price clause (is_offer: true AND offer_price
gte/lte), add a request to
"/api/commerces/products/filter/1?is_offer=false&price_min=10&price_max=15" and
assert both findMany and count are called with a where that only contains the
price clause (is_offer: false AND price gte/lte), and mirror the same
expect.objectContaining checks you used in the existing test (referencing
prisma.products.findMany and prisma.products.count) so the new tests fail if
either side of the OR or the count query is constructed incorrectly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/commerce/commerces/store.service.js`:
- Around line 841-875: Valida resolvedMinPrice y resolvedMaxPrice antes de
construir effectivePriceRange: rechaza valores vacíos o no numéricos (evitar que
Number("") => 0 o Number("abc") => NaN) y responde con 400; convierte sólo
cuando Number.isFinite(Number(value)) es true; además, si ambos existen valida
que Number(resolvedMinPrice) <= Number(resolvedMaxPrice) y rechaza con 400 si
no; después de estas comprobaciones procede a poblar effectivePriceRange y
construir las ramas que usan normalizedIsOfferFilter y whereConditions.OR como
ahora.

---

Nitpick comments:
In `@tests/e2e/stores.test.js`:
- Around line 170-207: Add tests to cover the missing branches and ensure both
prisma.products.findMany and prisma.products.count receive the correct where
filter: add a request to
"/api/commerces/products/filter/1?isOffer=true&price_min=10&price_max=15" and
assert prisma.products.findMany and prisma.products.count are called with a
where that only contains the offer_price clause (is_offer: true AND offer_price
gte/lte), add a request to
"/api/commerces/products/filter/1?is_offer=false&price_min=10&price_max=15" and
assert both findMany and count are called with a where that only contains the
price clause (is_offer: false AND price gte/lte), and mirror the same
expect.objectContaining checks you used in the existing test (referencing
prisma.products.findMany and prisma.products.count) so the new tests fail if
either side of the OR or the count query is constructed incorrectly.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c43f76c8-7d3d-484a-a5f6-149004a2c065

📥 Commits

Reviewing files that changed from the base of the PR and between 5b8f317 and 8459c03.

📒 Files selected for processing (2)
  • src/modules/commerce/commerces/store.service.js
  • tests/e2e/stores.test.js

Comment on lines +841 to 875
const effectivePriceRange = {};
if (resolvedMinPrice !== undefined && resolvedMinPrice !== null) {
whereConditions.price = { gte: Number(resolvedMinPrice) };
effectivePriceRange.gte = Number(resolvedMinPrice);
}

if (resolvedMaxPrice !== undefined && resolvedMaxPrice !== null) {
whereConditions.price = {
...whereConditions.price,
lte: Number(resolvedMaxPrice)
};
effectivePriceRange.lte = Number(resolvedMaxPrice);
}

if (Object.keys(effectivePriceRange).length > 0) {
const effectivePriceBranches = [];

if (normalizedIsOfferFilter !== true) {
effectivePriceBranches.push({
AND: [
{ is_offer: false },
{ price: effectivePriceRange }
]
});
}

if (normalizedIsOfferFilter !== false) {
effectivePriceBranches.push({
AND: [
{ is_offer: true },
{ offer_price: effectivePriceRange }
]
});
}

whereConditions.OR = [
...(Array.isArray(whereConditions.OR) ? whereConditions.OR : []),
...effectivePriceBranches
];
}

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 | 🟠 Major

Validá price_min y price_max antes de armar el rango.

Acá Number("") termina en 0 y Number("abc") en NaN. Con el fallback a req.query, eso puede abrir el filtro de más o mandar un rango inválido a Prisma en vez de rechazar la request con 400. También conviene rechazar price_min > price_max antes de construir el OR.

🛠️ Propuesta de ajuste
     const resolvedMinPrice = minPrice ?? price_min;
     const resolvedMaxPrice = maxPrice ?? price_max;
 
+    const parseOptionalPrice = (value, fieldName) => {
+      if (value === undefined || value === null) {
+        return undefined;
+      }
+
+      if (typeof value === "string" && value.trim() === "") {
+        return undefined;
+      }
+
+      const parsedValue = Number(value);
+      if (!Number.isFinite(parsedValue)) {
+        throw { status: 400, message: `${fieldName} invalido` };
+      }
+
+      return parsedValue;
+    };
+
-    const effectivePriceRange = {};
-    if (resolvedMinPrice !== undefined && resolvedMinPrice !== null) {
-      effectivePriceRange.gte = Number(resolvedMinPrice);
-    }
+    const parsedMinPrice = parseOptionalPrice(resolvedMinPrice, "price_min");
+    const parsedMaxPrice = parseOptionalPrice(resolvedMaxPrice, "price_max");
+
+    if (
+      parsedMinPrice !== undefined &&
+      parsedMaxPrice !== undefined &&
+      parsedMinPrice > parsedMaxPrice
+    ) {
+      throw { status: 400, message: "price_min no puede ser mayor que price_max" };
+    }
+
+    const effectivePriceRange = {};
+    if (parsedMinPrice !== undefined) {
+      effectivePriceRange.gte = parsedMinPrice;
+    }
 
-    if (resolvedMaxPrice !== undefined && resolvedMaxPrice !== null) {
-      effectivePriceRange.lte = Number(resolvedMaxPrice);
+    if (parsedMaxPrice !== undefined) {
+      effectivePriceRange.lte = parsedMaxPrice;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/commerce/commerces/store.service.js` around lines 841 - 875,
Valida resolvedMinPrice y resolvedMaxPrice antes de construir
effectivePriceRange: rechaza valores vacíos o no numéricos (evitar que
Number("") => 0 o Number("abc") => NaN) y responde con 400; convierte sólo
cuando Number.isFinite(Number(value)) es true; además, si ambos existen valida
que Number(resolvedMinPrice) <= Number(resolvedMaxPrice) y rechaza con 400 si
no; después de estas comprobaciones procede a poblar effectivePriceRange y
construir las ramas que usan normalizedIsOfferFilter y whereConditions.OR como
ahora.

@CrisNAC
CrisNAC merged commit 2b9a0b2 into dev Mar 27, 2026
1 of 2 checks passed
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