Detalle de Producto - bootcamp-uchile-2026/grupo-2-backend GitHub Wiki

Detalle de Producto

La funcionalidad Detalle de Producto permite que un usuario de BuenOrigen consulte información ampliada de un producto seleccionado desde el catálogo, la página de inicio, favoritos u otras secciones de la aplicación.

Desde la perspectiva Backend, esta funcionalidad consiste en recibir el identificador de un producto, verificar que exista y devolver la información necesaria para construir su vista de detalle.

La presentación visual, selección de opciones y demás interacciones corresponden a Frontend y Mobile.


Objetivo

Permitir que Frontend y Mobile consulten la información detallada de un producto específico.


Estado

Implementado

La funcionalidad se encuentra implementada mediante:

ProductosModule
      |
      v
ProductosController
      |
      v
ProductosService
      |
      v
ProductoDetalleDto

Responsabilidad Backend

Actualmente el Backend debe:

  • Recibir el identificador del producto solicitado.
  • Transformar productoId a un número entero.
  • Verificar que el producto exista.
  • Consultar la información asociada al producto.
  • Seleccionar los datos necesarios para representar su detalle.
  • Incluir colores y tallas cuando existan.
  • Transformar la información a ProductoDetalleDto.
  • Responder 404 Not Found cuando el producto no exista.
  • Evitar modificar el producto durante una operación de consulta.

Contrato de API

Endpoint

GET /productos/:productoId

Ejemplo:

GET /productos/25

Parámetro de Ruta

productoId

Tipo esperado:

number

DTO de salida

ProductoDetalleDto

La definición general del endpoint se encuentra centralizada en:

Endpoints

La estructura completa del DTO se encuentra documentada en:

DTOs


Parámetro productoId

El Controller recibe el identificador utilizando:

@Param('productoId', ParseIntPipe) productoId: number

Los parámetros recibidos mediante HTTP llegan inicialmente como texto.

Por ejemplo:

GET /productos/25

entrega inicialmente:

"25"

ParseIntPipe transforma ese valor en:

25

antes de entregarlo al método del Controller.

Conceptualmente:

HTTP
"25"
 |
 v
ParseIntPipe
 |
 v
25
 |
 v
ProductosController

Validación mediante ParseIntPipe

Si el identificador posee un formato válido:

GET /productos/25

ParseIntPipe puede transformarlo correctamente a:

25

Sin embargo, una solicitud como:

GET /productos/abc

no contiene un identificador entero válido.

En ese caso NestJS responde:

400 Bad Request

antes de ejecutar la lógica de ProductosService.

Conceptualmente:

productoId
    |
    v
ParseIntPipe
    |
 +--+--+
 |     |
Sí     No
 |     |
 v     v
number 400 Bad Request
 |
 v
ProductosService

Búsqueda del Producto

Una vez recibido un identificador válido, ProductosService busca el producto correspondiente.

Conceptualmente:

Producto[]
    |
    | find()
    v
producto.id === productoId
    |
 +--+--+
 |     |
Sí     No
 |     |
 v     v
Producto  undefined

Si el producto no existe, el Service genera:

NotFoundException

y la API responde:

404 Not Found

Información del Producto

Actualmente el detalle expone:

Campo Tipo Descripción
id number Identificador único del producto
nombre string Nombre del producto
precio number Precio actual
descripcion string Descripción del producto
imagenes string[] Imágenes asociadas
colores string[] Colores disponibles cuando corresponda
tallas string[] Tallas disponibles cuando corresponda

Los campos:

colores
tallas

son opcionales.


ProductoDetalleDto

La respuesta utiliza:

export class ProductoDetalleDto {
  id: number;
  nombre: string;
  precio: number;
  descripcion: string;
  imagenes: string[];
  colores?: string[];
  tallas?: string[];
}

Por lo tanto:

Producto
   |
   | seleccionar datos necesarios
   v
ProductoDetalleDto
   |
   v
Frontend / Mobile

Modelo vs DTO

El modelo interno Producto contiene información adicional utilizada por otras funcionalidades.

Actualmente puede incluir datos como:

id
subcategoriaId
emprendedorId
marca
nombre
descripcion
precio
precioOferta
imagenUrl
imagenes
stock
puntuacion
ventasUltimoMes
fechaCreacion
colores
tallas

Sin embargo, el endpoint de detalle no devuelve directamente todo el modelo.

Utiliza:

ProductoDetalleDto

para seleccionar únicamente la información definida por su contrato.

Conceptualmente:

Modelo Producto
      |
      | contiene todos los datos
      v
ProductosService
      |
      | selecciona información
      v
ProductoDetalleDto
      |
      v
API

Colores y Tallas

Actualmente algunos productos pueden contener:

colores?: string[];
tallas?: string[];

Estas propiedades representan de manera simple las opciones disponibles.

Ejemplo:

{
  "colores": [
    "Negro",
    "Blanco"
  ],
  "tallas": [
    "S",
    "M",
    "L"
  ]
}

Si un producto no requiere estas características, las propiedades pueden no existir.


Variantes de Producto

Actualmente BuenOrigen no implementa un modelo complejo de variantes.

Por ejemplo, todavía no existe una estructura como:

Producto
   |
   +--> Variante Negro / S
   |       stock = 4
   |
   +--> Variante Negro / M
   |       stock = 7
   |
   +--> Variante Blanco / S
           stock = 2

Por ahora:

colores

y:

tallas

se representan como listas independientes.

Esta estructura podrá evolucionar posteriormente si el negocio necesita manejar stock, precio u otras propiedades por combinación de variante.


Cantidad

La cantidad seleccionada por el comprador no forma parte de ProductoDetalleDto.

Por ejemplo:

Cantidad = 2

corresponde a una decisión realizada por el usuario durante la interacción con Frontend o Mobile.

Conceptualmente:

Detalle del Producto
        |
        v
Usuario selecciona cantidad
        |
        v
Agregar al Carrito

La cantidad deberá ser enviada posteriormente a la funcionalidad del carrito.


Agregar al Carrito

Desde el detalle del producto, Frontend o Mobile podrá iniciar la operación de agregar el producto al carrito.

Esta funcionalidad pertenece a:

Carrito de Compras

El contrato actualmente identificado es:

POST /carrito/items

utilizando:

AgregarProductoCarritoDto

Sin embargo, la funcionalidad de Carrito se encuentra actualmente:

⬜ Pendiente de implementación

Por lo tanto, consultar:

GET /productos/:productoId

no modifica el carrito ni el inventario del producto.


Consulta sin Efectos Secundarios

El endpoint utiliza:

GET

por lo que su propósito es obtener información.

Consultar:

GET /productos/25

no debe:

reducir stock
agregar al carrito
crear pedidos
modificar el producto
registrar una compra

Conceptualmente:

GET Producto
     |
     v
Consultar
     |
     v
Retornar información

Flujo Completo de la Operación

GET /productos/25
        |
        v
  ParseIntPipe
        |
        v
 productoId: 25
        |
        v
ProductosController
        |
        v
 ProductosService
        |
        | find()
        v
¿Existe producto?
    |
 +--+--+
 |     |
Sí     No
 |     |
 v     v
Construir  NotFoundException
DTO            |
 |             v
 v         404 Not Found
ProductoDetalleDto
 |
 v
200 OK

Ejemplo de Solicitud

GET /productos/25

Ejemplo de Respuesta

{
  "id": 25,
  "nombre": "Polera Sustentable",
  "precio": 18990,
  "descripcion": "Polera confeccionada con materiales de origen sustentable.",
  "imagenes": [
    "https://ejemplo.cl/imagenes/polera-1.jpg",
    "https://ejemplo.cl/imagenes/polera-2.jpg"
  ],
  "colores": [
    "Negro",
    "Blanco"
  ],
  "tallas": [
    "S",
    "M",
    "L"
  ]
}

Respuesta HTTP:

200 OK

Producto sin Colores o Tallas

Un producto puede no poseer alguna de estas propiedades opcionales.

Por ejemplo:

{
  "id": 30,
  "nombre": "Botella Reutilizable",
  "precio": 9990,
  "descripcion": "Botella reutilizable fabricada en acero inoxidable.",
  "imagenes": [
    "https://ejemplo.cl/imagenes/botella.jpg"
  ]
}

Esto continúa siendo compatible con:

ProductoDetalleDto

porque:

colores?: string[];
tallas?: string[];

son propiedades opcionales.


Manejo de Errores

Identificador inválido

Ejemplo:

GET /productos/abc

Respuesta:

400 Bad Request

Gestionado mediante:

ParseIntPipe

Producto inexistente

Ejemplo:

GET /productos/999

Si no existe un producto con ese identificador, el Backend responde:

