fix big files - #162
Conversation
|
Warning Review limit reached
Next review available in: 7 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (34)
📝 WalkthroughWalkthroughSe separa la lógica del formulario de productos en tipos, helpers, hooks y componentes, con gestión de imágenes, traducciones, validación y cambios no guardados. Además, el carrito incorpora personalizaciones creadas transaccionalmente y nuevos flujos autenticados y de invitado. ChangesFormulario de productos
Personalizaciones del carrito
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (3 passed)
✨ 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: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
modules/customizations/application/create-customer-customization.ts (1)
63-90: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy liftPersiste el propietario de la personalización.
ownerUserIdse valida pero se descarta:CustomizationEntityy el repositorio no guardan ningún owner. Como el carrito también acepta IDs enviados por el cliente, no puede impedir que otro usuario reutilice y consulte una personalización conocida. Añade el propietario al modelo persistido y valida su pertenencia al adjuntarla.🤖 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 `@modules/customizations/application/create-customer-customization.ts` around lines 63 - 90, Actualiza execute en el flujo de CreateCustomerCustomization para conservar ownerUserId en la CustomizationEntity antes de llamar a repo.save. Extiende el modelo y repositorio para persistir ese propietario, y en el flujo que adjunta o consulta personalizaciones valida que el owner coincida con el usuario actual antes de aceptarla.
🤖 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 `@app/`[locale]/seller/products/product-form-image-helpers.ts:
- Around line 43-48: En la construcción del payload de imagen, usa siempre el
argumento normalizado purpose para el campo purpose, ignorando seed.purpose.
Actualiza la asignación dentro del helper que contiene id, url y mimeType para
garantizar que el propósito coincida con el bucket.
In `@app/`[locale]/seller/products/product-form-payload.ts:
- Around line 13-20: Move the description-to-text_photo mode inference out of
the payload adapter and into the domain logic that owns customization
configuration, reusing that domain behavior wherever configurations are created
or normalized. Update the payload construction around effectiveMode and
customizationConfig to consume the domain-resolved mode without applying
business rules locally.
- Around line 88-96: Garantiza que todos los errores de Zod tengan un destino
visible: actualiza mapErrors en
app/[locale]/seller/products/product-form-payload.ts (88-96) para conservar solo
claves renderizadas y dirigir rutas desconocidas como translation/translations a
un error general; añade ese campo al tipo FormErrors en
app/[locale]/seller/products/product-form-types.ts (77-83); y muestra el error
general y errors.customizationConfig en
app/[locale]/seller/products/product-form-view.tsx (79-98).
In `@app/`[locale]/seller/products/product-form-translation-helpers.ts:
- Around line 85-94: Update hasInactiveTranslationContent in
app/[locale]/seller/products/product-form-translation-helpers.ts (lines 85-94)
to count photo-label content only when at least one label value remains
non-empty after trim(), rather than counting all keys. Apply the same
non-empty-value check in app/[locale]/seller/products/product-form-payload.ts
(lines 38-45) before including a translation in the payload; preserve the
existing checks for other translation fields.
In `@app/`[locale]/seller/products/product-form-types.ts:
- Around line 43-46: Convierte ProductFormProps en una unión discriminada: exige
productId: string cuando mode sea 'edit' y prohíbe productId en 'create'. En
app/[locale]/seller/products/product-form-types.ts, actualiza el contrato; en
app/[locale]/seller/products/use-product-form-submission.ts, construye el
endpoint solo con un ID validado o rechaza explícitamente la edición sin
productId.
In `@app/`[locale]/seller/products/use-product-form-photos.ts:
- Around line 37-45: Update the upload flow in the product photo form to handle
partial failures instead of relying on Promise.all. Use Promise.allSettled
around the uploadProductPhoto calls, retain successful uploads in the form, and
report or compensate for rejected uploads so completed files are not orphaned in
storage.
In `@app/`[locale]/seller/products/use-product-form.ts:
- Around line 96-104: Actualiza initialFormSnapshot para construirlo usando
exactamente el mismo estado inicial ya normalizado por el formulario,
especialmente las imágenes con IDs estables y las etiquetas limpiadas en el
flujo de inicialización. Reutiliza ese estado o sus valores resultantes en lugar
de volver a llamar normalizeInitialImages y buildTranslationMap con datos sin
limpiar, manteniendo el snapshot idéntico al estado inicial en modo edición.
In `@modules/cart/application/update-cart-item.ts`:
- Around line 57-80: Validate customizationIdList before persisting it in the
update-cart flow: inject and use CustomizationLookupPort to reject empty or
invalid IDs, deduplicate the list, and verify every customization belongs to
item.productId. Apply the same validation to IDs supplied directly and to those
produced by customizationCreator, then persist only the validated deduplicated
list in updatedItem.
In `@modules/cart/domain/customer-customization-create-port.ts`:
- Around line 15-20: Haz obligatorio un contexto transaccional válido para toda
creación de personalización desde el carrito. En
modules/cart/domain/customer-customization-create-port.ts:15-20, exige tx en
CustomerCustomizationCreatePort.create; en
modules/cart/application/add-item-to-cart.ts:56-62 y
modules/cart/application/update-cart-item.ts:39-47, rechaza configuraciones con
creador pero sin runner; y en
modules/cart/application/add-item-to-cart.ts:133-148 y
modules/cart/application/update-cart-item.ts:58-66, valida y propaga tx antes de
invocar la creación, sin permitir persistencia fuera de la transacción.
In `@modules/cart/presentation/components/add-to-cart-button-view.tsx`:
- Around line 156-170: Ensure the button rendered in the productInCart,
hasCustomization, and isAuthenticated branch always has a label: either require
props.labels.addAnotherPersonalization in the render condition or use an
existing localized fallback when it is absent. Keep the existing button behavior
unchanged when the label is available.
- Around line 37-98: Actualiza QuantityControls para aplicar una condición común
de deshabilitado basada en props.disabled || savingDesign || state === 'adding'
a los controles de cantidad, guardar y eliminar. Reemplaza las condiciones
individuales de los botones onDecrement, onIncrement, onSaveDesign y onRemove,
manteniendo sus etiquetas y acciones sin cambios.
In `@modules/cart/presentation/components/cart-item-matching.ts`:
- Around line 23-45: Incluye designPosition en la identidad de matching:
actualiza isCustomizationMatching y CustomizationFields para compararlo de forma
estable junto con los demás campos. En
modules/cart/presentation/components/cart-api.ts:7-12, añádelo a la respuesta y
al tipo del carrito autenticado; en
modules/cart/presentation/components/use-add-to-cart-button.ts:43-50, proyecta
customizationDesignPosition al matching invitado.
In `@modules/cart/presentation/components/use-add-to-cart-button.ts`:
- Around line 38-42: Actualiza el cálculo de guestMatch en useAddToCartButton
para priorizar editCartItemId al identificar el item invitado que se está
editando, en lugar de depender únicamente de los campos mutables del borrador.
Mantén el matching actual como alternativa cuando no exista editCartItemId,
asegurando que saveDesign continúe actualizando el mismo item durante las
modificaciones.
In `@modules/cart/presentation/components/use-authenticated-cart-actions.ts`:
- Around line 49-53: Actualiza las ramas catch de las operaciones de cantidad y
eliminación en useAuthenticatedCartActions para invocar onFailure después de
restaurar el estado optimista con setCartItemInfo(previous). Mantén el rollback
existente y asegúrate de notificar ambos fallos mediante el callback recibido
por el hook.
- Around line 35-53: Actualiza updateQuantity para evitar que una respuesta
antigua revierta el estado de una mutación posterior: serializa las solicitudes
o identifica la operación más reciente y solo permite que esa operación ejecute
setCartItemInfo(previous) tras un fallo. Conserva la actualización optimista y
dispatchCartUpdated para la operación válida.
In `@modules/cart/presentation/components/use-authenticated-cart.ts`:
- Around line 23-63: The useEffect currently reloads the cart whenever the draft
customization changes because updateCart depends on customization. Keep fetched
cart items in state, load them only when authentication changes, and derive the
matching cart item and productInCart locally from those stored items when
customization, productId, or editCartItemId changes. Reset cartItemInfo and
productInCart when the session, product, or edited item changes, while
preserving cancellation and refresh behavior.
In `@tests/unit/modules/cart/application/add-item-to-cart.test.ts`:
- Around line 25-47: The rollback tests do not prove that customization creation
was attempted before the transaction rolled back. In
tests/unit/modules/cart/application/add-item-to-cart.test.ts:25-47 and
tests/unit/modules/cart/application/update-cart-item.test.ts:25-47, update
TransactionalCustomizationCreator to record every create call; in
tests/unit/modules/cart/application/add-item-to-cart.test.ts:145-168 and
tests/unit/modules/cart/application/update-cart-item.test.ts:142-169, assert
that the recorded input includes the “Atomic design” draft while committed
customizations remain absent.
---
Outside diff comments:
In `@modules/customizations/application/create-customer-customization.ts`:
- Around line 63-90: Actualiza execute en el flujo de
CreateCustomerCustomization para conservar ownerUserId en la CustomizationEntity
antes de llamar a repo.save. Extiende el modelo y repositorio para persistir ese
propietario, y en el flujo que adjunta o consulta personalizaciones valida que
el owner coincida con el usuario actual antes de aceptarla.
🪄 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 Plus
Run ID: 62bda8b2-fbea-4abf-8e05-bf90f7f27310
📒 Files selected for processing (36)
app/[locale]/seller/products/product-form-image-helpers.tsapp/[locale]/seller/products/product-form-payload.tsapp/[locale]/seller/products/product-form-photo-galleries.tsxapp/[locale]/seller/products/product-form-translation-helpers.tsapp/[locale]/seller/products/product-form-types.tsapp/[locale]/seller/products/product-form-upload.tsapp/[locale]/seller/products/product-form-view.tsxapp/[locale]/seller/products/product-form.tsxapp/[locale]/seller/products/use-product-form-fields.tsapp/[locale]/seller/products/use-product-form-photos.tsapp/[locale]/seller/products/use-product-form-submission.tsapp/[locale]/seller/products/use-product-form.tsapp/api/cart/items/[itemId]/route.tsapp/api/cart/items/route.tscomposition-root/container.tsmodules/cart/application/add-item-to-cart.tsmodules/cart/application/update-cart-item.tsmodules/cart/domain/customer-customization-create-port.tsmodules/cart/presentation/components/add-to-cart-button-view.tsxmodules/cart/presentation/components/add-to-cart-button.tsxmodules/cart/presentation/components/add-to-cart-types.tsmodules/cart/presentation/components/cart-api.tsmodules/cart/presentation/components/cart-item-matching.tsmodules/cart/presentation/components/use-add-to-cart-button.tsmodules/cart/presentation/components/use-authenticated-cart-actions.tsmodules/cart/presentation/components/use-authenticated-cart.tsmodules/cart/presentation/components/use-guest-cart-actions.tsmodules/cart/presentation/schemas/cart-schemas.tsmodules/customizations/application/create-customer-customization.tsmodules/customizations/domain/customization-repository.tsmodules/customizations/infrastructure/cart-customer-customization-creator.tsmodules/customizations/infrastructure/prisma-customization-repository.tstests/unit/app/[locale]/seller/products/product-form.test.tsxtests/unit/components/cart/add-to-cart-button.test.tsxtests/unit/modules/cart/application/add-item-to-cart.test.tstests/unit/modules/cart/application/update-cart-item.test.ts
| export function mapErrors(error: ZodError): FormErrors { | ||
| const errors: FormErrors = {}; | ||
| for (const issue of error.issues) { | ||
| const path = issue.path[0] as keyof FormErrors | undefined; | ||
| if (path !== undefined && !Object.hasOwn(errors, path)) { | ||
| errors[path] = issue.message; | ||
| } | ||
| } | ||
| return errors; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Garantiza un destino visible para todos los errores de Zod.
mapErrors fuerza cualquier primer segmento a FormErrors; rutas como translation o translations quedan en propiedades que la vista ignora. Además, customizationConfig sí está tipado, pero tampoco se renderiza.
app/[locale]/seller/products/product-form-payload.ts#L88-L96: mapea rutas desconocidas a un error general en lugar de crear claves invisibles.app/[locale]/seller/products/product-form-types.ts#L77-L83: añade un campo de error general o modela explícitamente las rutas anidadas.app/[locale]/seller/products/product-form-view.tsx#L79-L98: muestra el error general yerrors.customizationConfig.
📍 Affects 3 files
app/[locale]/seller/products/product-form-payload.ts#L88-L96(this comment)app/[locale]/seller/products/product-form-types.ts#L77-L83app/[locale]/seller/products/product-form-view.tsx#L79-L98
🤖 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 `@app/`[locale]/seller/products/product-form-payload.ts around lines 88 - 96,
Garantiza que todos los errores de Zod tengan un destino visible: actualiza
mapErrors en app/[locale]/seller/products/product-form-payload.ts (88-96) para
conservar solo claves renderizadas y dirigir rutas desconocidas como
translation/translations a un error general; añade ese campo al tipo FormErrors
en app/[locale]/seller/products/product-form-types.ts (77-83); y muestra el
error general y errors.customizationConfig en
app/[locale]/seller/products/product-form-view.tsx (79-98).
| function hasInactiveTranslationContent( | ||
| translation: LocaleTranslationState, | ||
| ): boolean { | ||
| return ( | ||
| translation.description.trim().length > 0 || | ||
| translation.tags.length > 0 || | ||
| translation.sizes.length > 0 || | ||
| (translation.designChangeDescription?.trim().length ?? 0) > 0 || | ||
| Object.keys(translation.photoLabels ?? {}).length > 0 | ||
| ); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
No trates etiquetas vacías como contenido de una traducción.
La subida personalizable crea entradas photoId: '' en todos los idiomas. Contar sus claves obliga a nombrar idiomas inactivos y serializa traducciones realmente vacías.
app/[locale]/seller/products/product-form-translation-helpers.ts#L85-L94: considera contenido únicamente las etiquetas cuyo valor no esté vacío trastrim().app/[locale]/seller/products/product-form-payload.ts#L38-L45: aplica la misma regla antes de incluir una traducción en el payload.
📍 Affects 2 files
app/[locale]/seller/products/product-form-translation-helpers.ts#L85-L94(this comment)app/[locale]/seller/products/product-form-payload.ts#L38-L45
🤖 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 `@app/`[locale]/seller/products/product-form-translation-helpers.ts around
lines 85 - 94, Update hasInactiveTranslationContent in
app/[locale]/seller/products/product-form-translation-helpers.ts (lines 85-94)
to count photo-label content only when at least one label value remains
non-empty after trim(), rather than counting all keys. Apply the same
non-empty-value check in app/[locale]/seller/products/product-form-payload.ts
(lines 38-45) before including a translation in the payload; preserve the
existing checks for other translation fields.
Summary by CodeRabbit
Nuevas funcionalidades
Correcciones