Favoritos - bootcamp-uchile-2026/grupo-2-backend GitHub Wiki
Favoritos
La funcionalidad Favoritos permitirá que un usuario de BuenOrigen guarde productos de su interés para consultarlos posteriormente.
Podrá utilizarse desde distintas secciones de la aplicación, como:
- Búsqueda de Productos.
- Página de Inicio.
- Detalle de Producto.
- Listados del catálogo.
- Página de Favoritos.
Desde la perspectiva Backend, esta funcionalidad consiste en mantener una relación entre un usuario y los productos que dicho usuario ha marcado como favoritos.
Objetivo
Permitir que Frontend y Mobile puedan:
- Consultar los productos favoritos del usuario.
- Agregar productos a favoritos.
- Eliminar productos de favoritos.
- Mantener una lista independiente para cada usuario.
Estado
Pendiente de implementación
Actualmente se encuentran definidos conceptualmente:
FavoritosModule
FavoritosService
Endpoints
ProductoFavoritoDto
Reglas iniciales de negocio
Sin embargo, todavía no se encuentran implementados:
FavoritosController
FavoritosService
Almacenamiento de favoritos
Relación Usuario - Producto
Identificación del usuario autenticado
Dominio
Favoritos
Módulo Propuesto
FavoritosModule
Service Propuesto
FavoritosService
Conceptualmente:
FavoritosModule
|
v
FavoritosController
|
v
FavoritosService
|
v
Favoritos del Usuario
Responsabilidad Backend
Cuando la funcionalidad sea implementada, el Backend deberá:
- Identificar al usuario que realiza la solicitud.
- Consultar los productos favoritos pertenecientes a ese usuario.
- Verificar que un producto exista antes de agregarlo.
- Evitar que un mismo producto sea agregado dos veces por el mismo usuario.
- Permitir eliminar un producto de favoritos.
- Impedir que un usuario modifique los favoritos de otro usuario.
- Mantener la relación entre Usuario y Producto.
- Entregar únicamente la información necesaria para representar los productos favoritos.
- Evitar modificar o eliminar el producto original del catálogo al eliminarlo de favoritos.
Contratos de API
Actualmente se han identificado tres operaciones principales.
Consultar Favoritos
Endpoint
GET /favoritos
Objetivo
Obtener los productos guardados como favoritos por el usuario autenticado.
DTO de salida
ProductoFavoritoDto[]
Página relacionada:
Conceptualmente:
GET /favoritos
|
v
Identificar usuario
|
v
Obtener favoritos
|
v
Consultar productos
|
v
ProductoFavoritoDto[]
Agregar Producto a Favoritos
Endpoint
POST /favoritos/:productoId
Ejemplo:
POST /favoritos/25
Parámetro de Ruta
productoId
Tipo esperado:
number
Objetivo
Agregar un producto determinado a la lista de favoritos del usuario autenticado.
Actualmente no se ha definido un DTO de entrada porque el producto puede identificarse directamente mediante:
productoId
incluido en la URL.
Conceptualmente:
POST /favoritos/25
|
v
Identificar usuario
|
v
¿Existe producto 25?
|
+---+---+
| |
Sí No
| |
v v
¿Ya está? Error
|
+--+--+
| |
No Sí
| |
v v
Agregar No duplicar
Eliminar Producto de Favoritos
Endpoint
DELETE /favoritos/:productoId
Ejemplo:
DELETE /favoritos/25
Parámetro de Ruta
productoId
Objetivo
Eliminar la relación entre el usuario autenticado y un producto determinado.
Esta operación no elimina el producto del catálogo.
Conceptualmente:
DELETE /favoritos/25
|
v
Favorito Usuario - Producto
|
v
Eliminar relación
y no:
DELETE Producto 25
Relación entre Usuario y Producto
Favoritos representa una relación entre dos dominios:
Usuario
y:
Producto
Conceptualmente:
Usuario
|
| guarda
v
Favorito
|
| referencia
v
Producto
Un usuario puede tener múltiples productos favoritos:
Usuario
|
+---- Producto 1
|
+---- Producto 7
|
+---- Producto 25
Al mismo tiempo, un producto puede encontrarse en los favoritos de distintos usuarios.
Por lo tanto, conceptualmente existe una relación:
Usuario N -------- N Producto
gestionada mediante Favoritos.
Representación Conceptual de la Relación
Una posible representación interna podría ser:
export class Favorito {
usuarioId: number;
productoId: number;
}
Por ejemplo:
usuarioId = 3
productoId = 25
significa:
El usuario 3
ha agregado
el producto 25
a sus favoritos
Esta estructura es conceptual y podrá ajustarse cuando se implemente el dominio Usuarios y la persistencia definitiva.
ProductoFavoritoDto
La consulta de favoritos utiliza actualmente el contrato definido:
ProductoFavoritoDto
con la estructura:
export class ProductoFavoritoDto {
id: number;
marca: string;
nombre: string;
precio: number;
imagenUrl: string;
}
La respuesta de:
GET /favoritos
será:
ProductoFavoritoDto[]
Ejemplo de Respuesta
[
{
"id": 25,
"marca": "EcoHome",
"nombre": "Bolsa Reutilizable de Algodón",
"precio": 5990,
"imagenUrl": "https://ejemplo.cl/imagenes/bolsa-algodon.jpg"
},
{
"id": 31,
"marca": "Naturaleza Viva",
"nombre": "Shampoo Sólido",
"precio": 6990,
"imagenUrl": "https://ejemplo.cl/imagenes/shampoo-solido.jpg"
}
]
Usuario sin Favoritos
Si el usuario no posee productos favoritos, la operación:
GET /favoritos
deberá devolver:
[]
con:
200 OK
Esto no deberá considerarse un error.
Conceptualmente:
Usuario existe
|
v
Buscar favoritos
|
v
0 favoritos
|
v
[]
|
v
200 OK
Reglas de Negocio
La funcionalidad deberá considerar inicialmente las siguientes reglas.
Producto Existente
Antes de agregar un favorito:
POST /favoritos/:productoId
el Backend deberá verificar que el producto exista.
Conceptualmente:
productoId
|
v
ProductosService
|
v
¿Existe producto?
|
+--+--+
| |
Sí No
| |
v v
Continuar Error
Evitar Favoritos Duplicados
Un usuario no deberá mantener dos relaciones iguales con el mismo producto.
Por ejemplo:
Usuario 3
+
Producto 25
deberá existir como máximo una vez.
No debería producirse:
usuarioId: 3, productoId: 25
usuarioId: 3, productoId: 25
usuarioId: 3, productoId: 25
Favoritos Independientes por Usuario
Cada usuario deberá administrar únicamente sus propios favoritos.
Por ejemplo:
Usuario 1
├── Producto 5
└── Producto 8
Usuario 2
├── Producto 5
└── Producto 20
El hecho de que ambos usuarios tengan:
Producto 5
como favorito es válido.
Lo que debe evitarse es que:
Usuario 1
pueda eliminar o modificar directamente los favoritos pertenecientes a:
Usuario 2
Eliminación de un Favorito
Eliminar un favorito deberá eliminar solamente la relación:
Usuario - Producto
No deberá modificar:
Producto
stock
precio
catálogo
información del producto
Conceptualmente:
ANTES
Usuario
|
v
Favorito
|
v
Producto 25
DELETE /favoritos/25
DESPUÉS
Usuario
Producto 25
continúa existiendo
Identificación del Usuario
Esta es actualmente la principal dependencia pendiente para implementar Favoritos.
Los endpoints propuestos son:
GET /favoritos
POST /favoritos/:productoId
DELETE /favoritos/:productoId
pero ninguno contiene:
usuarioId
en la URL.
Esto es intencional si el usuario es identificado mediante autenticación.
Conceptualmente:
Request
|
+--> Token / Sesión
|
v
Usuario autenticado
|
v
Favoritos de ese usuario
Por ejemplo:
GET /favoritos
debería significar:
Obtener MIS favoritos
y no:
Obtener los favoritos de todos los usuarios
Dependencia con Autenticación
Antes de implementar completamente Favoritos deberá definirse cómo se obtiene el usuario autenticado.
Conceptualmente:
Usuario inicia sesión
|
v
Autenticación
|
v
Usuario identificado
|
+-------------------+
| |
v v
Favoritos Carrito
Por esta razón, Favoritos se encuentra relacionado con:
y:
Posible Flujo Futuro
Una vez implementada la autenticación, una solicitud podría funcionar conceptualmente así:
GET /favoritos
|
v
Request autenticada
|
v
Obtener usuarioId
|
v
FavoritosService
|
v
Buscar relaciones del usuario
|
v
Obtener productos
|
v
ProductoFavoritoDto[]
Relación con ProductosService
Favoritos necesitará consultar información perteneciente al dominio Productos.
Por ejemplo:
POST /favoritos/25
|
v
FavoritosService
|
| verificar producto
v
ProductosService
También al consultar favoritos:
Favoritos
|
| productoId
v
Productos
|
v
ProductoFavoritoDto
Por lo tanto, al implementar esta funcionalidad podrá evaluarse reutilizar:
ProductosService
en lugar de duplicar información del catálogo.
Manejo de Errores Propuesto
Los códigos definitivos deberán establecerse durante la implementación.
Como criterio inicial podrán considerarse:
| Código | Situación |
|---|---|
200 OK |
Favoritos obtenidos correctamente |
200 OK con [] |
El usuario no posee favoritos |
201 Created |
Producto agregado correctamente a favoritos |
400 Bad Request |
Parámetro incorrecto o intento de duplicar una relación, según la regla definitiva |
401 Unauthorized |
Usuario no autenticado |
404 Not Found |
Producto solicitado no existe |
204 No Content |
Favorito eliminado correctamente, si se adopta este contrato |
Los códigos exactos deberán confirmarse al momento de implementar los endpoints y documentarse posteriormente en Swagger y Endpoints.
Documentación Swagger
Cuando se implemente la funcionalidad deberán documentarse las operaciones mediante decoradores como:
@ApiTags()
@ApiOperation()
@ApiParam()
@ApiOkResponse()
@ApiCreatedResponse()
@ApiNotFoundResponse()
@ApiUnauthorizedResponse()
según corresponda.
El parámetro:
productoId
deberá documentarse como:
Number
y la respuesta de:
GET /favoritos
como:
ProductoFavoritoDto[]
Flujo General
Conceptualmente:
Frontend / Mobile
|
v
Usuario autenticado
|
v
FavoritosController
|
v
FavoritosService
|
+-------------------------+
| |
v v
Usuario ProductosService
| |
v v
Relaciones favoritas Productos
| |
+------------+------------+
|
v
ProductoFavoritoDto[]
Relación con el Header
Desde el Header, el usuario podrá acceder a su lista de favoritos.
Header
|
v
Favoritos
|
v
GET /favoritos
|
v
Productos Favoritos
Desde otras páginas podrá:
Producto
|
+--> POST /favoritos/:productoId
|
└--> DELETE /favoritos/:productoId
Estado de los Componentes
| Elemento | Estado |
|---|---|
| Funcionalidad identificada | Definida |
| Dominio Favoritos | Identificado |
FavoritosModule |
Pendiente |
FavoritosController |
Pendiente |
FavoritosService |
Pendiente |
GET /favoritos |
Pendiente |
POST /favoritos/:productoId |
Pendiente |
DELETE /favoritos/:productoId |
Pendiente |
ProductoFavoritoDto |
Definido |
| Relación Usuario - Producto | Diseño conceptual |
| Identificación del usuario | Pendiente de Autenticación |
| Persistencia | Pendiente |
Decisiones Pendientes
Antes de implementar completamente Favoritos se deberá definir principalmente:
1. Cómo se autenticará el usuario.
2. Cómo obtendrá FavoritosService
la identidad del usuario.
3. Cómo se almacenará la relación:
Usuario - Producto.
4. Qué respuesta tendrá POST
cuando el producto ya sea favorito.
5. Qué respuesta tendrá DELETE
cuando el producto no esté en favoritos.
6. Qué mecanismo de persistencia
utilizará la aplicación.
Estas decisiones deberán resolverse junto con el diseño de Usuarios y Autenticación.
Relación con la Arquitectura
La funcionalidad pertenecerá al dominio:
Favoritos
y conceptualmente utilizará:
FavoritosModule
|
v
FavoritosController
|
v
FavoritosService
|
+--> Usuario autenticado
|
+--> ProductosService
|
v
ProductoFavoritoDto[]
Páginas relacionadas: