Carrusel de Ofertas - bootcamp-uchile-2026/grupo-2-backend GitHub Wiki
Carrusel de Ofertas
La funcionalidad Carrusel de Ofertas permite que la página de inicio de BuenOrigen presente productos que actualmente poseen un precio de oferta.
Desde la perspectiva Backend, esta funcionalidad consiste en identificar los productos que poseen un precioOferta, calcular la información relacionada con el descuento y devolver los datos necesarios para que Frontend y Mobile puedan representarlos.
La construcción visual del carrusel, su navegación, animaciones y comportamiento corresponden a Frontend y Mobile.
Objetivo
Proporcionar a Frontend y Mobile la información necesaria para mostrar productos en oferta en la página de inicio de BuenOrigen.
Estado
Implementado
La funcionalidad se encuentra implementada actualmente mediante:
ProductosModule
|
v
ProductosController
|
v
ProductosService
|
v
ProductoOfertaDto[]
Responsabilidad Backend
Actualmente el Backend debe:
- Consultar los productos disponibles en el catálogo.
- Identificar los productos que poseen un
precioOferta. - Obtener el precio original del producto.
- Obtener el precio con descuento.
- Calcular el porcentaje de descuento.
- Transformar cada producto al contrato
ProductoOfertaDto. - Retornar una lista con los productos en oferta.
- Retornar una lista vacía si no existen productos en oferta.
Contrato de API
Endpoint
GET /productos/ofertas
Página relacionada:
Datos de entrada
La operación no requiere:
Body
Parámetros de ruta
Query Parameters
DTO de salida
ProductoOfertaDto[]
La definición general del endpoint se encuentra centralizada en:
La estructura completa del DTO se encuentra en:
Criterio Actual para Determinar una Oferta
Actualmente un producto es considerado en oferta cuando:
producto.precioOferta !== null
Conceptualmente:
Producto
|
v
¿precioOferta !== null?
|
+---+---+
| |
Sí No
| |
v v
Oferta No se incluye
Por ejemplo:
{
precio: 12990,
precioOferta: 9990
}
corresponde a un producto en oferta.
Mientras que:
{
precio: 12990,
precioOferta: null
}
no será incluido en la respuesta del endpoint.
Flujo de la Operación
Conceptualmente:
GET /productos/ofertas
|
v
ProductosController
|
v
ProductosService
|
| filter()
v
precioOferta !== null
|
| map()
v
Calcular información
de descuento
|
v
ProductoOfertaDto[]
|
v
200 OK
Procesamiento en ProductosService
La operación principal corresponde a:
obtenerProductosEnOferta(): ProductoOfertaDto[]
Primero se seleccionan los productos cuyo precioOferta no sea null.
Conceptualmente:
const productosEnOferta = this.productos.filter(
(producto) => producto.precioOferta !== null,
);
Posteriormente, cada producto se transforma a:
ProductoOfertaDto
Cálculo del Porcentaje de Descuento
El porcentaje de descuento se calcula utilizando:
precioOriginal
precioDescuento
Conceptualmente:
(precioOriginal - precioDescuento)
---------------------------------- × 100
precioOriginal
El resultado se redondea al número entero más cercano.
En la implementación se utiliza:
Math.round(
((producto.precio - precioOferta) / producto.precio) * 100,
)
Ejemplo
Si un producto posee:
Precio original: $12.990
Precio de oferta: $9.990
la diferencia corresponde a:
12.990 - 9.990 = 3.000
Luego:
3.000
------ × 100 ≈ 23,09 %
12.990
Al aplicar:
Math.round()
el resultado será:
23 %
Por lo tanto, el DTO devolverá:
{
"precioOriginal": 12990,
"precioDescuento": 9990,
"descuentoPorcentaje": 23
}
DTO de Salida
La operación utiliza:
ProductoOfertaDto
con la siguiente estructura:
export class ProductoOfertaDto {
id: number;
marca: string;
nombre: string;
precioOriginal: number;
precioDescuento: number;
descuentoPorcentaje: number;
imagenUrl: string;
}
El endpoint no devuelve directamente el modelo completo Producto.
Conceptualmente:
Producto
|
| seleccionar y transformar datos
v
ProductoOfertaDto
|
v
Frontend / Mobile
Ejemplo de Solicitud
GET /productos/ofertas
Ejemplo de Respuesta
[
{
"id": 1,
"marca": "EcoWear",
"nombre": "Polera de algodón",
"precioOriginal": 12990,
"precioDescuento": 9990,
"descuentoPorcentaje": 23,
"imagenUrl": "https://ejemplo.cl/imagenes/productos/polera.jpg"
}
]
Respuesta HTTP:
200 OK
Resultado sin Productos en Oferta
Si ningún producto posee:
precioOferta !== null
el Backend devuelve:
[]
Esto corresponde a una respuesta válida y no a un error.
La respuesta HTTP continúa siendo:
200 OK
Conceptualmente:
Productos
|
v
¿Existen productos con precioOferta?
|
+--+--+
| |
Sí No
| |
v v
DTO[] []
\ /
\ /
v v
200 OK
Reglas de Negocio Actuales
Actualmente las reglas implementadas son:
- El producto debe poseer un
precioOfertadistinto denull. preciocorresponde al precio original.precioOfertacorresponde al precio con descuento.- El porcentaje de descuento es calculado por el Backend.
- El porcentaje se redondea al entero más cercano.
Vigencia de las Ofertas
Actualmente el modelo y la lógica implementada no utilizan fechas de inicio o término de una oferta.
Por lo tanto, en la implementación actual:
precioOferta !== null
|
v
Producto en oferta
No se comprueba todavía:
fechaInicioOferta
fechaTerminoOferta
estadoOferta
Por esta razón, el concepto de "oferta vigente" corresponde actualmente a la existencia de un precioOferta.
Posibles Mejoras Futuras
Si posteriormente las reglas de negocio necesitan controlar temporalmente las ofertas, podrán incorporarse propiedades como:
fechaInicioOferta: Date;
fechaTerminoOferta: Date;
Entonces la lógica podría evolucionar conceptualmente hacia:
precioOferta existe
+
fecha actual >= fechaInicioOferta
+
fecha actual <= fechaTerminoOferta
|
v
Oferta vigente
También podrán evaluarse reglas adicionales como:
- Estado de publicación del producto.
- Stock disponible.
- Estado activo de la oferta.
- Cantidad máxima de productos del carrusel.
- Priorización de determinadas ofertas.
Estas reglas deberán incorporarse únicamente cuando sean requeridas por BuenOrigen.
Documentación Swagger
El endpoint se encuentra documentado en Swagger mediante:
@ApiOperation()
@ApiOkResponse()
La respuesta exitosa se encuentra documentada como:
ProductoOfertaDto[]
Conceptualmente:
@ApiOperation()
|
v
Describe la operación
@ApiOkResponse()
|
v
Documenta 200 OK
|
v
ProductoOfertaDto[]
Para mayor información consultar:
Relación con la Página de Inicio
La funcionalidad puede representarse de la siguiente forma:
Página de Inicio
|
v
Carrusel de Ofertas
|
v
GET /productos/ofertas
|
v
ProductosController
|
v
ProductosService
|
v
ProductoOfertaDto[]
|
v
Frontend / Mobile
Relación con la Arquitectura
La funcionalidad pertenece al dominio:
Productos
y utiliza:
ProductosModule
|
v
ProductosController
|
v
ProductosService
|
v
ProductoOfertaDto[]
Páginas relacionadas: