7.6 KiB
Musify — Guía de páginas
Documento vivo de qué debe contener cada página del frontend web. Sirve como mapa
para priorizar features. El sistema de diseño (tokens, recetas, componentes) vive en
el skill musify-web; aquí describimos contenido y estructura, no estilos.
Leyenda de estado: ✅ hecho · 🟡 parcial / maqueta · ⬜ pendiente.
Nota (rediseño app): se está portando el prototipo
Musify.dc.html(app: sidebar + vistas + player persistente con acento dinámico por pista). La landing de marketing se eliminó. Las secciones de abajo describen el diseño anterior y quedan pendientes de actualizar a las vistas de la app (Inicio, Buscar, Biblioteca, Subir, Importar, Descargas, Playlists). El player ya está hecho por componentes en$lib/components/player/con el tema en$lib/theme/(theme.csspaleta +color.tsacento/gradiente).
Inicio (app) / 🟡
- Hero: saludo + "Tu música. Sin límites." con color-wash del hue de la pista actual.
- Acceso rápido = escuchado recientemente (
player.recentlyPlayed, hoy en cliente). Estado vacío con icono + CTA «Explorar». - Tus playlists: tarjetas mosaico de las playlists (hoy datos de muestra). Estado vacío.
Backend pendiente (ASP.NET) para Inicio
- Escuchado recientemente: registrar reproducciones por usuario (tabla de historial:
userId,trackId,playedAt) y exponerGET /me/recently-played?limit=(o/users/{id}/recently-played) devolviendo pistas ordenadas porplayedAtdesc, sin duplicados. El front lo cargaría en unloady lo pasaría al store en vez derecentlyPlayed. - Playlists por última escucha: añadir
lastPlayedAta la playlist (hoy el schema solo tienecreatedAt/updatedAt) y permitir ordenarGET /playlists/users/{userId}por ese campo (p. ej.?sort=lastPlayed), para mostrar «tus últimas escuchadas». - Las pistas necesitarán artista y un color/hue (o portada real de la que extraerlo)
para el arte y el acento dinámico; hoy
TrackApplicationResponseno trae artista ni color.
Estructura de rutas
Rutas agrupadas para separar lo público de lo autenticado (los grupos no cambian la URL):
src/routes/
(marketing)/ Público, sin sesión obligatoria
+page.svelte / Landing ✅
(app)/ Experiencia de la app
explore/ /explore Explorar / buscar ✅
upload/ /upload Subir música 🟡 maqueta
library/ /library Tu biblioteca ⬜
playlists/ /playlists Tus playlists ⬜
[id]/ /playlists/:id Detalle playlist ⬜
login logout auth/callback Auth (endpoints) ✅
api/tracks/[id]/stream Proxy de stream ✅
Componentes globales (en todas las páginas): Navbar, Footer y PlayerBar (barra de reproducción fija, aparece al reproducir).
1. Landing / ✅ (marketing)
Página de entrada para no autenticados. Vender el producto y llevar a registro/explorar.
- Hero: badge de estado (beta), título, subtítulo, CTAs primario (Empezar gratis → registro) y secundario (Explorar canciones).
- Features: 3 cards (escuchar, playlists, subir).
- Pendiente sugerido: sección de capturas/demo, prueba social, FAQ corta.
2. Login / Auth ✅ (endpoints)
No es una página visual propia: /login inicia el flujo OIDC de Zitadel y redirige.
?mode=register arranca en registro; ?returnTo= vuelve a la ruta pedida tras entrar.
/logout cierra sesión. /auth/callback intercambia el código y crea la cookie
cifrada mf_session. La UI de credenciales la sirve Zitadel, no Musify.
3. Explorar / Buscar /explore ✅ (app)
Descubrimiento y búsqueda de canciones del catálogo.
- Buscador: input de texto (
?q=) que filtra por nombre en el backend. - Contador de resultados y grid de tracks (2→4 columnas): portada, título, fecha, botón play/pausa en hover que encola y reproduce vía el player global.
- Paginación anterior/siguiente (
?page=, 24 por página). - Estado vacío: sin resultados / catálogo vacío.
- Pendiente sugerido: filtros (más recientes, por usuario), skeletons de carga, portada real del track (hoy la API de listado no devuelve la key de imagen).
4. Subir música /upload 🟡 maqueta (app)
Alta de una canción nueva. Flujo real de backend (para cuando se cablee):
POST /tracks/upload-urls→ URLs presignadas para portada y audio +intentIds.PUTde cada archivo a su URL presignada (subida directa al almacenamiento).POST /trackscontitle,pictureIntentId,audioIntentId.- El backend procesa el audio (transcodifica a DASH) de forma asíncrona.
Contenido de la página:
- Zona de audio: drag & drop o selector; muestra nombre y tamaño del archivo, validación de tipo (audio) y tamaño.
- Portada: selector de imagen con vista previa cuadrada.
- Metadatos: título (obligatorio). Espacio para futuros campos (descripción, etc.).
- Pipeline visible: pasos Subir → Procesar → Publicar con su estado.
- Barra de progreso de subida y estado de procesado.
- Estados: vacío, archivo seleccionado, subiendo, procesando, publicado, error.
- Requiere sesión (al cablear: redirigir a
/login?returnTo=/upload).
5. Tu biblioteca /library ⬜ (app)
Panel personal del usuario autenticado: lo suyo en un sitio.
- Tabs / secciones: «Tus canciones» (
GET /tracks/users/{userId}) y «Tus playlists» (GET /playlists/users/{userId}). - Tus canciones: lista con play, y acciones de gestión (borrar
DELETE /tracks/{id}, añadir a playlist). - Tus playlists: grid de portadas + botón «Crear playlist».
- Estado vacío con CTA a subir / crear.
- Requiere sesión.
6. Playlists /playlists ⬜ (app)
Listado de las playlists del usuario.
- Grid de playlists (portada, nombre, nº de tracks) → enlaza al detalle.
- Crear playlist: modal/página con nombre, descripción y portada
(
POST /playlists, portada víaPOST /playlists/upload-picture). - Estado vacío con CTA.
- Requiere sesión.
7. Detalle de playlist /playlists/[id] ⬜ (app)
- Cabecera: portada grande, nombre, descripción, nº de tracks, botón «Reproducir todo».
- Lista de tracks (
GET /playlists/{id}/tracks, paginada): índice, título, fecha, play, quitar de la playlist (DELETE /playlists/{id}/tracks/{trackId}). - Acciones del dueño: editar (
PUT), borrar (DELETE) la playlist, reordenar (futuro). - Añadir tracks: desde explorar/biblioteca (
POST /playlists/{id}/tracks/{trackId}).
8. Perfil de usuario /users/[id] ⬜ (futuro)
Vista pública de un usuario: avatar, nombre, sus canciones y playlists públicas
(GET /users/{id}, GET /tracks/users/{id}, GET /playlists/users/{id}).
Player global (PlayerBar) ✅
Barra fija inferior visible al reproducir. Info de la pista, transporte
(anterior/play-pausa/siguiente), barra de progreso y control de volumen. Encola listas
desde cualquier grid (player.playQueue). Reproduce DASH vía el proxy
/api/tracks/:id/stream, que pide manifiesto + ticket firmado al backend.
Backend disponible (resumen)
| Recurso | Endpoints |
|---|---|
| Tracks | listar/buscar, detalle, por usuario, stream, crear, borrar, upload-urls |
| Playlists | CRUD, tracks de la playlist, add/remove track, upload-picture |
| Users | listar/buscar, detalle, crear |
Cliente tipado en $lib/server/api.ts (openapi-fetch, estilo ErrorOr). Consumir en
load/actions server, nunca desde cliente. Tipos en src/lib/api/schema.d.ts.