Repository navigation
Conversation
|
Warning Review limit reached
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 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 configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughResumen ejecutivoSe 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. CambiosModelo de carrito, restricción parcial y flujo de checkout
🎯 3 (Moderado) | ⏱️ ~25 minutos PRs posiblemente relacionados
Revisores sugeridos
Poema 🐰
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/docs/schemas/users/cart.schema.js (1)
4-88: ⚡ Quick winEndurecé el contrato de schema con
requiredyadditionalProperties: false.Hoy cualquier payload parcial o con campos extra sigue “válido” a nivel spec. Agregar
requireden 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
📒 Files selected for processing (1)
src/docs/schemas/users/cart.schema.js
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
prisma/migrations/20260528123758_allow_multiple_checked_out_carts/migration.sqlprisma/schema.prismasrc/modules/users/cart/cart.service.jssrc/modules/users/orders/order.service.js
| // 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' | ||
| `; |
There was a problem hiding this comment.
🧩 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" || trueRepository: 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" || trueRepository: 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" || trueRepository: 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 || trueRepository: 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.jsRepository: 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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.
|
hay sugerencias del conejo |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/unit/order/order.test.js (1)
530-537: ⚡ Quick winConsiderar validar los filtros aplicados en la transacción.
Los tests de
getStoreOrdersServicesolo verifican queprisma.$transactionfue llamada, pero no validan que los filtros (order_status, múltiples estados, rango de fechas) se aplicaron correctamente en las cláusulaswheredel 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
📒 Files selected for processing (5)
src/config/swagger.config.jssrc/modules/users/cart/cart.service.jssrc/modules/users/orders/order.service.jstests/unit/cart/cart.test.jstests/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
|



Summary by CodeRabbit
Notas de Versión
Nuevas Características
Documentación
Tests