Inspirada en el grupo de Facebook "Si lo venís a buscar es tuyo", esta API promueve la economía circular y facilita el intercambio gratuito de objetos entre personas, fomentando la reutilización y reduciendo residuos. A través de esta plataforma, los usuarios pueden ofrecer artículos que ya no necesitan y donar objetos a otros de manera sencilla y accesible.
La API gestiona usuarios, objetos y recogidas para una plataforma de donaciones. Está desarrollada con Express.js, Sequelize para consultas a la base de datos, y JWT para autenticación. Actualmente, no está desplegada y se ejecuta localmente con Docker.
http://localhost:3001
- Token JWT: Requerido para rutas protegidas (por ejemplo,
/user/profile/:id,/object/:id/accept). - Cómo autenticarse:
- Usa
POST /loginoPOST /registerpara obtener un token. - Incluye el token en el encabezado
Authorizationpara rutas protegidas:Authorization: <token>
- Usa
Registra un nuevo usuario.
- Cuerpo (JSON):
{ "user_name": "string", "user_email": "string", "user_pwd": "string" } - Respuestas:
201 Created: Usuario creado.{ "token": "jwt_token", "user": { "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com" } }400 Bad Request: Faltan campos, formato inválido (email o contraseña), ouser_name/user_emailduplicados.{ "error": "Nombre de usuario ya existe" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Inicia sesión y devuelve un token JWT.
- Cuerpo (JSON):
{ "user_email": "string", // o "user_name" "user_pwd": "string" } - Respuestas:
200 OK: Inicio de sesión exitoso.{ "token": "jwt_token", "user_name": "juan" }400 Bad Request: Faltan campos o credenciales inválidas.{ "error": "Debe proporcionar email o nombre de usuario" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene todos los usuarios.
- Respuestas:
200 OK: Lista de usuarios.[ { "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com", "DonatedObjects": [], "ReceivedObjects": [] } ]404 Not Found: No se encontraron usuarios.{ "error": "Usuario no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene un usuario por ID.
- Parámetros:
id(ruta): ID del usuario (entero).
- Respuestas:
200 OK: Datos del usuario.{ "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com", "DonatedObjects": [], "ReceivedObjects": [] }404 Not Found: Usuario no encontrado.{ "error": "Usuario no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene el perfil del usuario autenticado.
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID del usuario (entero).
- Respuestas:
200 OK: Perfil del usuario.{ "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com", "DonatedObjects": [], "ReceivedObjects": [] }401 Unauthorized: Token inválido o ausente.{ "error": "Falta token" }404 Not Found: Usuario no encontrado.{ "error": "Usuario no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene los objetos donados por el usuario autenticado.
- Encabezados:
Authorization: <token>
- Respuestas:
200 OK: Lista de objetos donados.[ { "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 1, "user_name": "juan" }, "Recipient": null, "Pickup": null } ]404 Not Found: No se encontraron donaciones.{ "error": "No se encontraron donaciones asociadas a este usuario" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene las recogidas asociadas al usuario autenticado.
- Encabezados:
Authorization: <token>
- Respuestas:
200 OK: Lista de recogidas.[ { "pickup_id": 1, "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02", "pickup_object_id": 1, "ObjectModel": { "object_id": 1, "object_name": "Libro", "Donor": { "user_id": 2, "user_name": "ana" }, "Recipient": { "user_id": 1, "user_name": "juan" } } } ]404 Not Found: No se encontraron recogidas.{ "error": "No se encontraron recogidas asociadas a este usuario" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Crea un nuevo usuario.
- Cuerpo (JSON):
{ "user_name": "string", "user_email": "string", "user_pwd": "string" } - Respuestas:
200 OK: Usuario creado.{ "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com" }400 Bad Request: Faltan campos o formato inválido.{ "error": "Ingresa un nombre de usuario" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Actualiza un usuario.
- Parámetros:
id(ruta): ID del usuario (entero).
- Cuerpo (JSON):
{ "user_name": "string", "user_email": "string", "user_pwd": "string" } - Respuestas:
200 OK: Usuario actualizado.{ "user_id": 1, "user_name": "juan_actualizado", "user_email": "juan@ejemplo.com", "DonatedObjects": [], "ReceivedObjects": [] }404 Not Found: Usuario no encontrado.{ "error": "Usuario no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Elimina un usuario.
- Parámetros:
id(ruta): ID del usuario (entero).
- Respuestas:
200 OK: Número de usuarios eliminados (1 o 0).1404 Not Found: Usuario no encontrado.{ "error": "Usuario no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene todos los objetos.
- Respuestas:
200 OK: Lista de objetos.[ { "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 1, "user_name": "juan" }, "Recipient": null, "Pickup": null } ]404 Not Found: No se encontraron objetos.{ "error": "Objetos no encontrados" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene los objetos disponibles para el usuario autenticado (excluye los donados por el propio usuario).
- Encabezados:
Authorization: <token>
- Respuestas:
200 OK: Lista de objetos disponibles.[ { "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 2, "user_name": "ana" }, "Recipient": null, "Pickup": null } ]500 Internal Server Error: Error del servidor.{ "error": "Error al obtener objetos disponibles para el usuario" }
Obtiene un objeto por ID.
- Parámetros:
id(ruta): ID del objeto (entero).
- Respuestas:
200 OK: Datos del objeto.{ "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 1, "user_name": "juan" }, "Recipient": null, "Pickup": null }404 Not Found: Objeto no encontrado.{ "error": "Objeto no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Crea un nuevo objeto.
- Encabezados:
Authorization: <token>
- Cuerpo (JSON):
{ "object_name": "string", "object_description": "string", "object_img": "string", "pickup_area": "string", "pickup_start_date": "string", "pickup_end_date": "string" } - Respuestas:
200 OK: Objeto creado.{ "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 1, "user_name": "juan" }, "Recipient": null, "Pickup": { "pickup_id": 1, "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02" } }400 Bad Request: Faltan campos o datos inválidos.{ "error": "Indique de qué objeto se trata" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Reserva un objeto, cambiando su estado a "Reservado".
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID del objeto (entero).
- Respuestas:
200 OK: Objeto reservado.{ "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Reservado", "Donor": { "user_id": 2, "user_name": "ana" }, "Recipient": { "user_id": 1, "user_name": "juan" }, "Pickup": null }400 Bad Request: Objeto no disponible o usuario es el donante.{ "error": "Objeto no disponible" }404 Not Found: Objeto no encontrado.{ "error": "Objeto no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Cancela la reserva de un objeto, devolviéndolo a "Disponible".
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID del objeto (entero).
- Respuestas:
200 OK: Reserva cancelada.{ "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 2, "user_name": "ana" }, "Recipient": null, "Pickup": null }400 Bad Request: Objeto no reservado o usuario no autorizado.{ "error": "Objeto no reservado" }404 Not Found: Objeto no encontrado.{ "error": "Objeto no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Actualiza un objeto (solo por el donante).
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID del objeto (entero).
- Cuerpo (JSON):
{ "object_name": "string", "object_description": "string", "object_img": "string" } - Respuestas:
200 OK: Objeto actualizado.{ "object_id": 1, "object_name": "Libro actualizado", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 1, "user_name": "juan" }, "Recipient": null, "Pickup": null }400 Bad Request: Campos inválidos o usuario no autorizado.{ "error": "Campos inválidos: object_state" }404 Not Found: Objeto no encontrado.{ "error": "Objeto no encontrado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Elimina un objeto (solo por el donante).
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID del objeto (entero).
- Respuestas:
200 OK: Número de objetos eliminados (1 o 0).1404 Not Found: Objeto no encontrado.{ "error": "Objeto no encontrado" }403 Forbidden: Usuario no autorizado.{ "error": "Permiso denegado" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene todas las recogidas.
- Respuestas:
200 OK: Lista de recogidas.[ { "pickup_id": 1, "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02", "pickup_object_id": 1, "ObjectModel": { "object_id": 1, "object_name": "Libro" } } ]500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene una recogida por ID.
- Parámetros:
id(ruta): ID de la recogida (entero).
- Respuestas:
200 OK: Datos de la recogida.{ "pickup_id": 1, "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02", "pickup_object_id": 1, "ObjectModel": { "object_id": 1, "object_name": "Libro" } }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Crea una nueva recogida.
- Encabezados:
Authorization: <token>
- Cuerpo (JSON):
{ "pickup_area": "string", "pickup_start_date": "string", "pickup_end_date": "string", "pickup_object_id": integer } - Respuestas:
200 OK: Recogida creada.{ "pickup_id": 1, "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02", "pickup_object_id": 1, "ObjectModel": { "object_id": 1, "object_name": "Libro" } }400 Bad Request: Faltan campos opickup_object_idinválido.{ "error": "Debe indicar el área de recogida" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Actualiza una recogida.
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID de la recogida (entero).
- Cuerpo (JSON):
{ "pickup_area": "string", "pickup_start_date": "string", "pickup_end_date": "string", "pickup_object_id": integer } - Respuestas:
200 OK: Recogida actualizada.1400 Bad Request: Fechas inválidas o datos incorrectos.{ "error": "Fecha inicial inválida" }500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Elimina una recogida.
- Encabezados:
Authorization: <token>
- Parámetros:
id(ruta): ID de la recogida (entero).
- Respuestas:
200 OK: Número de recogidas eliminadas (1 o 0).1500 Internal Server Error: Error del servidor.{ "error": "Error del servidor" }
Obtiene la configuración de Cloudinary para subir imágenes.
- Respuestas:
200 OK: Configuración de Cloudinary.{ "cloud_name": "string", "upload_preset": "string" }500 Internal Server Error: Error del servidor.{ "error": "Error interno" }
Los errores devuelven un objeto JSON con un campo error:
{ "error": "Mensaje de error" }Códigos de estado comunes:
200 OK: Éxito.201 Created: Recurso creado.400 Bad Request: Parámetros inválidos o ausentes.401 Unauthorized: Token inválido o ausente.403 Forbidden: Permiso denegado.404 Not Found: Recurso no encontrado.500 Internal Server Error: Error del servidor.
-
Clonar el Repositorio:
git clone https://github.com/Ceci222/Lo_quiero.git cd Lo_quiero -
Instalar Dependencias:
npm install
-
Configurar Entorno:
- Crea un archivo
.envcon las siguientes variables (valores de ejemplo):APP_HOST=localhost APP_PORT=3001 DB_HOST=mysql DB_PORT=3306 DB_ROOT_PASSWORD=**** DB_NAME=**** DB_USER=**** DB_PASSWORD=**** NODE_ENV=development JWT_SECRET=**** CLOUDINARY_CLOUD_NAME=**** CLOUDINARY_UPLOAD_PRESET=****
- Crea un archivo
-
Ejecutar con Docker:
docker compose up --build
-
Acceder a la API:
- Abre
http://localhost:3001en un navegador o en Postman.
- Abre
Postman:
-
Registrar un Usuario:
- Solicitud:
POST http://localhost:3001/register Content-Type: application/json { "user_name": "juan", "user_email": "juan@ejemplo.com", "user_pwd": "Pass1234" }
- Respuesta:
{ "token": "jwt_token", "user": { "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com" } }
- Solicitud:
-
Iniciar Sesión:
- Solicitud:
POST http://localhost:3001/login Content-Type: application/json { "user_email": "juan@ejemplo.com", "user_pwd": "Pass1234" }
- Respuesta:
{ "token": "jwt_token", "user_name": "juan" }
- Solicitud:
-
Obtener Perfil del Usuario:
- Solicitud:
GET http://localhost:3001/user/profile/1 Authorization: <jwt_token>
- Respuesta:
{ "user_id": 1, "user_name": "juan", "user_email": "juan@ejemplo.com", "DonatedObjects": [], "ReceivedObjects": [] }
- Solicitud:
-
Crear un Objeto:
- Solicitud:
POST http://localhost:3001/object Authorization: <jwt_token> Content-Type: application/json { "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02" }
- Respuesta:
{ "object_id": 1, "object_name": "Libro", "object_description": "Una novela", "object_img": "url", "object_state": "Disponible", "Donor": { "user_id": 1, "user_name": "juan" }, "Recipient": null, "Pickup": { "pickup_id": 1, "pickup_area": "Centro", "pickup_start_date": "2025-05-01", "pickup_end_date": "2025-05-02" } }
- Solicitud: