- play_winner acepta device_id del formulario y verifica que el
dispositivo exista y no sea restringido antes de reproducir
- corrige construcción del URI según spotify_type del ganador
(antes siempre usaba spotify:playlist: independiente del tipo)
- errores se muestran en la página admin en lugar de HTTPException cruda
- template sincroniza device_id activo al campo oculto del formulario
- dispositivos restringidos se marcan en el selector del admin
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
El contenedor corría en UTC causando que la ventana horaria no
coincidiera con la hora local. Se agrega TZ en docker-compose y se
muestra la hora actual del servidor en el panel de votación.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
El parámetro fields="name,description,images" causaba error en playlists
curadas de Spotify (ej. "This Is ..."), haciendo que el nombre cayera
al fallback con el spotify_id.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reemplaza los bind mounts individuales de cantina.db y .spotify_cache
por un único directorio ./data/ montado en /app/data. El entrypoint
crea el directorio y los archivos vacíos si no existen, evitando que
Docker los cree como directorios al hacer un despliegue limpio.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nuevo endpoint GET /admin/status devuelve si el usuario está logueado como admin
- Navbar muestra botón "Admin" que lleva a /admin/login si no hay sesión,
o "⚙ Admin" → /admin/playlists si ya está autenticado
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>