Usuarios Favoritos — Referencia Técnica
Dónde vive esto
Backend
apps/backend/graphql/resolvers/user-favorites.resolver.js- resuelvefavoriteUsers,isFavoriteUser,getFavoritesStats,addToFavorites,removeFromFavorites,reorderFavorites(archivo de resolver dedicado propio, no en línea enuser.resolver.js)apps/backend/graphql/types/favorites.type.js- tipos del esquema de favoritosapps/backend/managers/user-managers/favorites.manager.js- lógica de negocio de favoritos, llamada desdemanagers/user-managers/index.js. Aplica un límite de 50 favoritos por usuario (maxFavoritesenaddToFavorites), lanzandofavorites.limit_exceededal alcanzarlo.apps/backend/data-access-services/user/user-favorite.access-service.js- acceso a la base de datos de favoritos
Frontend
apps/frontend-nextjs/src/page-components/settings/FavoritesPage.tsx(enrutada en/settings/favorites) — enumera las cuentas favoritas con acciones de reordenar (arriba/abajo) y eliminar por fila, además del encabezado de estadísticas; conectada afavoriteUsers,removeFromFavorites,reorderFavoritesygetFavoritesStats. No tiene un mecanismo propio para "agregar".apps/frontend-nextjs/src/page-components/PublicProfilePage.tsx— el menú ⋯ Más opciones de un perfil (MoreOptionsMenu) muestra un interruptor de "Agregar a favoritos" / "Quitar de favoritos" respaldado porisFavoriteUser,addToFavorites, yremoveFromFavorites. Este es el único lugar donde se puede agregar un favorito desde la interfaz hoy.
Checklist de implementación técnica
-
addToFavorites— conectado enuser-favorites.resolver.js; utilizado por el interruptor de favorito dePublicProfilePage.tsx -
removeFromFavorites— conectado; utilizado tanto porFavoritesPage.tsxcomo porPublicProfilePage.tsx -
favoriteUsers— conectado; utilizado porFavoritesPage.tsx -
isFavoriteUser— conectado; utilizado porPublicProfilePage.tsxpara renderizar el estado actual del interruptor -
reorderFavorites— conectado enuser-favorites.resolver.js; utilizado por los controles de subir/bajar por fila deFavoritesPage.tsx -
getFavoritesStats— conectado; utilizado por el encabezado de estadísticas deFavoritesPage.tsx. Corregido en esta sesión:mutualFavorites/recentAdditions/mostFavoritedUserantes tenían valores fijos0/0/null; los tres son ahora queries agregadas reales (ver Queries a continuación) - Persistencia real —
favorites.manager.jsdelega enuser-favorite.access-service.js(create / destroy / getUserFavorites / getFavoritesCount / update), respaldado por el modelo SequelizeUserFavorite(migración20250109000003-create-user-favorites-table.js). Sin estructuras simuladas (mock).
Queries
favoriteUsers devuelve la lista completa de favoritos del usuario actual, con el position (el orden de clasificación) y la marca de tiempo addedAt de cada entrada. Usa limit y offset para el renderizado paginado.
isFavoriteUser es una verificación booleana ligera — utilizada por PublicProfilePage.tsx para renderizar el estado del interruptor "Agregar a favoritos" / "Quitar de favoritos" en el menú Más opciones de un perfil, sin obtener la lista completa.
getFavoritesStats declara campos para métricas agregadas (total, mutuos, adiciones recientes, el más favorito), y ahora todos son reales. Corregido en esta sesión: mutualFavorites/recentAdditions/mostFavoritedUser antes tenían valores fijos 0/0/null. favorites.manager.js#getFavoritesStats ahora ejecuta queries reales contra user_favorites: mutualFavorites cuenta el favoriteo recíproco (usuarios que también te agregaron a ti como favorito), recentAdditions cuenta los favoritos agregados en los últimos 7 días, y mostFavoritedUser es el usuario de entre tus favoritos con el mayor conteo total de favoritos a nivel de todo el sistema.
query FavoriteUsers($limit: Int, $offset: Int) {
favoriteUsers(limit: $limit, offset: $offset) {
total limit offset
favorites {
id position addedAt
user { id username profilePicture isVerified }
}
}
}
query IsFavorite($userId: ID!) {
isFavoriteUser(userId: $userId)
}
query FavoritesStats {
getFavoritesStats {
totalFavorites
mutualFavorites # users who have also favorited you
recentAdditions # added in the last 7 days
mostFavoritedUser { username profilePicture }
}
}
Mutations
addToFavorites agrega un usuario a la lista de favoritos y le asigna el siguiente position disponible. El esquema declara un campo favorite: FavoriteUser anulable en la respuesta. Corregido en esta sesión: el manager antes devolvía una clave favoriteUser, que no existe en absoluto en el esquema (el campo se llama favorite), por lo que siempre resolvía a null. Ahora devuelve un objeto favorite: { id, user, addedAt, position } correcto que coincide con FavoriteUser, así que la respuesta de la mutación puede usarse para insertar la nueva entrada sin necesidad de volver a obtener los datos.
removeFromFavorites elimina un usuario de la lista. No recompacta los valores de position restantes — quedan huecos que simplemente no afectan el orden, ya que la lista siempre se ordena por position ASC.
reorderFavorites acepta la lista completa y ordenada de IDs de usuario. El servidor reemplaza el orden existente con la nueva secuencia, actualizando position para cada entrada. Para mover un solo usuario, envía la lista completa con ese usuario en el índice deseado.
mutation AddFavorite($userId: ID!) {
addToFavorites(userId: $userId) {
success message
favorite { id position addedAt user { username } }
}
}
mutation RemoveFavorite($userId: ID!) {
removeFromFavorites(userId: $userId) { success message }
}
# Pass the complete ordered list of user IDs to update all positions at once
mutation ReorderFavorites($userIds: [ID!]!) {
reorderFavorites(userIds: $userIds) { success message }
}
reorderFavorites acepta la lista completa y ordenada de IDs de usuario y actualiza position para cada entrada.