El descuento del POS (apps/web/src/app/pos/page.tsx:460) acepta cualquier valor mayor o igual a 0, sin límite ni autorización. Si supera el subtotal, el total queda en $0 pero el carrito guarda el descuento completo. El API tampoco lo valida.
Entorno
local
Módulos
Punto de venta (POS), Web / frontend, API / backend, Reportes
Severidad
Molesta; hay workaround
Pasos para reproducir
Como cajero, agregar al carrito un producto de $100.
Escribir un descuento de $500.
Cobrar.
Revisar el shop_cart creado.
Esperado
El descuento no puede superar el subtotal.
Por encima de un límite definido (porcentaje o monto), el descuento requiere autorización de un administrador.
Actual
La venta se cobra en $0 y el carrito queda con totalPrice = 0.00 y discount = 500.00. Cualquier cajero puede regalar una venta completa sin dejar rastro de quién lo autorizó.
Evidencia
Encontrado en auditoría de código; no reproducido en ejecución.
// pos/page.tsx
onChange={(e)=> setDiscount(Math.max(0, Number(e.target.value)))} // sin tope
const total= Math.max(0, subtotal - discount); // total en 0, discount sin recortar
Arreglo sugerido: limitar el descuento a subtotal en el POS y validar en el servidor; definir con el negocio el tope sin autorización. Workaround: revisar en reportes las ventas con descuento.
¿Está también en producción?
Sí — este issue no basta; hay que abrir un Incidente / hotfix
No — solo local / staging
No sé
Antes de abrir
Busqué un issue duplicado
### Qué pasa
El descuento del POS (`apps/web/src/app/pos/page.tsx:460`) acepta cualquier valor mayor o igual a 0, sin límite ni autorización. Si supera el subtotal, el total queda en $0 pero el carrito guarda el descuento completo. El API tampoco lo valida.
### Entorno
local
### Módulos
Punto de venta (POS), Web / frontend, API / backend, Reportes
### Severidad
Molesta; hay workaround
### Pasos para reproducir
1. Como cajero, agregar al carrito un producto de $100.
2. Escribir un descuento de $500.
3. Cobrar.
4. Revisar el `shop_cart` creado.
### Esperado
- El descuento no puede superar el subtotal.
- Por encima de un límite definido (porcentaje o monto), el descuento requiere autorización de un administrador.
### Actual
La venta se cobra en $0 y el carrito queda con `totalPrice = 0.00` y `discount = 500.00`. Cualquier cajero puede regalar una venta completa sin dejar rastro de quién lo autorizó.
### Evidencia
```shell
Encontrado en auditoría de código; no reproducido en ejecución.
// pos/page.tsx
onChange={(e) => setDiscount(Math.max(0, Number(e.target.value)))} // sin tope
const total = Math.max(0, subtotal - discount); // total en 0, discount sin recortar
```
Arreglo sugerido: limitar el descuento a `subtotal` en el POS y validar en el servidor; definir con el negocio el tope sin autorización. Workaround: revisar en reportes las ventas con descuento.
### ¿Está también en producción?
- [ ] Sí — este issue no basta; hay que abrir un Incidente / hotfix
- [ ] No — solo local / staging
- [x] No sé
### Antes de abrir
- [x] Busqué un issue duplicado
Jose
was assigned by Carlos2026-10-02 20:04:15 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Qué pasa
El descuento del POS (
apps/web/src/app/pos/page.tsx:460) acepta cualquier valor mayor o igual a 0, sin límite ni autorización. Si supera el subtotal, el total queda en $0 pero el carrito guarda el descuento completo. El API tampoco lo valida.Entorno
local
Módulos
Punto de venta (POS), Web / frontend, API / backend, Reportes
Severidad
Molesta; hay workaround
Pasos para reproducir
shop_cartcreado.Esperado
Actual
La venta se cobra en $0 y el carrito queda con
totalPrice = 0.00ydiscount = 500.00. Cualquier cajero puede regalar una venta completa sin dejar rastro de quién lo autorizó.Evidencia
Arreglo sugerido: limitar el descuento a
subtotalen el POS y validar en el servidor; definir con el negocio el tope sin autorización. Workaround: revisar en reportes las ventas con descuento.¿Está también en producción?
Antes de abrir