Files
Musify/web-player/docs/paginas.md
T
Admin fbb102ffbd Consolidate auth routes under /auth and rename /u to /user
Moves the login screen from /login to /auth, logout from /logout to
/auth/logout (alongside the existing /auth/login and /auth/callback
endpoints), and the public profile route from /u/[id] to /user/[id].

AUTH_REDIRECT_URI and AUTH_POST_LOGOUT_URI already point at
/auth/callback and / respectively, so no Zitadel config change is
needed for the auth move.
2026-09-22 14:20:46 +02:00

7.8 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.css paleta + color.ts acento/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 exponer GET /me/recently-played?limit= (o /users/{id}/recently-played) devolviendo pistas ordenadas por playedAt desc, sin duplicados. El front lo cargaría en un load y lo pasaría al store en vez de recentlyPlayed.
  • Playlists por última escucha: añadir lastPlayedAt a la playlist (hoy el schema solo tiene createdAt/updatedAt) y permitir ordenar GET /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 TrackApplicationResponse no 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 ⬜
  auth  auth/login  auth/logout  auth/callback  Auth (página + 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)

/auth es la pantalla de login de Musify; sus botones llevan a /auth/login, que inicia el flujo OIDC de Zitadel y redirige. ?mode=register arranca en registro; ?returnTo= vuelve a la ruta pedida tras entrar. /auth/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):

  1. POST /tracks/upload-urls → URLs presignadas para portada y audio + intentIds.
  2. PUT de cada archivo a su URL presignada (subida directa al almacenamiento).
  3. POST /tracks con title, pictureIntentId, audioIntentId.
  4. 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 /auth?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ía POST /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 /user/[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.