404 Not Found

mediante:

NotFoundException

Respuestas HTTP

Código Situación
200 OK Producto obtenido correctamente
400 Bad Request productoId no corresponde a un entero válido
404 Not Found El producto solicitado no existe

Huella Verde

La información de sustentabilidad no forma parte directamente de:

ProductoDetalleDto

Se obtiene mediante:

GET /productos/:productoId/huella-verde

Ver:

Huella Verde del Producto


Valoraciones

Las valoraciones tampoco forman parte directamente del DTO principal del producto.

Se consultan mediante:

GET /productos/:productoId/valoraciones

Ver:

Valoraciones de Producto


Productos Relacionados

Los productos relacionados se obtienen mediante:

GET /productos/:productoId/relacionados

Ver:

Productos Relacionados


Separación de Contratos

Por lo tanto, el detalle completo que puede construir Frontend puede provenir de varias operaciones:

Página Detalle de Producto
          |
          +--> GET /productos/:productoId
          |          |
          |          v
          |   ProductoDetalleDto
          |
          +--> GET /productos/:productoId/huella-verde
          |          |
          |          v
          |   HuellaVerdeProductoDto
          |
          +--> GET /productos/:productoId/valoraciones
          |          |
          |          v
          |   ValoracionDetalleDto[]
          |
          +--> GET /productos/:productoId/relacionados
                     |
                     v
             ProductoRelacionadoDto[]

Esto permite mantener cada responsabilidad separada.


Reglas de Negocio Actuales

Actualmente las reglas implementadas pueden resumirse como:

1. productoId debe ser un entero válido.

2. El producto debe existir.

3. Si no existe:
      404 Not Found.

4. Si existe:
      construir ProductoDetalleDto.

5. colores y tallas pueden ser opcionales.

6. La consulta no modifica el producto.

Reglas que Actualmente no se Aplican

La implementación actual no verifica todavía:

estado habilitado
estado de publicación
stock disponible
stock por color
stock por talla
variantes
fecha de publicación

Por lo tanto, no corresponde afirmar actualmente que el endpoint filtra únicamente productos "habilitados".


Disponibilidad y Stock

Aunque el modelo Producto posee:

stock: number;

el campo:

stock

no forma parte actualmente de:

ProductoDetalleDto

y la operación de detalle no realiza todavía reglas complejas de disponibilidad.

La forma definitiva de representar disponibilidad deberá evaluarse posteriormente según las necesidades de compra de BuenOrigen.


Posibles Mejoras Futuras

Posteriormente podrán evaluarse:

  • Incorporar stock al contrato de detalle.
  • Incorporar estado activo o publicado.
  • Incorporar variantes de producto.
  • Manejar stock por combinación de color y talla.
  • Incorporar precio por variante.
  • Incorporar disponibilidad.
  • Incorporar información del emprendedor.
  • Incorporar información resumida de la subcategoría.

Estas mejoras deberán implementarse únicamente cuando sean requeridas por las reglas de negocio.


Documentación Swagger

El endpoint se encuentra documentado mediante decoradores de @nestjs/swagger.

Entre ellos:

@ApiOperation()
@ApiParam()
@ApiOkResponse()
@ApiNotFoundResponse()

El parámetro:

productoId

se documenta como:

Number

y la respuesta exitosa utiliza:

ProductoDetalleDto

Para mayor información consultar:

OpenAPI y Swagger


Relación con otras Funcionalidades

Catálogo / Inicio / Favoritos
            |
            v
     Detalle de Producto
            |
            +---- Información principal
            |
            +---- Color / Talla
            |
            +---- [Huella Verde del Producto](/bootcamp-uchile-2026/grupo-2-backend/wiki/Huella-Verde-del-Producto)
            |
            +---- [Valoraciones de Producto](/bootcamp-uchile-2026/grupo-2-backend/wiki/Valoraciones-de-Producto)
            |
            +---- [Productos Relacionados](/bootcamp-uchile-2026/grupo-2-backend/wiki/Productos-Relacionados)
            |
            +---- [Carrito de Compras](/bootcamp-uchile-2026/grupo-2-backend/wiki/Carrito-de-Compras)

Relación con la Arquitectura

La funcionalidad pertenece al dominio:

Productos

y utiliza:

ProductosModule
      |
      v
ProductosController
      |
      v
ProductosService
      |
      v
ProductoDetalleDto

Páginas relacionadas: