Skip to content

OM-77 - #19

Merged
Andoumeda merged 5 commits into
devfrom
OM-77
Mar 11, 2026
Merged

Andoumeda merged 5 commits into
devfrom
OM-77

Conversation

@leoAchu16

@leoAchu16 leoAchu16 commented Mar 10, 2026 •

Copy link
Copy Markdown
Collaborator

El ticket OM-77 terminado.
Obs.: Hacer "npx prisma generate" debido a un cambio en schema.prisma.

Summary by CodeRabbit

Notas de Lanzamiento

  • Nuevas Funcionalidades
    • Se agregó búsqueda de productos con capacidad de filtrar por nombre y descripción.
    • Implementación de paginación para resultados de búsqueda.
    • Ordenamiento inteligente: por relevancia en búsquedas y por defecto en listados.

@coderabbitai

coderabbitai Bot commented Mar 10, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Se implementó una funcionalidad de búsqueda de productos con soporte para filtrado por nombre/descripción, paginación y ordenamiento por relevancia. Se agregó un generador Prisma para fullTextSearchPostgres, un nuevo endpoint GET, controlador y servicio con lógica de búsqueda e filtraje.

Changes

Cohort / File(s) Summary
Configuración de Base de Datos
prisma/schema.prisma
Se habilitó la opción de vista previa de generador Prisma para fullTextSearchPostgres, expandiendo capacidades de búsqueda de texto completo en PostgreSQL.
Capa de Enrutamiento
src/modules/commerce/products/product.routes.js
Se importó y registró la nueva función controladora getProductsSearch con una ruta GET "/" para manejar solicitudes de búsqueda de productos.
Capa de Controlador
src/modules/commerce/products/product.controller.js
Se agregó nuevo endpoint getProductsSearch que importa el servicio de búsqueda, procesa parámetros de consulta y devuelve resultados con manejo de errores estandarizado.
Capa de Servicio
src/modules/commerce/products/product.service.js
Se implementó getProductsSearchService con filtrado por estado/visibilidad, búsqueda case-insensitive en nombre/descripción, paginación, ordenamiento por relevancia y retorno de datos con información de paginación.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Router
    participant Controller
    participant Service
    participant Database

    Client->>Router: GET /?search=keyword&page=1&limit=10
    Router->>Controller: getProductsSearch(request, response)
    Controller->>Service: getProductsSearchService(query)
    Service->>Database: COUNT products (status=true, visible=true)
    Service->>Database: SELECT products (filtered, paginated, ordered)
    Database-->>Service: totalProducts, products[]
    Service-->>Controller: {products, pagination}
    Controller-->>Client: 200 {data, pagination}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • SebaKisser

Poem

🐰 Una búsqueda nueva florece en el jardín,
Con filtros y paginación, qué elegante fin,
Los productos danzarán por relevancia,
PostgreSQL canta con su confianza,
¡Que busque el cliente sin preocupación! 🌸

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive El título es vago y genérico, solo contiene un identificador de ticket sin describir el cambio principal del PR. Cambiar el título a una descripción clara del cambio, por ejemplo: 'Agregar endpoint de búsqueda de productos con soporte de búsqueda de texto completo'.
✅ 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 (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch OM-77

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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: 2

🧹 Nitpick comments (3)
src/modules/commerce/products/product.controller.js (2)

24-27: El console.info está ubicado después de obtener los productos.

El mensaje "Obteniendo productos..." se loguea después de que los productos ya fueron obtenidos. Si el propósito es trazar el inicio de la operación, debería estar antes de la llamada al servicio. Si es para confirmar éxito, el mensaje debería reflejar eso.

♻️ Sugerencia para corregir el orden del log
 export const getProductsSearch = async (request, response) => {
   try {
+    console.info("Obteniendo productos...");
     const filterProducts = await getProductsSearchService(request.query);
-    console.info("Obteniendo productos...")
     return response.status(200).json(filterProducts);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/commerce/products/product.controller.js` around lines 24 - 27, El
log "Obteniendo productos..." está después de la llamada a
getProductsSearchService, por lo que no marca el inicio de la operación; mueve
la llamada a console.info antes de invocar
getProductsSearchService(request.query) (por ejemplo colocar
console.info("Obteniendo productos...") justo antes de la llamada) o, si
prefieres confirmar éxito, cambia el texto del log posterior a algo como
"Productos obtenidos" y deja el inicio antes; edita el bloque que usa
getProductsSearchService y filterProducts para reflejar ese cambio.

17-17: Pequeño typo en el comentario.

Falta un espacio: "losproductos" → "los productos".

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

In `@src/modules/commerce/products/product.controller.js` at line 17, Corrige el
comentario en product.controller.js donde aparece "/** GET: Para obtener todos
losproductos..." cambiando "losproductos" a "los productos" (localiza el
comentario text "/** GET: Para obtener todos losproductos o buscar segun nombre
o descripcion (por el momento)." y añade el espacio entre "los" y "productos").
src/modules/commerce/products/product.service.js (1)

254-260: El ordenamiento por relevancia solo considera name, pero la búsqueda incluye description.

La búsqueda con contains busca en name y description, pero _relevance solo calcula score sobre name. Esto puede causar que productos que coinciden solo en description aparezcan con relevancia baja o cero.

♻️ Considerar incluir description en _relevance
     orderBy = {
       _relevance: {
-        fields: ['name'],
+        fields: ['name', 'description'],
         search: search,
         sort: 'desc',
       },
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/commerce/products/product.service.js` around lines 254 - 260, La
ordenación por relevancia (la variable orderBy con _relevance y fields:
['name']) solo calcula score sobre name mientras la búsqueda usa search sobre
name y description; actualiza orderBy._relevance.fields para incluir
'description' junto a 'name' (p. ej. fields: ['name','description']) —
asegurándote de preservar la variable search y la estructura _relevance para que
los resultados que coincidan solo en description obtengan puntuación de
relevancia coherente.
🤖 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/products/product.routes.js`:
- Around line 6-7: The POST route currently calls createProduct without
authentication; add the existing authenticate middleware (the same used in
store.routes.js) to the router.post call so requests to createProduct run
authentication first and reject missing/invalid x-user-id before hitting the
controller; update the route declaration to include authenticate between
router.post and createProduct to ensure consistent validation.

In `@src/modules/commerce/products/product.service.js`:
- Around line 238-240: The limit variable currently has no upper bound, allowing
very large queries; clamp it to a safe maximum (e.g., 100) before computing
skip. Update the logic where page, limit, and skip are computed in
product.service.js (variables page, limit, skip) to coerce filters.limit to
Number, enforce a maxLimit (100), and use the bounded value when calculating
skip so clients cannot request more than 100 items per page.

---

Nitpick comments:
In `@src/modules/commerce/products/product.controller.js`:
- Around line 24-27: El log "Obteniendo productos..." está después de la llamada
a getProductsSearchService, por lo que no marca el inicio de la operación; mueve
la llamada a console.info antes de invocar
getProductsSearchService(request.query) (por ejemplo colocar
console.info("Obteniendo productos...") justo antes de la llamada) o, si
prefieres confirmar éxito, cambia el texto del log posterior a algo como
"Productos obtenidos" y deja el inicio antes; edita el bloque que usa
getProductsSearchService y filterProducts para reflejar ese cambio.
- Line 17: Corrige el comentario en product.controller.js donde aparece "/**
GET: Para obtener todos losproductos..." cambiando "losproductos" a "los
productos" (localiza el comentario text "/** GET: Para obtener todos
losproductos o buscar segun nombre o descripcion (por el momento)." y añade el
espacio entre "los" y "productos").

In `@src/modules/commerce/products/product.service.js`:
- Around line 254-260: La ordenación por relevancia (la variable orderBy con
_relevance y fields: ['name']) solo calcula score sobre name mientras la
búsqueda usa search sobre name y description; actualiza
orderBy._relevance.fields para incluir 'description' junto a 'name' (p. ej.
fields: ['name','description']) — asegurándote de preservar la variable search y
la estructura _relevance para que los resultados que coincidan solo en
description obtengan puntuación de relevancia coherente.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2dcd627f-f898-4713-900e-db027016013c

📥 Commits

Reviewing files that changed from the base of the PR and between 711ee59 and f8166e1.

📒 Files selected for processing (4)
  • prisma/schema.prisma
  • src/modules/commerce/products/product.controller.js
  • src/modules/commerce/products/product.routes.js
  • src/modules/commerce/products/product.service.js

Comment on lines 6 to +7
router.post("/", createProduct);
router.get("/", getProductsSearch);

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verificar cómo se registran las rutas de productos y si hay middlewares de autenticación aplicados a nivel superior

# Buscar dónde se monta el router de productos
rg -n "product" --type js -g '*.routes.js' -g 'index.js' -g 'app.js' -A 3 -B 1

# Verificar si hay middleware de autenticación
rg -n "auth" --type js -g '*.js' -A 2

Repository: CrisNAC/BackendMarketplace

Length of output: 5260


🏁 Script executed:

# Ver el archivo completo de rutas de productos
cat -n src/modules/commerce/products/product.routes.js

# Ver la implementación del controlador getProductsSearch
cat -n src/modules/commerce/products/product.controller.js

Repository: CrisNAC/BackendMarketplace

Length of output: 1979


Agregar middleware de autenticación a la ruta POST.

La ruta GET / sin autenticación es intencional—es un endpoint público para búsqueda de productos (como se indica en el comentario del controlador, línea 22). Sin embargo, la ruta POST / depende de x-user-id extraído del cliente sin validar. El servicio interno valida su presencia (lanzando 401 si falta), pero es más seguro usar el middleware authenticate importado en otras rutas (store.routes.js). Esto proporciona validación consistente y fallará antes de llegar al controlador.

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

In `@src/modules/commerce/products/product.routes.js` around lines 6 - 7, The POST
route currently calls createProduct without authentication; add the existing
authenticate middleware (the same used in store.routes.js) to the router.post
call so requests to createProduct run authentication first and reject
missing/invalid x-user-id before hitting the controller; update the route
declaration to include authenticate between router.post and createProduct to
ensure consistent validation.

Comment on lines +238 to +240
const page = Number(filters.page) > 0 ? Number(filters.page) : 1;
const limit = Number(filters.limit) > 0 ? Number(filters.limit) : 20; //por defecto trae hasta 20 productos
const skip = (page - 1) * limit;

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

Agregar límite máximo al parámetro limit para evitar consultas excesivamente grandes.

No hay un límite superior para limit, lo que podría permitir que un cliente solicite miles de registros en una sola petición. Otros servicios similares en el código (como product-category.service.js y product-tag.service.js) limitan a 100.

🛡️ Sugerencia para agregar límite máximo
   //Paginacion
   const page = Number(filters.page) > 0 ? Number(filters.page) : 1;
-  const limit = Number(filters.limit) > 0 ? Number(filters.limit) : 20; //por defecto trae hasta 20 productos
+  const limitRaw = Number(filters.limit);
+  const limit = Number.isInteger(limitRaw) && limitRaw > 0
+    ? Math.min(limitRaw, 100)
+    : 20; //por defecto trae hasta 20 productos, máximo 100
   const skip = (page - 1) * limit;
📝 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
const page = Number(filters.page) > 0 ? Number(filters.page) : 1;
const limit = Number(filters.limit) > 0 ? Number(filters.limit) : 20; //por defecto trae hasta 20 productos
const skip = (page - 1) * limit;
const page = Number(filters.page) > 0 ? Number(filters.page) : 1;
const limitRaw = Number(filters.limit);
const limit = Number.isInteger(limitRaw) && limitRaw > 0
? Math.min(limitRaw, 100)
: 20; //por defecto trae hasta 20 productos, máximo 100
const skip = (page - 1) * limit;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/commerce/products/product.service.js` around lines 238 - 240, The
limit variable currently has no upper bound, allowing very large queries; clamp
it to a safe maximum (e.g., 100) before computing skip. Update the logic where
page, limit, and skip are computed in product.service.js (variables page, limit,
skip) to coerce filters.limit to Number, enforce a maxLimit (100), and use the
bounded value when calculating skip so clients cannot request more than 100
items per page.

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