Construir una plataforma de streaming musical (estilo Spotify) con Node.js + Express + MySQL, que contemple un modelo relacional correcto, endpoints REST bien documentados y validaciones para prevenir errores frecuentes.
Este es un proyecto base con toda la estructura necesaria para que completes el desarrollo de una API REST. Todos los archivos están creados pero vacíos - tu trabajo es implementar la funcionalidad.
# 1. Hacer fork del repositorio en GitHub
# Ve a: https://github.com/FabioDrizZt/Trabajo-Integrador-Spotify-Backend/
# Haz clic en "Fork" para crear tu copia
# 2. Clonar tu fork
git clone https://github.com/TU_USUARIO/Trabajo-Integrador-Spotify-Backend.git
# 3. Navegar al directorio del proyecto
cd Trabajo-Integrador-Spotify-Backend
# 4. Instalar dependencias
npm install
# 5. Configurar variables de entorno
cp env.example .env
# Editar .env con tus datos de MySQL# Ejecutar el script SQL en MySQL
mysql -u tu_usuario -p < scripts.sql# Modo desarrollo
npm run dev
# El servidor estará disponible en http://localhost:3000Usa Datos_Spotify.xlsx o Datos_Spotify.json (artistas, discográficas, álbumes, canciones, géneros, usuarios, playlists, suscripciones, datos de pago y pagos) como guía para poblar la base y validar casos reales.
📁 Proyecto Spotify Backend/
├── 📄 package.json # Dependencias ya configuradas ✅
├── 📄 env.example # Variables de entorno (copia a .env)
├── 📄 .gitignore # Archivos a ignorar en Git ✅
├── 📄 server.js # Punto de entrada (COMPLETAR)
├── 📄 scripts.sql # Base de datos completa ✅
├── 📄 api.http # Pruebas REST Client ✅
├── 📄 readme.md # Especificación del proyecto ✅
├── 📁 src/
│ ├── 📄 app.js # Configuración Express (COMPLETAR)
│ ├── 📁 config/
│ │ ├── 📄 database.js # Conexión MySQL (COMPLETAR)
│ ├── 📁 models/ # Modelos de datos (COMPLETAR)
│ │ ├── 📄 Usuario.js
│ │ ├── 📄 Artista.js
│ │ ├── 📄 Album.js
│ │ ├── 📄 Cancion.js
│ │ ├── 📄 Genero.js
│ │ ├── 📄 Playlist.js
│ │ ├── 📄 Suscripcion.js
│ │ ├── 📄 MetodoPago.js
│ │ └── 📄 Pago.js
│ ├── 📁 routes/ # Rutas Express (COMPLETAR)
│ │ ├── 📄 index.js
│ │ ├── 📄 usuarios.js
│ │ ├── 📄 artistas.js
│ │ ├── 📄 albumes.js
│ │ ├── 📄 canciones.js
│ │ ├── 📄 generos.js
│ │ ├── 📄 playlists.js
│ │ ├── 📄 suscripciones.js
│ │ ├── 📄 metodos-pago.js
│ │ ├── 📄 pagos.js
│ │ └── 📄 vistas.js # ⭐ EJERCICIOS ADICIONALES
│ ├── 📁 controllers/ # Lógica de negocio (COMPLETAR)
│ │ ├── 📄 usuariosController.js
│ │ ├── 📄 artistasController.js
│ │ ├── 📄 albumesController.js
│ │ ├── 📄 cancionesController.js
│ │ ├── 📄 generosController.js
│ │ ├── 📄 playlistsController.js
│ │ ├── 📄 suscripcionesController.js
│ │ ├── 📄 metodosPagoController.js
│ │ ├── 📄 pagosController.js
│ │ └── 📄 vistasController.js # ⭐ EJERCICIOS ADICIONALES
│ ├── 📁 data/ # Datos de referencia ✅
│ │ ├── 📄 Datos_Spotify.json
│ │ └── 📄 Datos_Spotify.xlsx
│ └── 📁 docs/ # Documentación ✅
│ └── 📄 swagger.yaml
src/config/database.js- Conexión MySQLsrc/config/index.js- Variables centralizadasserver.js- Inicialización del servidorsrc/app.js- Configuración Express
- Empezar por
Usuario.jsyArtista.js(más simples) - Continuar con
Album.js,Cancion.js,Genero.js - Terminar con
Playlist.js,Suscripcion.js,MetodoPago.js,Pago.js
- Implementar lógica de negocio para cada entidad
- Usar los modelos creados anteriormente
- Conectar controladores con endpoints
vistasController.js- Consultas con JOINs complejosvistas.js- Rutas para las vistas
Incluye, como mínimo, estas tablas (puedes agregar otras si aportan valor):
- usuario (
id_usuarioPK,emailUNIQUE NOT NULL,password_hashNOT NULL,fecha_nac,sexoCHAR(1),cp,id_paisFK →pais,tipo_usuario_actualFK →tipo_usuario,fecha_ult_mod_passwordDATETIME). - pais (
id_pais,nombre_paisUNIQUE). - tipo_usuario (
id_tipo_usuario, valores:free,standard,premium). - artista (
id_artista,nombreUNIQUE,imagen_url). - discografica (
id_discografica,nombre,id_paisFK) con UNIQUE (nombre,id_pais). - album (
id_album,titulo,id_artistaFK,id_discograficaFK,imagen_portada,anio_publicacion,duracion_total_segINT derivada). UNIQUE (id_artista,titulo). - genero (
id_genero,nombreUNIQUE). - cancion (
id_cancion,titulo,duracion_segINT NOT NULL,id_albumFK,reproduccionesBIGINT DEFAULT 0,likesBIGINT DEFAULT 0,fecha_agregadaDATETIME DEFAULT CURRENT_TIMESTAMP). - cancion_genero (N:M) PK(
id_cancion,id_genero). - playlist (
id_playlist,titulo,id_usuarioFK,cant_cancionesINT derivada,estadoENUM('activa','eliminada') DEFAULT 'activa',fecha_creacionDATETIME,fecha_eliminadaDATETIME NULL). CHECK coherenciaestado/fecha_eliminada. - playlist_cancion (N:M) PK(
id_playlist,id_cancion),orden,fecha_agregada. - suscripcion (
id_suscripcion,id_usuarioFK,tipo_usuarioFK/ENUM,fecha_inicio,fecha_renovacion). CHECKfecha_renovacion > fecha_inicioy UNIQUE (id_usuario,fecha_inicio). - metodo_pago (
id_metodo_pago,id_usuarioFK,tipo_forma_pago,cbu,banco_codigo,nro_tarjeta_masc(últimos 4),mes_caduca,anio_caduca, sin CVC). Permitir múltiples métodos por usuario. - pago (
id_pago,id_usuarioFK,id_suscripcionFK,id_metodo_pagoFK,importe,fecha_pago).
- Email obligatorio y único en
usuario. - Duración de canciones en segundos (INT) → no usar formato
mm.sscomoDECIMAL. - No duplicar datos:
cancionno debe guardar artista/discográfica; eso proviene dealbum. - UNIQUE (
id_artista,titulo) enalbumpara evitar duplicados. - Playlist soft-delete: si
estado='eliminada'entoncesfecha_eliminadaNOT NULL; siactiva, entoncesfecha_eliminadaNULL. - Métodos de pago: sin CVC y PAN enmascarado (guardar solo últimos 4). N métodos por usuario;
pagodebe referenciar unmetodo_pagoreal. - Cargas mínimas: al menos 3 usuarios, 3 álbumes y 3 canciones. Incluye 1 playlist con canciones y otra eliminada (con fecha).
Prefijo sugerido: /api/v1.
- GET
/usuarios→ lista. - GET
/usuarios/:id→ detalle. - POST
/usuarios→ crear (validar email único, hashear password, setearfecha_ult_mod_password). - PUT
/usuarios/:id→ actualizar (si cambiapassword, actualizarfecha_ult_mod_password). - DELETE
/usuarios/:id→ baja lógica (activo=false) o hard-delete si lo justificás. - GET
/usuarios/password-vencidas→ lista usuarios con contraseña > 90 días.
- GET
/artistasy GET/artistas/:id. - POST
/artistas→ validarnombreúnico.
- GET
/albumes→ filtros:?artistaId,?q. - GET
/albumes/:id. - GET
/albumes/:id/canciones. - POST
/albumes→ validar UNIQUE (id_artista,titulo).
- GET
/canciones→ filtros:?genero=,?artistaId=,?albumId=. - GET
/canciones/:id. - POST
/canciones→ validarduracion_seg(INT>0) yid_albumexistente. - PUT
/canciones/:id. - POST
/canciones/:id/generos{id_genero} → asocia género. - DELETE
/canciones/:id/generos/:idGenero→ desasocia.
- GET
/generos– POST/generos(único por nombre).
- GET
/playlists– GET/playlists/:id. - POST
/playlists. - PUT
/playlists/:id(cambiartitulooestado; sieliminada, setearfecha_eliminada). - POST
/playlists/:id/canciones{id_cancion,orden} → agregar. - DELETE
/playlists/:id/canciones/:idCancion→ quitar.
- GET
/suscripciones– GET/suscripciones/:id. - POST
/suscripciones→ validarfecha_renovacion > fecha_inicioy UNIQUE (id_usuario,fecha_inicio).
- GET
/metodos-pago?usuarioId=. - POST
/metodos-pago→ crear (sin CVC;nro_tarjeta_masc=**** **** **** 1234).
- GET
/pagos?usuarioId=&desde=&hasta=. - POST
/pagos→ registrar pago referenciandoid_suscripcionyid_metodo_pagoválidos.
Los estudiantes deben implementar estos endpoints que utilizan consultas complejas con múltiples JOINs:
- GET
/vistas/canciones-populares-por-pais - Archivo:
src/controllers/vistasController.js→ métodocancionesPopularesPorPais - Objetivo: Mostrar las canciones más reproducidas agrupadas por país de origen de los usuarios.
- Datos a incluir:
nombre_cancion,nombre_artista,nombre_album,nombre_pais,total_reproducciones,apariciones_en_playlists. - JOINs requeridos:
cancion→album→artista,playlist_cancion→playlist→usuario→pais. - Lógica: Agrupar por país y canción, sumar reproducciones, contar apariciones en playlists activas.
- Ordenamiento: Por país y luego por total de reproducciones (DESC).
- GET
/vistas/ingresos-por-artista-discografica - Archivo:
src/controllers/vistasController.js→ métodoingresosPorArtistaDiscografica - Objetivo: Analizar los ingresos generados por cada combinación artista-discográfica.
- Datos a incluir:
nombre_artista,nombre_discografica,nombre_pais_discografica,total_ingresos,cantidad_suscripciones_activas,total_canciones,promedio_reproducciones. - JOINs requeridos:
pago→suscripcion→usuario→playlist→playlist_cancion→cancion→album→artista/discografica→pais. - Lógica: Calcular ingresos totales, contar suscripciones activas, estadísticas de canciones.
- Filtros: Solo suscripciones vigentes (
fecha_renovacion > NOW()) y playlists activas. - Ordenamiento: Por total de ingresos (DESC).
💡 Tip para estudiantes: Estas consultas requieren entender bien las relaciones entre tablas y usar agregaciones (SUM, COUNT, AVG) junto con GROUP BY. Son excelentes para practicar JOINs complejos y análisis de datos.
- Email único en usuarios
- Duración en segundos (INT) para canciones
- UNIQUE (artista, título) para álbumes
- Soft delete coherente en playlists
- Tarjetas enmascaradas sin CVC
- Fechas válidas en suscripciones
- Hasheo de contraseñas con bcrypt
- 400: Datos faltantes o inválidos
- 409: Conflictos de unicidad
- 422: Estructura semánticamente inválida
- 404: Recursos no encontrados
- 401/403: Si implementás auth (opcional recomendado)
Respuestas JSON con { error: { code, message, details } }.
- Usar api.http: Archivo con todas las pruebas listas
- Casos positivos: Crear, leer, actualizar, eliminar
- Casos negativos: Datos inválidos, duplicados, etc.
- Ejercicios adicionales: Probar las vistas con JOINs
Se incluye un archivo api.http (VS Code – REST Client) con solicitudes listas para probar todos los endpoints, incluidos casos negativos que deben fallar si las validaciones están bien.
- Hashear contraseñas (bcrypt). Nunca devolver
password_hash. - Variables de entorno en
.env(DB_HOST,DB_USER,DB_PASS,DB_NAME, etc.). - Logueo, manejo centralizado de errores, rate limiting básico.
- Modelo de datos (30%): Estructura correcta, constraints, triggers
- Integridad/Validaciones (25%): Manejo de errores, validaciones
- Endpoints (25%): Funcionalidad completa de la API
- Ejercicios JOINs (10%): Implementación de vistas complejas
- Documentación (10%): DER, comentarios, README
- Lee toda la especificación antes de empezar
- Implementa paso a paso siguiendo el orden sugerido
- Prueba frecuentemente con api.http
- Maneja errores apropiadamente desde el inicio
- Comenta tu código para facilitar la revisión
- Crea el DER para entender las relaciones
- No copies código - entiende lo que implementas
- README.md: Especificación completa del proyecto
- src/docs/swagger.yaml: Documentación detallada de la API
- INSTRUCCIONES_ESTUDIANTES.md: Guía paso a paso para estudiantes
- Revisa los comentarios en cada archivo
- Consulta la documentación Swagger para ver ejemplos
- Usa los datos de prueba en scripts.sql
- Prueba con casos simples antes de casos complejos
- Scripts SQL (creación + inserts) ✔
- API funcional con endpoints arriba listados ✔
- Validaciones anti-errores implementadas ✔
- DER (imagen en
/docs) ✔ - Documentación (Swagger o Markdown) ✔
- Datos mínimos (≥ 3 usuarios, 3 álbumes, 3 canciones; playlists con canciones; una playlist eliminada) ✔
Ponderación sugerida: Modelo 30% · Integridad/validaciones 25% · Endpoints 25% · Datos/consistencia 10% · Documentación 10%.
- Crear BD y tablas con
scripts.sql. npm i· configurar.env·npm run dev.- Abrir
api.httpen VS Code y ejecutar solicitudes.
¡Éxito en tu proyecto! 🚀