Skip to content

OM-536: Inicio de trabajo - #173

Merged
CrisNAC merged 7 commits into
devfrom
OM-536
May 28, 2026
Merged

CrisNAC merged 7 commits into
devfrom
OM-536

Conversation

@Benjakr04

@Benjakr04 Benjakr04 commented May 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Notas de Versión

  • Nuevas Características

    • Ahora se pueden gestionar múltiples carritos activos simultáneamente por usuario y comercio.
    • Los carritos anteriormente comprados se marcan automáticamente como abandonados al crear una nueva orden.
  • Documentación

    • Se agregaron esquemas de API para mejorar la documentación de carritos.
  • Tests

    • Se actualizaron tests unitarios para validar el nuevo comportamiento de gestión de carritos.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 27, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Benjakr04, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 43 minutes and 34 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f542395c-22ce-4931-9eae-cce273ea998a

📥 Commits

Reviewing files that changed from the base of the PR and between 805ce3d and f5d5b7e.

📒 Files selected for processing (1)
  • tests/unit/order/order.test.js
📝 Walkthrough

Resumen ejecutivo

Se permite que múltiples carritos coexistan en estado CHECKED_OUT por usuario y tienda mediante una restricción única filtrada en Prisma, se actualiza el flujo de checkout para marcar carritos previos como ABANDONED, se documenta el dominio de carrito con esquemas OpenAPI, y se ajustan tests para soportar nuevas operaciones de repositorio.

Cambios

Modelo de carrito, restricción parcial y flujo de checkout

Capa / Archivo(s) Resumen
Prisma: previewFeatures e índice único filtrado
prisma/schema.prisma, prisma/migrations/20260528123758_allow_multiple_checked_out_carts/migration.sql
Se agrega partialIndexes a previewFeatures del generador Prisma, y se modifica la restricción @@unique del modelo Carts para aplicarse únicamente cuando cart_status = "ACTIVE" mediante cláusula where, permitiendo múltiples carritos en otros estados (CHECKED_OUT, ABANDONED) por usuario y tienda. La migración SQL elimina el índice existente y crea el nuevo índice único filtrado.
Servicio de carrito: aclaración de upsert
src/modules/users/cart/cart.service.js
getOrCreateActiveCart actualiza su JSDoc para aclarar explícitamente que usa upsert en lugar de findFirst+create, evitando condiciones de carrera al obtener o crear el carrito ACTIVE por usuario y tienda. La lógica de implementación permanece equivalente.
Servicio de orden: checkout marca carritos previos como ABANDONED
src/modules/users/orders/order.service.js
createOrderService reemplaza la actualización exclusiva del carrito actual a CHECKED_OUT por un flujo de dos pasos: primero actualiza todos los carritos previos en estado CHECKED_OUT a ABANDONED mediante tx.carts.updateMany, luego marca el carrito actual como CHECKED_OUT.
Esquemas OpenAPI del carrito
src/docs/schemas/users/cart.schema.js
Nuevo módulo que exporta cartSchemas con definiciones JSON/OpenAPI para CartItem (con product e información de precios/ofertas), CartCommerceInfo, Cart (con array de items), respuestas de endpoints (GetCartsResponse, DeleteCartResponse, DeleteAllCartsResponse), y estructuras de error/validación con ejemplos.
Integración de esquemas en Swagger
src/config/swagger.config.js
Se incorpora cartSchemas en la importación desde ../docs/schemas/index.js y se agrega el spread ...cartSchemas a components.schemas en la configuración de Swagger para exponer los esquemas de carrito en la documentación OpenAPI generada.
Tests de carrito: limpieza de comentarios inline
tests/unit/cart/cart.test.js
Se eliminan comentarios inline descriptivos en tests de addCartItemService, getCartItemsByIdService, updatedCartItemQuantityService, deleteCartService y deleteAllCartsService para mejorar legibilidad, sin cambios en lógica de ejecución ni aserciones verificadas.
Tests de orden: refactor de mocks de transacción
tests/unit/order/order.test.js
Se agrega updateMany a mocks de prisma.carts y findMany a mocks de prisma.orderItems. Se refactoriza prisma.$transaction en tests de createOrderService para construir un mockTx con repositorios inyectados en lugar de pasar prisma directamente, simplificando aserciones de transacción y eliminando inspecciones del callback en getStoreOrdersService.

🎯 3 (Moderado) | ⏱️ ~25 minutos

PRs posiblemente relacionados

  • CrisNAC/BackendMarketplace#84: Ambas PRs modifican src/modules/users/orders/order.service.js en la función createOrderService; la PR actual cambia el estado de carritos al crear la orden mientras la PR #84 reestructura el cálculo de costos de envío.
  • CrisNAC/BackendMarketplace#79: Ambas PRs ajustan pruebas unitarias de tests/unit/order/order.test.js para createOrderService con mocks de Prisma, incluyendo operaciones adicionales como carts.updateMany.
  • CrisNAC/BackendMarketplace#53: La PR actual refina la lógica de Carts y cart_status (restricción @@unique filtrada y flujo de ABANDONED/CHECKED_OUT), directamente alineado con el PR que introduce el modelo Carts y la relación Orders.fk_cart.

Revisores sugeridos

  • leoAchu16
  • elianasmz
  • CrisNAC

Poema 🐰

Carritos que viajan sin morir,
por usuario y tienda a florecer,
CHECKED_OUT de antaño, ABANDONED volver,
esquemas OpenAPI brindando luz,
múltiples estados, sin conflicto en la cruz. 🛒✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive El título es demasiado genérico y no describe específicamente los cambios del PR; usa "Inicio de trabajo" que no comunica el contenido real de la implementación. Cambiar el título a algo más descriptivo como "Allow multiple checked-out carts and add cart schemas for OpenAPI documentation" que refleje los cambios principales.
✅ Passed checks (4 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.
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
  • Commit unit tests in branch OM-536

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)
src/docs/schemas/users/cart.schema.js (1)

4-88: ⚡ Quick win

Endurecé el contrato de schema con required y additionalProperties: false.

Hoy cualquier payload parcial o con campos extra sigue “válido” a nivel spec. Agregar required en campos clave (id, quantity, product, items, message, success, etc.) mejora la precisión de la documentación y de clientes generados.

Ejemplo mínimo de ajuste
   CartItem: {
     type: "object",
+    required: ["id", "quantity", "product"],
+    additionalProperties: false,
     properties: {
@@
       product: {
         type: "object",
+        required: ["id", "name", "price", "originalPrice", "isOffer"],
+        additionalProperties: false,
         properties: {
@@
   GetCartsResponse: {
     type: "object",
+    required: ["carts"],
+    additionalProperties: false,
     properties: {
@@
   DeleteAllCartsResponse: {
     type: "object",
+    required: ["success", "message"],
+    additionalProperties: false,
     properties: {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/docs/schemas/users/cart.schema.js` around lines 4 - 88, Add strict
validation to the JSON schemas by adding "required" arrays and
"additionalProperties: false" for each object schema: e.g. in CartItem require
["id","quantity","product"] and set additionalProperties: false; in the nested
product object require ["id","name","price","originalPrice","isOffer"] (and
optionally "offerPrice","imageUrl" if required) and set additionalProperties:
false; in CartCommerceInfo require ["id","name"] and additionalProperties:
false; in Cart require ["id","storeId","commerce","status","items"] and
additionalProperties: false; in GetCartsResponse require ["carts"] and
additionalProperties: false; in DeleteCartResponse and DeleteAllCartsResponse
require ["success","message"] and additionalProperties: false; in
CartErrorResponse and CartValidationError require ["message"] and
additionalProperties: false; update the schemas named CartItem, Cart (and its
product), CartCommerceInfo, GetCartsResponse, DeleteCartResponse,
DeleteAllCartsResponse, CartErrorResponse, and CartValidationError accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/docs/schemas/users/cart.schema.js`:
- Line 3: Registrar cartSchemas en la configuración de Swagger: importa
cartSchemas desde el archivo de esquemas (ej., ../docs/schemas/index.js) en el
módulo de configuración de swagger (swagger.config.js) y añade ...cartSchemas
dentro de components.schemas para que las referencias como
`#/components/schemas/GetCartsResponse` resuelvan correctamente; asegúrate además
de que la exportación cartSchemas (símbolo cartSchemas) contiene las claves
esperadas (GetCartsResponse, etc.) y que la importación usada en
swagger.config.js coincide con ese nombre.

---

Nitpick comments:
In `@src/docs/schemas/users/cart.schema.js`:
- Around line 4-88: Add strict validation to the JSON schemas by adding
"required" arrays and "additionalProperties: false" for each object schema: e.g.
in CartItem require ["id","quantity","product"] and set additionalProperties:
false; in the nested product object require
["id","name","price","originalPrice","isOffer"] (and optionally
"offerPrice","imageUrl" if required) and set additionalProperties: false; in
CartCommerceInfo require ["id","name"] and additionalProperties: false; in Cart
require ["id","storeId","commerce","status","items"] and additionalProperties:
false; in GetCartsResponse require ["carts"] and additionalProperties: false; in
DeleteCartResponse and DeleteAllCartsResponse require ["success","message"] and
additionalProperties: false; in CartErrorResponse and CartValidationError
require ["message"] and additionalProperties: false; update the schemas named
CartItem, Cart (and its product), CartCommerceInfo, GetCartsResponse,
DeleteCartResponse, DeleteAllCartsResponse, CartErrorResponse, and
CartValidationError accordingly.
🪄 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: f100ead3-8ed5-4352-b6e3-ab5090646908

📥 Commits

Reviewing files that changed from the base of the PR and between 32a4a8f and 699f432.

📒 Files selected for processing (1)
  • src/docs/schemas/users/cart.schema.js

Comment thread src/docs/schemas/users/cart.schema.js

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/modules/users/cart/cart.service.js`:
- Around line 15-24: El servicio getOrCreateActiveCart ahora usa
tx.carts.findFirst y tx.carts.create pero los tests/mocks aún exponen solo
upsert; actualizá los doubles para implementar ambos métodos (tx.carts.findFirst
y tx.carts.create) en los mocks unitarios de carrito y en los mocks e2e
relacionados con stock, devolviendo el comportamiento esperado cuando findFirst
no encuentra carrito y create crea uno nuevo; reemplazá o complementá cualquier
uso de upsert en los mocks por estas nuevas funciones para que las pruebas
cubran el flujo de creación.
- Around line 15-31: The getOrCreateActiveCart flow is not idempotent and
mismatches unit-test mocks: replace the findFirst/create sequence inside the
transaction with a single atomic tx.carts.upsert call in getOrCreateActiveCart
(use the unique key { fk_user, fk_store, cart_status: "ACTIVE" } as the upsert
selector and set/create the desired fields), and update tests to mock
tx.carts.upsert instead of tx.carts.findFirst/create so prisma.$transaction
mocks match the service implementation and avoid P2002 race conditions and
TypeError: tx.carts.findFirst is not a function.

In `@src/modules/users/orders/order.service.js`:
- Around line 394-401: The raw UPDATE in order.service.js (tx.$executeRaw
updating "Carts" setting "cart_status" = 'ABANDONED' for CHECKED_OUT carts)
wrongly flips carts that are already linked to Orders via Orders.fk_cart (which
is `@unique/1`:1); remove this tx.$executeRaw block entirely or alter its WHERE to
exclude carts referenced by Orders (e.g., skip carts where an Order exists with
fk_cart = Carts.id) so you do not mark carts that have produced confirmed Orders
as ABANDONED.
🪄 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: f4a5250c-bc1d-4e8a-a56b-3de09ac8e80f

📥 Commits

Reviewing files that changed from the base of the PR and between 699f432 and be847d0.

📒 Files selected for processing (4)
  • prisma/migrations/20260528123758_allow_multiple_checked_out_carts/migration.sql
  • prisma/schema.prisma
  • src/modules/users/cart/cart.service.js
  • src/modules/users/orders/order.service.js

Comment thread src/modules/users/cart/cart.service.js Outdated
Comment thread src/modules/users/cart/cart.service.js Outdated
Comment on lines +394 to +401
// Marcar todos los carritos CHECKED_OUT anteriores como ABANDONED usando raw SQL
await tx.$executeRaw`
UPDATE "Carts"
SET "cart_status" = 'ABANDONED'
WHERE "fk_user" = ${resolvedUserId}
AND "fk_store" = ${cart.fk_store}
AND "cart_status" = 'CHECKED_OUT'
`;

@coderabbitai coderabbitai Bot May 28, 2026 •

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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and print the relevant region in the target file with line numbers
FILE="src/modules/users/orders/order.service.js"
if [ ! -f "$FILE" ]; then
  echo "File not found: $FILE" >&2
  exit 1
fi

# Print around the referenced lines
sed -n '360,430p' "$FILE" | nl -ba | sed -n '1,120p'

# Search for $executeRaw usage in the repo (to see tx type / ORM)
rg -n "\\$executeRaw" -S . || true

# Search for carts.update and cart_status transitions nearby
rg -n "cart_status" "$FILE" || true

# Find where tx is created/typed in this module (search for transaction usage)
rg -n "tx\\b|transaction|\\$transaction|prisma\\.\\$transaction" "$FILE" || true

Repository: CrisNAC/BackendMarketplace

Length of output: 114


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/modules/users/orders/order.service.js"
if [ ! -f "$FILE" ]; then
  echo "File not found: $FILE" >&2
  exit 1
fi

echo "== Código alrededor de líneas 360-430 =="
sed -n '360,430p' "$FILE" | nl -ba | sed -n '1,120p'

echo
echo "== Búsqueda de \"$executeRaw\" en el repo =="
rg -n "\\$executeRaw" -S . || true

echo
echo "== Búsqueda de \"cart_status\" en el archivo =="
rg -n "cart_status" "$FILE" || true

echo
echo "== Búsqueda de creación/uso de tx en el archivo =="
rg -n "tx\\b|\\$transaction|prisma\\.\\$transaction|transaction" "$FILE" || true

Repository: CrisNAC/BackendMarketplace

Length of output: 173


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/modules/users/orders/order.service.js"
if [ ! -f "$FILE" ]; then
  echo "File not found: $FILE" >&2
  exit 1
fi

echo "== Código alrededor de líneas 360-430 =="
sed -n '360,430p' "$FILE" | awk '{ printf "%d:%s\n", NR+359, $0 }'

echo
echo '== Búsqueda de "$executeRaw" en el repo =='
rg -n "\\$executeRaw" -S .

echo
echo '== Búsqueda de "cart_status" en el archivo =='
rg -n "cart_status" "$FILE"

echo
echo '== Búsqueda de creación/uso de tx en el archivo (prisma tx/transaction) =='
rg -n "\\btx\\b|\\$transaction|transaction|prisma\\." "$FILE" || true

echo
echo '== Búsqueda específica de tx.$executeRaw en el archivo =='
rg -n "tx\\s*\\.\\s*\\$executeRaw" "$FILE" || true

Repository: CrisNAC/BackendMarketplace

Length of output: 2567


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/modules/users/orders/order.service.js"
if [ ! -f "$FILE" ]; then
  echo "File not found: $FILE" >&2
  exit 1
fi

echo "== Código alrededor de líneas 360-410 =="
sed -n '380,410p' "$FILE" | awk '{ printf "%d:%s\n", NR+379, $0 }'

echo
echo '== Búsqueda de "$executeRaw" en el repo (literal) =='
rg -n '\$executeRaw' -S .

echo
echo
echo '== Búsqueda de "$executeRaw" en el archivo =='
rg -n '\$executeRaw' "$FILE" || true

echo
echo '== Búsqueda específica de "tx.$executeRaw" (literal aprox) =='
rg -n 'tx\s*\.\s*\$executeRaw' "$FILE" || true

echo
echo '== Búsqueda de creación/uso de tx (prisma transaction) en el archivo =='
rg -n '\btx\b|prisma\.\$transaction|\$transaction|transaction\(' "$FILE" || true

echo
echo '== Búsqueda de relación Orders->Carts (fk_cart / id_cart) en el repo =='
rg -n 'fk_cart|id_cart' -S src || true

echo
echo '== Búsqueda de referencia a tabla "Carts" en el repo =='
rg -n '"Carts"' -S src || true

Repository: CrisNAC/BackendMarketplace

Length of output: 5953


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Buscar versión de Prisma en package.json / lockfiles
ls -la package.json 2>/dev/null || true
rg -n "\"prisma\"|prisma-client|`@prisma/client`|prisma" package.json pnpm-lock.yaml package-lock.json yarn.lock 2>/dev/null || true

# 2) Buscar schema (Prisma schema.prisma) para relaciones Orders->Carts
SCHEMA_FILE="$(find . -maxdepth 4 -name 'schema.prisma' -print -quit)"
echo "== schema.prisma =="
echo "$SCHEMA_FILE"

if [ -n "${SCHEMA_FILE}" ]; then
  # Print Carts + Orders models sections
  rg -n "model (Carts|Orders|Order|Cart)" "$SCHEMA_FILE" || true
  # Show likely model definitions around those
  # Use awk to print ranges for matches
  for model in Carts Orders Order Cart; do
    if rg -n "model ${model}\\b" "$SCHEMA_FILE" >/dev/null 2>&1; then
      line=$(rg -n "model ${model}\\b" "$SCHEMA_FILE" | head -n1 | cut -d: -f1)
      start=$((line-5))
      if [ $start -lt 1 ]; then start=1; fi
      sed -n "${start},$((line+160))p" "$SCHEMA_FILE" | cat
      echo "----"
    fi
  done
fi

# 3) Buscar definición concreta de fk_cart / fk_order en el schema
if [ -n "${SCHEMA_FILE}" ]; then
  rg -n "fk_cart|id_cart|fk_order|id_order|Carts|Orders" "$SCHEMA_FILE" || true
fi

# 4) Buscar en el mismo order.service.js cómo se crea la order y qué fk_cart se setea
rg -n "fk_cart|id_cart:|cart_status|CHECKED_OUT|ABANDONED" src/modules/users/orders/order.service.js

# 5) Buscar en cart.service.js qué significa ABANDONED y cómo se manejan múltiples CHECKED_OUT
rg -n "ABANDONED|ABANDON|CHECKED_OUT|cart_status" src/modules/users/cart/cart.service.js

Repository: CrisNAC/BackendMarketplace

Length of output: 17757


No marcar ABANDONED carritos CHECKED_OUT que ya tienen pedido
El UPDATE en order.service.js cambia a ABANDONED todos los carritos CHECKED_OUT previos del mismo usuario/tienda, pero en el schema Orders.fk_cart es @unique y referencia 1:1 a Carts; por lo tanto carritos que ya originaron pedidos van a quedar “abandonados” aunque el pedido siga ligado a ese carrito, rompiendo la semántica histórica. Eliminar ese bloque evita esa alteración de estado cruzado entre checkout previos y pedidos confirmados.

🧰 Tools
🪛 GitHub Actions: Vitest + Supertest (Backend) / 0_test.txt

[error] 395-395: TypeError: tx.$executeRaw is not a function at order creation. Code tries to run raw SQL inside a Prisma transaction (tx.$executeRaw`... ).

🪛 GitHub Actions: Vitest + Supertest (Backend) / test

[error] 395-397: TypeError: tx.$executeRaw is not a function. Error occurs while updating previous carts to ABANDONED. Affects POST /api/orders and downstream E2E tests expecting 201 but receiving 500.

🪛 GitHub Check: test

[failure] 395-395: tests/unit/order/order.test.js > createOrderService > crea la orden correctamente con dirección válida
TypeError: tx.$executeRaw is not a function
❯ src/modules/users/orders/order.service.js:395:25

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/users/orders/order.service.js` around lines 394 - 401, The raw
UPDATE in order.service.js (tx.$executeRaw updating "Carts" setting
"cart_status" = 'ABANDONED' for CHECKED_OUT carts) wrongly flips carts that are
already linked to Orders via Orders.fk_cart (which is `@unique/1`:1); remove this
tx.$executeRaw block entirely or alter its WHERE to exclude carts referenced by
Orders (e.g., skip carts where an Order exists with fk_cart = Carts.id) so you
do not mark carts that have produced confirmed Orders as ABANDONED.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

El carrito transiciona CHECKED_OUT → ABANDONED después de confirmar la orden.
Esto marca históricamente que fue consumido y ya no está activo.

La relación Orders.fk_cart se mantiene íntegra: el pedido sigue referenciando
correctamente el carrito que lo originó. El estado ABANDONED no invalida el carrito,
solo indica que ya fue usado en una orden.

Sin este cambio, quedarían múltiples carritos CHECKED_OUT en la BD sin forma de
distinguir cuál fue el que generó la orden actual. Es un patrón de transición de
estado que preserva la auditoría y mantiene la consistencia de datos.

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.

@Benjakr04, el razonamiento de diseño es válido — el estado ABANDONED funciona como marca de auditoría histórica, y la relación Orders.fk_cart efectivamente se conserva intacta sin importar el cambio de estado del carrito. Me equivoqué en la parte semántica; la acepto.

Sin embargo, persiste el problema de implementación que reportan los tests de GitHub Actions: TypeError: tx.$executeRaw is not a function. Esto indica que el objeto tx dentro del callback de prisma.$transaction(async (tx) => …) no expone $executeRaw en el entorno de tests (por cómo se mockea). El comportamiento real puede variar según la versión de Prisma y el setup de mocks.

Una alternativa más limpia que lograría exactamente lo mismo sin raw SQL sería usar tx.carts.updateMany, que es type-safe y funciona correctamente dentro de transacciones interactivas de Prisma:

// Marcar todos los carritos CHECKED_OUT anteriores como ABANDONED
await tx.carts.updateMany({
  where: {
    fk_user: resolvedUserId,
    fk_store: cart.fk_store,
    cart_status: "CHECKED_OUT"
  },
  data: { cart_status: "ABANDONED" }
});

Esto resuelve el error de tests, elimina la dependencia de raw SQL, y mantiene el patrón de auditoría que describiste.

@leoAchu16

Copy link
Copy Markdown
Collaborator

hay sugerencias del conejo

@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 (1)
tests/unit/order/order.test.js (1)

530-537: ⚡ Quick win

Considerar validar los filtros aplicados en la transacción.

Los tests de getStoreOrdersService solo verifican que prisma.$transaction fue llamada, pero no validan que los filtros (order_status, múltiples estados, rango de fechas) se aplicaron correctamente en las cláusulas where del query.

Esto debilita ligeramente la cobertura: un bug en la construcción de filtros podría pasar desapercibido.

💡 Ejemplo de cómo validar los filtros

Podés inspeccionar los argumentos de la transacción array-form para verificar los filtros:

it("aplica filtro por order_status correctamente", async () => {
  prisma.stores.findFirst.mockResolvedValue({ id_store: 10 });
  prisma.$transaction.mockResolvedValue([[mockOrderFromDB], 1]);

  await getStoreOrdersService(1, 10, { order_status: "PENDING" });

  expect(prisma.$transaction).toHaveBeenCalled();
  const transactionArgs = prisma.$transaction.mock.calls[0][0];
  expect(transactionArgs).toHaveLength(2);
  // Verificar que el where incluye order_status: "PENDING"
  // Nota: esto requiere que los mocks de findMany/count registren sus argumentos
});

Also applies to: 539-546, 548-558

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/order/order.test.js` around lines 530 - 537, The test only asserts
prisma.$transaction was called but not that the query filters were built
correctly; update the tests for getStoreOrdersService to inspect
prisma.$transaction.mock.calls[0][0] (the array-form transaction queries) and
assert the relevant query arguments include the expected where clauses (e.g.,
that one of the queries passed to $transaction contains where.order_status:
"PENDING", handles multiple statuses array, and includes date range keys when
provided); ensure the mocks (prisma.$transaction, prisma.stores.findFirst) still
return the existing values but add assertions on the transactionArgs length and
the specific where properties to validate correct filter construction.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/order/order.test.js`:
- Around line 415-417: El test "calcula precio con oferta correctamente (usa
offer_price)" actualmente solo verifica que prisma.$transaction fue llamado;
extendé la aserción para inspeccionar la llamada a createMany dentro de la
transacción y asegurar que los items usan offer_price (80) en lugar de price
(100). Localizá la llamada a createOrderService(1, { ... }), mockeá/prendo la
invocación de prisma.$transaction y extraé los argumentos pasados a createMany
(referirse a createMany en el mock de prisma), luego añadí expect sobre los
datos para comprobar que el campo usado para el precio sea 80 (offer_price) en
los elementos creados. Asegurate de mantener la verificación de
prisma.$transaction además de la nueva aserción.
- Around line 371-383: El bloque que vuelve a mockear prisma.$transaction es
redundante y debe eliminarse; en su lugar usa el mockTx ya definido y añade una
aserción sobre mockTx.orderItems.createMany para verificar que fue llamado con
los items cuyo quantity y price producen el subtotal esperado (p. ej. quantity 3
y price 100 => subtotal 300). Localiza los símbolos mockTx, prisma.$transaction
y mockTx.orderItems.createMany y reemplaza la verificación existente
expect(prisma.$transaction).toHaveBeenCalled() por una aserción que inspeccione
los argumentos pasados a mockTx.orderItems.createMany (o el mock asociado) para
validar los valores calculados del item.

---

Nitpick comments:
In `@tests/unit/order/order.test.js`:
- Around line 530-537: The test only asserts prisma.$transaction was called but
not that the query filters were built correctly; update the tests for
getStoreOrdersService to inspect prisma.$transaction.mock.calls[0][0] (the
array-form transaction queries) and assert the relevant query arguments include
the expected where clauses (e.g., that one of the queries passed to $transaction
contains where.order_status: "PENDING", handles multiple statuses array, and
includes date range keys when provided); ensure the mocks (prisma.$transaction,
prisma.stores.findFirst) still return the existing values but add assertions on
the transactionArgs length and the specific where properties to validate correct
filter construction.
🪄 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: d9efd221-edd4-483f-a2b3-4838b15ac1d9

📥 Commits

Reviewing files that changed from the base of the PR and between be847d0 and 805ce3d.

📒 Files selected for processing (5)
  • src/config/swagger.config.js
  • src/modules/users/cart/cart.service.js
  • src/modules/users/orders/order.service.js
  • tests/unit/cart/cart.test.js
  • tests/unit/order/order.test.js
✅ Files skipped from review due to trivial changes (3)
  • src/config/swagger.config.js
  • src/modules/users/cart/cart.service.js
  • tests/unit/cart/cart.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/modules/users/orders/order.service.js

Comment thread tests/unit/order/order.test.js Outdated
Comment thread tests/unit/order/order.test.js Outdated
@sonarqubecloud

Copy link
Copy Markdown

@CrisNAC
CrisNAC merged commit 7511828 into dev May 28, 2026
3 of 4 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.

3 participants