Documentation cleanup: remove outdated files, add API docs, update core documentation

This commit is contained in:
glenneth 2025-10-10 16:12:12 +03:00
parent da054c1ab9
commit 925a624bda
9 changed files with 974 additions and 694 deletions

484
docs/API-ENDPOINTS.org Normal file
View File

@ -0,0 +1,484 @@
#+TITLE: Asteroid Radio - API Endpoints Reference
#+AUTHOR: Glenn Thompson
#+DATE: 2025-10-10
* Overview
Asteroid Radio provides a comprehensive JSON API built with Radiance's =define-api= framework. All API endpoints return JSON responses and follow RESTful conventions.
** Base URL
All API endpoints are prefixed with =/api/asteroid/=
** Authentication
Protected endpoints require user authentication via session cookies. Unauthenticated requests to protected endpoints will return an error response.
** Response Format
All API responses follow this structure:
#+BEGIN_SRC json
{
"status": "success" | "error",
"message": "Human-readable message",
"data": { ... } // Optional, endpoint-specific data
}
#+END_SRC
* Status Endpoints
** GET /api/asteroid/status
Get server status and system information.
*** Authentication
Not required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"server": "asteroid-radio",
"version": "1.0",
"uptime": 3600
}
#+END_SRC
** GET /api/asteroid/auth-status
Check current authentication status.
*** Authentication
Not required
*** Response
#+BEGIN_SRC json
{
"loggedIn": true,
"username": "admin",
"role": "admin"
}
#+END_SRC
** GET /api/asteroid/icecast-status
Get Icecast streaming server status and current track information.
*** Authentication
Not required
*** Response
#+BEGIN_SRC json
{
"icestats": {
"source": {
"title": "Artist - Track Name",
"listeners": 5,
"genre": "Electronic",
"bitrate": 128
}
}
}
#+END_SRC
* Track Endpoints
** GET /api/asteroid/tracks
Get list of all tracks in the music library.
*** Authentication
Required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"tracks": [
{
"id": "track-id-123",
"title": "Track Name",
"artist": "Artist Name",
"album": "Album Name",
"duration": 245,
"format": "mp3"
}
]
}
#+END_SRC
** GET /api/asteroid/admin/tracks
Get administrative track listing (admin only).
*** Authentication
Required (Admin role)
*** Response
Same as =/api/asteroid/tracks= but includes additional metadata for administration.
* Player Control Endpoints
** GET /api/asteroid/player/status
Get current player status.
*** Authentication
Required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"player": {
"state": "playing" | "paused" | "stopped",
"currentTrack": {
"id": "track-id-123",
"title": "Track Name",
"artist": "Artist Name"
},
"position": 45,
"duration": 245
}
}
#+END_SRC
** POST /api/asteroid/player/play
Play a specific track.
*** Authentication
Required
*** Parameters
- =track-id= (required) - ID of the track to play
*** Example Request
#+BEGIN_SRC bash
curl -X POST http://localhost:8080/api/asteroid/player/play \
-d "track-id=track-id-123"
#+END_SRC
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Playing track",
"player": {
"state": "playing",
"currentTrack": { ... }
}
}
#+END_SRC
** POST /api/asteroid/player/pause
Pause current playback.
*** Authentication
Required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Playback paused",
"player": {
"state": "paused"
}
}
#+END_SRC
** POST /api/asteroid/player/stop
Stop current playback.
*** Authentication
Required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Playback stopped",
"player": {
"state": "stopped"
}
}
#+END_SRC
** POST /api/asteroid/player/resume
Resume paused playback.
*** Authentication
Required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Playback resumed",
"player": {
"state": "playing"
}
}
#+END_SRC
* Playlist Endpoints
** GET /api/asteroid/playlists
Get all playlists for the current user.
*** Authentication
Required
*** Response
#+BEGIN_SRC json
{
"status": "success",
"playlists": [
{
"id": "playlist-id-123",
"name": "My Playlist",
"description": "Favorite tracks",
"trackCount": 15,
"created": "2025-10-10T12:00:00Z"
}
]
}
#+END_SRC
** POST /api/asteroid/playlists/create
Create a new playlist.
*** Authentication
Required
*** Parameters
- =name= (required) - Playlist name
- =description= (optional) - Playlist description
*** Example Request
#+BEGIN_SRC bash
curl -X POST http://localhost:8080/api/asteroid/playlists/create \
-d "name=My Playlist&description=Favorite tracks"
#+END_SRC
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Playlist created successfully",
"playlist": {
"id": "playlist-id-123",
"name": "My Playlist",
"description": "Favorite tracks"
}
}
#+END_SRC
** GET /api/asteroid/playlists/get
Get details of a specific playlist.
*** Authentication
Required
*** Parameters
- =playlist-id= (required) - ID of the playlist
*** Example Request
#+BEGIN_SRC bash
curl "http://localhost:8080/api/asteroid/playlists/get?playlist-id=playlist-id-123"
#+END_SRC
*** Response
#+BEGIN_SRC json
{
"status": "success",
"playlist": {
"id": "playlist-id-123",
"name": "My Playlist",
"description": "Favorite tracks",
"tracks": [
{
"id": "track-id-123",
"title": "Track Name",
"artist": "Artist Name"
}
]
}
}
#+END_SRC
** POST /api/asteroid/playlists/add-track
Add a track to a playlist.
*** Authentication
Required
*** Parameters
- =playlist-id= (required) - ID of the playlist
- =track-id= (required) - ID of the track to add
*** Example Request
#+BEGIN_SRC bash
curl -X POST http://localhost:8080/api/asteroid/playlists/add-track \
-d "playlist-id=playlist-id-123&track-id=track-id-456"
#+END_SRC
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Track added to playlist"
}
#+END_SRC
* Admin Endpoints
** POST /api/asteroid/admin/scan-library
Scan the music library for new tracks.
*** Authentication
Required (Admin role)
*** Response
#+BEGIN_SRC json
{
"status": "success",
"message": "Library scan initiated",
"tracksFound": 42
}
#+END_SRC
* Error Responses
All endpoints may return error responses in this format:
#+BEGIN_SRC json
{
"status": "error",
"message": "Description of the error"
}
#+END_SRC
** Common HTTP Status Codes
- =200= - Success
- =400= - Bad Request (missing or invalid parameters)
- =401= - Unauthorized (authentication required)
- =403= - Forbidden (insufficient permissions)
- =404= - Not Found (resource doesn't exist)
- =500= - Internal Server Error
* Testing API Endpoints
** Using curl
#+BEGIN_SRC bash
# Get server status
curl http://localhost:8080/api/asteroid/status
# Get auth status
curl http://localhost:8080/api/asteroid/auth-status
# Get tracks (requires authentication)
curl -b cookies.txt http://localhost:8080/api/asteroid/tracks
# Play a track
curl -X POST -b cookies.txt http://localhost:8080/api/asteroid/player/play \
-d "track-id=123"
#+END_SRC
** Using the Test Suite
The project includes a comprehensive test suite:
#+BEGIN_SRC bash
./test-server.sh
#+END_SRC
See =docs/TESTING.org= for details.
* Browser Detection
API endpoints support a =browser= parameter for dual usage (API + browser):
#+BEGIN_SRC bash
# API usage - returns JSON
curl -X POST http://localhost:8080/api/asteroid/playlists/create \
-d "name=Test"
# Browser usage - redirects to page
curl -X POST http://localhost:8080/api/asteroid/playlists/create \
-d "name=Test&browser=true"
#+END_SRC
When =browser=true= is passed, endpoints will redirect to appropriate pages instead of returning JSON.
* Integration Examples
** JavaScript/Fetch API
#+BEGIN_SRC javascript
// Get tracks
fetch('/api/asteroid/tracks')
.then(response => response.json())
.then(data => {
console.log('Tracks:', data.tracks);
});
// Play a track
fetch('/api/asteroid/player/play', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'track-id=123'
})
.then(response => response.json())
.then(data => {
console.log('Now playing:', data.player.currentTrack);
});
#+END_SRC
** Python
#+BEGIN_SRC python
import requests
# Get server status
response = requests.get('http://localhost:8080/api/asteroid/status')
print(response.json())
# Create playlist (with session)
session = requests.Session()
# ... login first ...
response = session.post(
'http://localhost:8080/api/asteroid/playlists/create',
data={'name': 'My Playlist', 'description': 'Test'}
)
print(response.json())
#+END_SRC
* Rate Limiting
API endpoints implement rate limiting to prevent abuse. Excessive requests may result in temporary blocking.
* Future Enhancements
Planned API improvements:
- WebSocket support for real-time updates
- Pagination for large result sets
- Advanced search and filtering
- Batch operations
- API versioning
- OAuth2 authentication option

View File

@ -1,10 +1,16 @@
#+TITLE: Asteroid Radio - Interface Reference
#+AUTHOR: Interface Team
#+DATE: 2025-10-03
#+AUTHOR: Glenn Thompson
#+DATE: 2025-10-10
* Current Interfaces
Asteroid Radio currently operates as a Docker-based streaming platform using Icecast2 and Liquidsoap. The system provides streaming interfaces and control mechanisms rather than a traditional REST API.
Asteroid Radio provides multiple interfaces for different purposes:
1. **REST API** - JSON API for web application and programmatic access (see [[file:API-ENDPOINTS.org][API Endpoints Reference]])
2. **Streaming Endpoints** - Direct audio stream access via Icecast2
3. **Icecast Admin** - Web-based streaming server administration
4. **Liquidsoap Control** - Telnet interface for DJ controls
5. **Docker Management** - Container orchestration and management
** Available Interfaces
@ -147,22 +153,38 @@ cp ~/path/to/music/*.flac docker/music/
echo "request.queue" | nc localhost 1234
#+END_SRC
* Future Development
* REST API
** Potential REST API
A REST API may be developed in the future if deemed necessary for:
- **Web Interface**: Browser-based control panel
- **Mobile Applications**: Native mobile apps
- **Third-party Integration**: External service integration
- **User Management**: Account and playlist management
Asteroid Radio includes a comprehensive REST API built with Radiance's =define-api= framework.
Such an API would likely be built using the RADIANCE Common Lisp web framework and would provide endpoints for:
- Track and playlist management
- User authentication and profiles
- Streaming control and statistics
- System administration
** API Documentation
However, the current Docker streaming setup provides all essential functionality through existing interfaces (Icecast admin, Liquidsoap telnet, and direct stream access).
For complete REST API documentation, see **[[file:API-ENDPOINTS.org][API Endpoints Reference]]**.
The API provides:
- **Authentication & User Management** - Login, registration, user administration
- **Track Management** - Browse and search music library
- **Playlist Operations** - Create, manage, and play playlists
- **Player Control** - Play, pause, stop, resume playback
- **Admin Functions** - Library scanning, system management
** Quick API Examples
#+BEGIN_SRC bash
# Get server status
curl http://localhost:8080/api/asteroid/status
# Get authentication status
curl http://localhost:8080/api/asteroid/auth-status
# Get Icecast streaming status
curl http://localhost:8080/api/asteroid/icecast-status
# Get tracks (requires authentication)
curl -b cookies.txt http://localhost:8080/api/asteroid/tracks
#+END_SRC
See **[[file:API-ENDPOINTS.org][API Endpoints Reference]]** for complete documentation of all 15+ endpoints.
* Getting Help
@ -172,5 +194,4 @@ For support with interfaces and streaming setup:
- Join our IRC chat room: **#asteroid.music** on **irc.libera.chat**
- Submit issues with detailed system information
This interface reference covers all currently available methods for interacting with Asteroid Radio's streaming infrastructure.
#+END_SRC
This interface reference covers the streaming infrastructure interfaces. For the REST API, see **[[file:API-ENDPOINTS.org][API Endpoints Reference]]**.

View File

@ -1,76 +0,0 @@
#+TITLE: CLIP Template Refactoring - Complete
#+AUTHOR: Asteroid Radio Development Team
#+DATE: 2025-10-04
* Overview
Complete refactoring of template rendering system to use CLIP (Common Lisp HTML Processor) machinery properly, eliminating code duplication and establishing a centralized template management system.
* What Was Completed
** Centralized Template Utilities
- Created =template-utils.lisp= with core rendering functions
- Implemented =render-template-with-plist= for consistent template rendering
- Added template caching for improved performance
- Defined CLIP attribute processors (=data-text=) in centralized location
** Template Refactoring
All pages now use the centralized rendering system:
- Front page (=/=)
- Admin dashboard (=/admin=)
- User management (=/admin/users=)
- Web player (=/player=)
** Files Modified
- =asteroid.asd= - Added template-utils.lisp to system definition
- =asteroid.lisp= - Refactored all define-page forms to use new system
- =template-utils.lisp= - New file with centralized utilities
- All =.chtml= template files - Updated to use CLIP processors
* Technical Implementation
** Template Caching
#+BEGIN_SRC lisp
(defvar *template-cache* (make-hash-table :test 'equal)
"Cache for compiled templates")
(defun get-cached-template (template-name)
"Get template from cache or load and cache it"
(or (gethash template-name *template-cache*)
(setf (gethash template-name *template-cache*)
(load-template template-name))))
#+END_SRC
** Rendering Function
#+BEGIN_SRC lisp
(defun render-template-with-plist (template-name &rest plist)
"Render a template with a property list of values"
(let ((template (get-cached-template template-name)))
(clip:process-to-string template plist)))
#+END_SRC
** CLIP Attribute Processors
#+BEGIN_SRC lisp
(clip:define-attribute-processor data-text (node value)
"Process data-text attributes for dynamic content"
(plump:clear node)
(plump:make-text-node node (clip:clipboard value)))
#+END_SRC
* Benefits
1. *Code Reduction* - Eliminated duplicate template loading code across all routes
2. *Performance* - Template caching reduces file I/O
3. *Maintainability* - Single source of truth for template rendering
4. *Consistency* - All pages use the same rendering mechanism
5. *Type Safety* - Centralized error handling for template operations
* Documentation
Complete documentation available in:
- =docs/CLIP-REFACTORING.org= - Detailed technical documentation
- =template-utils.lisp= - Inline code documentation
* Status: ✅ COMPLETE
All template refactoring tasks completed successfully. System is production-ready.

View File

@ -1,6 +1,6 @@
#+TITLE: Asteroid Radio - Development Guide
#+AUTHOR: Development Team
#+DATE: 2025-10-03
#+AUTHOR: Glenn Thompson
#+DATE: 2025-10-10
* Development Setup
@ -11,13 +11,46 @@
- Quicklisp package manager
- Git version control
- Docker and Docker Compose
- taglib for metadata extraction (for local development)
- PostgreSQL (for production database)
- taglib for metadata extraction
*** Lisp Dependencies (via Quicklisp)
All Lisp dependencies are automatically installed via Quicklisp when you run =(ql:quickload :asteroid)=:
**** Core Framework
- =radiance= - Web framework and module system
- =slynk= - SLIME/SLY development server
- =i-log4cl= - Logging interface
- =r-clip= - CLIP template processor (Radiance)
- =r-simple-rate= - Rate limiting (Radiance)
- =r-simple-profile= - User profiles (Radiance)
- =r-data-model= - Data modeling (Radiance)
**** Utilities & Libraries
- =lass= - CSS preprocessing in Lisp
- =cl-json= - JSON encoding/decoding
- =alexandria= - Common Lisp utilities
- =local-time= - Time and date handling
- =taglib= - Audio metadata extraction
- =ironclad= - Cryptographic functions
- =babel= - Character encoding conversion
- =cl-fad= - File and directory operations
- =bordeaux-threads= - Portable threading
- =drakma= - HTTP client
- =usocket= - Universal socket library
- =cl-ppcre= - Perl-compatible regular expressions
**** Radiance Interfaces
- =:auth= - Authentication interface
- =:database= - Database interface
- =:user= - User management interface
*** Ubuntu/Debian Installation
#+BEGIN_SRC bash
# Install system packages
sudo apt update
sudo apt install sbcl git docker.io docker compose
sudo apt install sbcl git docker.io docker-compose postgresql libtagc0-dev
# Add user to docker group
sudo usermod -a -G docker $USER
@ -26,6 +59,9 @@ sudo usermod -a -G docker $USER
# Install Quicklisp (if not already installed)
curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp --eval "(quicklisp-quickstart:install)" --quit
# Note: PostgreSQL runs in Docker for development
# See docs/POSTGRESQL-SETUP.org for database configuration
#+END_SRC
** Project Setup
@ -80,6 +116,9 @@ sbcl --eval "(ql:quickload :asteroid)" --eval "(asteroid:start-server)"
*** Development URLs
- *Web Interface*: http://localhost:8080/asteroid/
- *Admin Panel*: http://localhost:8080/asteroid/admin
- *User Management*: http://localhost:8080/asteroid/admin/users
- *Web Player*: http://localhost:8080/asteroid/player
- *API Base*: http://localhost:8080/api/asteroid/
- *Live Stream*: http://localhost:8000/asteroid.mp3
- *Icecast Admin*: http://localhost:8000/admin/ (admin/asteroid_admin_2024)
@ -121,7 +160,7 @@ cp -r /path/to/your/music/* docker/music/
ln -s /path/to/existing/music docker/music/collection
# Trigger library scan via API
curl -X POST http://localhost:8080/asteroid/api/scan-library
curl -X POST http://localhost:8080/api/asteroid/admin/scan-library
#+END_SRC
** Code Organization
@ -157,10 +196,65 @@ curl -X POST http://localhost:8080/asteroid/api/scan-library
(gethash "_id" track-record)
#+END_SRC
*** Template Development
- Use CLIP templating with =data-text= attributes
*** Template Development with CLIP
Asteroid Radio uses CLIP (Common Lisp HTML Processor) for templating. Templates are in the =template/= directory.
**** Custom =data-text= Attribute Processor
We define a custom CLIP attribute processor in =template-utils.lisp= for dynamic text replacement:
#+BEGIN_SRC lisp
;; Defined in template-utils.lisp
(clip:define-attribute-processor data-text (node value)
"Process data-text attribute - replaces node text content with clipboard value"
(plump:clear node)
(plump:make-text-node node (clip:clipboard value)))
#+END_SRC
**** Using =data-text= in Templates
In your HTML templates (=.chtml= files):
#+BEGIN_SRC html
<!-- The data-text attribute gets replaced with the value from the plist -->
<h1 data-text="page-title">Default Title</h1>
<span data-text="username">Guest</span>
<p data-text="status-message">Loading...</p>
#+END_SRC
**** Rendering Templates from Lisp
In your route handlers:
#+BEGIN_SRC lisp
(define-page my-page #@"/my-page" ()
(render-template-with-plist "my-template"
:page-title "My Page"
:username (user:username (auth:current))
:status-message "Ready"))
#+END_SRC
**** How It Works
1. =render-template-with-plist= passes keyword arguments to CLIP
2. CLIP processes the template and finds =data-text= attributes
3. The custom processor replaces the node's text with the value from the "clipboard" (keyword args)
4. Default text in the HTML is replaced with dynamic content
**** CLIP Documentation
- **CLIP GitHub**: https://github.com/Shinmera/clip
- **Attribute Processors**: Custom processors extend CLIP's functionality
- **Standard CLIP**: Uses =lquery= for more complex DOM manipulation
- **Our Approach**: Simple =data-text= processor for most use cases
**** Template Development Tips
- Keep templates in =template/= directory
- Test template changes with browser refresh
- Use =data-text= for simple text replacement
- Test template changes with browser refresh (templates are cached)
- Clear cache during development: =(clear-template-cache)=
- Maintain responsive design principles
*** CSS Development with LASS
@ -197,14 +291,34 @@ docker compose logs liquidsoap
#+END_SRC
*** API Testing
#+BEGIN_SRC bash
# Test track listing
curl http://localhost:8080/asteroid/api/tracks
# Test file processing
curl -X POST http://localhost:8080/asteroid/api/copy-files
Asteroid Radio includes a comprehensive automated test suite:
#+BEGIN_SRC bash
# Run full test suite
./test-server.sh
# Run with verbose output
./test-server.sh -v
# Test specific endpoints manually
curl http://localhost:8080/api/asteroid/status
curl http://localhost:8080/api/asteroid/tracks
curl -X POST http://localhost:8080/api/asteroid/player/play -d "track-id=123"
#+END_SRC
See [[file:TESTING.org][Testing Guide]] for complete documentation.
*** API Endpoint Structure
All API endpoints use Radiance's =define-api= macro and follow this pattern:
- Base URL: =/api/asteroid/=
- Response format: JSON
- Authentication: Session-based for protected endpoints
See [[file:API-ENDPOINTS.org][API Endpoints Reference]] for complete API documentation.
** Debugging
*** Common Development Issues

View File

@ -75,19 +75,26 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack
## 🚀 Features
### Current Features
- ✅ **User Authentication** - Registration, login, profiles
- ✅ **Music Streaming** - Multiple quality formats
- ✅ **Web Player** - Browser-based music player
- ✅ **User Authentication** - Registration, login, profiles, role-based access
- ✅ **User Management** - Admin interface for user administration
- ✅ **Music Library** - Track management with pagination and search
- ✅ **User Playlists** - Create, manage, and play personal music collections
- ✅ **Web Player** - Browser-based player with queue management
- ✅ **REST API** - Comprehensive JSON API with 15+ endpoints
- ✅ **Music Streaming** - Multiple quality formats (MP3, AAC)
- ✅ **Rate Limiting** - Anti-abuse protection
- ✅ **Docker Integration** - Icecast2/Liquidsoap streaming
- ✅ **Docker Integration** - Icecast2/Liquidsoap streaming infrastructure
- ✅ **PostgreSQL Database** - Persistent data storage
- ✅ **Liquidsoap DJ Controls** - Telnet interface for live control
- ✅ **Responsive Design** - Works on desktop and mobile
- ✅ **Automated Testing** - Comprehensive test suite
### Planned Features
- 🔄 **User Playlists** - Personal music collections
- 🔄 **Social Features** - Sharing and discovery
- 🔄 **Advanced Player** - Queue management, crossfade
- 🔄 **Admin Interface** - System management tools
- 🔄 **API Extensions** - Mobile app support
- 🔄 **Social Features** - Playlist sharing and discovery
- 🔄 **Advanced Search** - Full-text search and filtering
- 🔄 **Mobile App** - Native mobile applications
- 🔄 **WebSocket Support** - Real-time updates
- 🔄 **Analytics** - Listening statistics and insights
## 🔮 Vision

View File

@ -1,6 +1,6 @@
#+TITLE: Asteroid Radio - Documentation Index
#+AUTHOR: Documentation Team
#+DATE: 2025-10-03
#+AUTHOR: Glenn Thompson
#+DATE: 2025-10-10
* Welcome to Asteroid Radio Documentation
@ -30,17 +30,44 @@ Complete guide to the Docker-based streaming infrastructure using Icecast2 and L
*** [[file:DEVELOPMENT.org][Development Guide]]
Development environment setup, contributing guidelines, coding standards, and debugging procedures for developers working on Asteroid Radio.
*** [[file:API-ENDPOINTS.org][API Endpoints Reference]]
Complete documentation of all REST API endpoints including authentication, tracks, playlists, player control, and admin functions.
*** [[file:API-REFERENCE.org][Interface Reference]]
Documentation of all available interfaces including streaming endpoints, Icecast admin interface, Liquidsoap telnet control, and Docker management commands.
Documentation of streaming endpoints, Icecast admin interface, Liquidsoap telnet control, and Docker management commands.
*** [[file:TESTING.org][Testing Guide]]
Automated testing suite documentation, test script usage, and manual testing procedures.
** Feature Documentation
*** [[file:POSTGRESQL-SETUP.org][PostgreSQL Setup]]
Database configuration, schema design, and migration guide for PostgreSQL backend.
*** [[file:PLAYLIST-SYSTEM.org][Playlist System]]
User playlist functionality including creation, management, and playback features.
*** [[file:USER-MANAGEMENT-SYSTEM.org][User Management]]
User administration system with role management, authentication, and access control.
*** [[file:TRACK-PAGINATION-SYSTEM.org][Track Pagination]]
Pagination system for efficient browsing of large music libraries.
* Current System Status
** What's Working Now
- **Web Application**: Full-featured web interface with authentication
- **REST API**: JSON API with 15+ endpoints for programmatic access
- **User Management**: Registration, login, roles, and profiles
- **Music Library**: Track management with pagination and search
- **Playlists**: User playlists with creation and playback
- **Web Player**: Browser-based audio player with queue management
- **Docker Streaming Infrastructure**: Icecast2 + Liquidsoap containers
- **Three Quality Streams**: 128kbps MP3, 96kbps AAC, 64kbps MP3
- **Admin Interface**: Icecast web admin at http://localhost:8000/admin/
- **Telnet Control**: Liquidsoap control via telnet localhost:1234
- **Liquidsoap DJ Controls**: Telnet control via localhost:1234
- **Professional Features**: Crossfading, normalization, metadata support
- **PostgreSQL Database**: Persistent data storage with full CRUD operations
** Stream URLs (when running)
- **High Quality MP3**: http://localhost:8000/asteroid.mp3 (128kbps)
@ -56,8 +83,10 @@ Documentation of all available interfaces including streaming endpoints, Icecast
** Developers
1. Review the **[[file:DEVELOPMENT.org][Development Guide]]** for setup procedures
2. Check the **[[file:API-REFERENCE.org][Interface Reference]]** for available controls
3. Join our IRC channel: **#asteroid.music** on **irc.libera.chat**
2. Check the **[[file:API-ENDPOINTS.org][API Endpoints Reference]]** for REST API documentation
3. Review the **[[file:API-REFERENCE.org][Interface Reference]]** for streaming controls
4. See **[[file:TESTING.org][Testing Guide]]** for automated testing
5. Join our IRC channel: **#asteroid.music** on **irc.libera.chat**
** System Administrators
1. Follow the **[[file:INSTALLATION.org][Installation Guide]]** production deployment section
@ -112,5 +141,5 @@ For detailed technical information, see the **[[file:PROJECT-OVERVIEW.org][Proje
---
*Last Updated: 2025-10-03*
*Documentation Version: 1.0*
*Last Updated: 2025-10-10*
*Documentation Version: 2.0*

View File

@ -1,327 +0,0 @@
#+TITLE: Development Session Summary - October 4, 2025
#+AUTHOR: Asteroid Radio Development Team
#+DATE: 2025-10-04
* Session Overview
Massive development session completing the Templates section of the TODO list and implementing comprehensive web player features.
* Major Accomplishments
** 1. CLIP Template Refactoring ✅ COMPLETE
- Centralized template rendering system
- Template caching for performance
- Eliminated code duplication across all routes
- Documentation: =docs/CLIP-TEMPLATE-REFACTORING.org=
** 2. User Management System ✅ COMPLETE
- Dedicated /admin/users page
- User creation, role management, activation
- Comprehensive API endpoints
- Full testing suite
- Documentation: =docs/USER-MANAGEMENT-SYSTEM.org=
** 3. Track Pagination ✅ COMPLETE
- Admin dashboard pagination (10/20/50/100 per page)
- Web player pagination (10/20/50 per page)
- Smart navigation controls
- Works with search and sort
- Documentation: =docs/TRACK-PAGINATION-SYSTEM.org=
** 4. Playlist System ⚠️ PARTIAL (Database Limited)
- Create empty playlists ✅
- View playlists ✅
- Save queue as playlist ❌ (tracks don't persist - db:update fails)
- Load playlists ❌ (playlists are empty - no tracks saved)
- Audio playback fixed (added get-track-by-id with type handling) ✅
- Database limitations documented
- Documentation: =docs/PLAYLIST-SYSTEM.org=
** 5. UI Fixes and Improvements ✅ COMPLETE
- Fixed live stream indicators (green)
- Corrected stream quality display
- Verified Now Playing functionality
- Added missing API endpoints (get-track-by-id)
- Documentation: =docs/UI-FIXES-AND-IMPROVEMENTS.org=
** 6. PostgreSQL Setup ✅ COMPLETE (Ready for Fade)
- PostgreSQL added to docker-compose.yml
- Complete database schema (users, tracks, playlists, playlist_tracks, sessions)
- Persistent volume configuration (postgres-data)
- Radiance PostgreSQL configuration file
- Database initialization script with indexes and constraints
- Comprehensive setup documentation
- Documentation: =docs/POSTGRESQL-SETUP.org=
** 7. Streaming Infrastructure ✅ COMPLETE
- All 3 streams working (MP3 128k, AAC 96k, MP3 64k)
- Fixed AAC stream (Docker caching issue resolved)
- Liquidsoap playlist.safe() for faster startup
- NAS music mount configured
- Small dataset streaming successfully
* Statistics
** Code Changes
- Files created: 10+ new files
- Files modified: 20+ files
- Lines of code added: ~2500+
- Documentation pages: 6 comprehensive org files
- Database schema: Complete PostgreSQL schema
** Features Completed
- Template refactoring: 100%
- User management: 100%
- Track pagination: 100%
- Playlist system: 40% (limited by database - create/view only)
- UI fixes: 100%
- PostgreSQL setup: 100%
- Streaming: 100% (3 streams operational)
** Testing
- API endpoints tested: 10+
- User scenarios tested: 20+
- Browser compatibility: Verified
- Performance: Optimized
* Technical Achievements
** Architecture Improvements
- Centralized template rendering
- Consistent error handling
- Proper authentication/authorization
- RESTful API design
- Client-side pagination
** Database Work
- User management schema
- Playlist schema (with junction table for many-to-many)
- Track management
- Sessions table for Radiance
- Identified Radiance DB limitations (UPDATE queries fail)
- Complete PostgreSQL schema designed
- Database initialization script created
- Persistent volume configuration
** Frontend Enhancements
- Pagination controls
- Dynamic quality switching
- Real-time Now Playing updates
- Queue management
- Playlist UI
* Known Issues & Future Work
** Database Backend Limitations
Current Radiance database backend has issues:
- UPDATE queries don't persist reliably
- Type handling inconsistencies (scalars vs lists)
- Query matching problems
*** Solution: PostgreSQL Migration
- Proper UPDATE support
- Consistent data types
- Full CRUD operations
- Better performance
** Playlist Limitations (Requires PostgreSQL)
- Cannot save tracks to playlists (db:update fails)
- Cannot load playlists (no tracks persist)
- Cannot add tracks to existing playlists
- Cannot modify playlist metadata
- Root cause: Radiance default DB doesn't persist UPDATE operations
- Workaround: None available - PostgreSQL required for full functionality
* Files Created
** New Source Files
- =template-utils.lisp= - Template rendering utilities
- =playlist-management.lisp= - Playlist CRUD operations
- =template/users.chtml= - User management page
- =test-user-api.sh= - API testing script
- =config/radiance-postgres.lisp= - PostgreSQL configuration
- =docker/init-db.sql= - Database initialization script
- =asteroid-scripts/setup-remote-music.sh= - NAS mount script (updated)
** New Documentation
- =docs/CLIP-TEMPLATE-REFACTORING.org=
- =docs/USER-MANAGEMENT-SYSTEM.org=
- =docs/TRACK-PAGINATION-SYSTEM.org=
- =docs/PLAYLIST-SYSTEM.org=
- =docs/UI-FIXES-AND-IMPROVEMENTS.org=
- =docs/POSTGRESQL-SETUP.org=
- =docs/SESSION-SUMMARY-2025-10-04.org= (this file)
* TODO Status Update
** ✅ COMPLETED
- [X] Templates: move template hydration into CLIP machinery [4/4]
- [X] Admin Dashboard [2/2]
- [X] System Status [4/4]
- [X] Music Library Management [3/3]
- [X] Track Management (Pagination complete)
- [X] Player Control
- [X] User Management
- [X] Live Stream
- [X] Now Playing
- [X] Front Page [3/3]
- [X] Station Status
- [X] Live Stream
- [X] Now Playing
- [X] Web Player [5/6] ⚠️ MOSTLY COMPLETE
- [X] Live Radio Stream
- [X] Now Playing
- [X] Personal Track Library (with pagination)
- [X] Audio Player (fixed with get-track-by-id)
- [ ] Playlists (PARTIAL - create/view only, no track persistence)
- [X] Play Queue
** ✅ READY FOR FADE
- [X] PostgreSQL Docker setup complete
- [X] Database schema designed
- [X] Initialization script created
- [X] Radiance configuration prepared
** 🔄 PENDING (Fade's Tasks)
- [ ] Server runtime configuration
- [ ] Database [1/3]
- [X] PostgreSQL Docker container (ready to start)
- [ ] Radiance PostgreSQL adapter configuration
- [ ] Data migration from current DB
* Commit Information
** Branch
=feature/clip-templating=
** Commits Made
1. Initial CLIP refactoring and template utilities
2. User management system complete
3. Track pagination implementation
4. Playlist system (partial - database limited)
5. UI fixes and improvements
6. Audio playback fixes (get-track-by-id)
7. PostgreSQL setup complete
8. Streaming fixes (AAC restored)
9. Documentation and session summary
** Files to Commit
#+BEGIN_SRC bash
git add -A
git commit -m "Complete Templates section: CLIP refactoring, user management, pagination, playlists, UI fixes
✅ CLIP Template Refactoring:
- Centralized template rendering in template-utils.lisp
- Template caching for performance
- Eliminated code duplication
✅ User Management:
- Dedicated /admin/users page
- User creation, roles, activation
- Comprehensive API endpoints
- Full test suite
✅ Track Pagination:
- Admin dashboard: 10/20/50/100 per page
- Web player: 10/20/50 per page
- Smart navigation controls
⚠️ Playlist System (PARTIAL):
- Create empty playlists ✅
- View playlists ✅
- Save/load playlists ❌ (database UPDATE fails)
- Audio playback fixed ✅
- Database limitations documented
✅ PostgreSQL Setup:
- Docker container configuration
- Complete database schema
- Persistent storage
- Radiance configuration
- Ready for Fade to integrate
✅ UI Fixes:
- Green live stream indicators
- Correct stream quality display
- Now Playing verified working
- Missing API endpoints added
📚 Documentation:
- 5 comprehensive org files
- Complete technical documentation
- Known issues documented
Note: Playlist editing requires PostgreSQL migration (Fade's task)"
#+END_SRC
* Next Steps
** For Fade
1. Review PostgreSQL setup (docker-compose.yml, init-db.sql)
2. Start PostgreSQL container: =cd docker && docker compose up -d postgres=
3. Configure Radiance PostgreSQL adapter
4. Migrate data from current database
5. Test playlist functionality with PostgreSQL
6. Update application code for PostgreSQL queries
** For Future Development
1. Playlist editing features (post-PostgreSQL)
2. Advanced playlist features (sharing, collaboration)
3. Liquidsoap playlist integration
4. Mobile responsive improvements
5. Additional API endpoints
* Performance Metrics
** Before Session
- Template loading: Duplicated code in every route
- Track display: All 64 tracks loaded at once
- No pagination
- No playlist system
- UI inconsistencies
** After Session
- Template loading: Centralized, cached
- Track display: 20 tracks per page (68% DOM reduction)
- Full pagination system
- Working playlist system
- Consistent UI across all pages
* Lessons Learned
** Database Backend
- Radiance default backend has limitations
- PostgreSQL migration is critical for advanced features
- Type handling needs careful consideration
- Manual filtering sometimes necessary
** Frontend Development
- Client-side pagination is efficient for moderate datasets
- Proper index management crucial for playback
- User feedback important (alerts, console logs)
- Progressive enhancement approach works well
** Testing
- API testing scripts invaluable
- Browser console debugging essential
- Server console logging helps diagnose issues
- Incremental testing catches issues early
* Status: ✅ SESSION COMPLETE
All planned features implemented and documented. Templates section 100% complete. System ready for PostgreSQL migration and advanced features.
** Total Time Investment
~10 hours of focused development
** Lines of Code
~2500+ lines added/modified
** Documentation
~2000+ lines of documentation
** Features Delivered
18+ major features completed
** Quality
Production-ready code with comprehensive documentation

271
docs/TESTING.org Normal file
View File

@ -0,0 +1,271 @@
#+TITLE: Asteroid Radio Testing Guide
#+AUTHOR: Glenn Thompson
#+DATE: 2025-10-08
* Overview
This document describes the automated testing system for Asteroid Radio.
* Test Script
The =test-server.sh= script provides comprehensive testing of all server endpoints and functionality.
** Features
- Tests all API endpoints (15 endpoints)
- Tests HTML page rendering (5 pages)
- Tests static file serving
- Validates JSON response format
- Color-coded output for easy reading
- Detailed pass/fail reporting
- Verbose mode for debugging
** Usage
*** Basic Usage
#+BEGIN_SRC bash
# Test local server (default: http://localhost:8080)
./test-server.sh
# Verbose mode (shows response details)
./test-server.sh -v
# Test remote server
./test-server.sh -u http://example.com
# Show help
./test-server.sh -h
#+END_SRC
*** Environment Variables
#+BEGIN_SRC bash
# Set base URL via environment
ASTEROID_URL=http://example.com ./test-server.sh
# Enable verbose mode
VERBOSE=1 ./test-server.sh
#+END_SRC
** Test Categories
*** 1. Server Status
- Server accessibility check
- API response format validation
*** 2. Status Endpoints
- =/api/asteroid/status= - Server status
- =/api/asteroid/auth-status= - Authentication status
- =/api/asteroid/icecast-status= - Icecast streaming status
*** 3. Track Endpoints
- =/api/asteroid/tracks= - Track listing
- =/api/asteroid/admin/tracks= - Admin track listing
*** 4. Player Control Endpoints
- =/api/asteroid/player/status= - Player status
- =/api/asteroid/player/play= - Play track
- =/api/asteroid/player/pause= - Pause playback
- =/api/asteroid/player/stop= - Stop playback
- =/api/asteroid/player/resume= - Resume playback
*** 5. Playlist Endpoints
- =/api/asteroid/playlists= - Playlist listing
- =/api/asteroid/playlists/create= - Create playlist
- =/api/asteroid/playlists/add-track= - Add track to playlist
- =/api/asteroid/playlists/get= - Get playlist details
*** 6. Admin Endpoints
- =/api/asteroid/admin/tracks= - Admin track listing
- =/api/asteroid/admin/scan-library= - Library scan
*** 7. HTML Pages
- =/asteroid/= - Front page
- =/asteroid/admin= - Admin dashboard
- =/asteroid/player= - Web player
- =/asteroid/profile= - User profile
- =/asteroid/register= - Registration page
*** 8. Static Files
- CSS files (=/asteroid/static/*.css=)
- JavaScript files (=/asteroid/static/js/*.js=)
** Example Output
#+BEGIN_EXAMPLE
╔═══════════════════════════════════════╗
║ Asteroid Radio Server Test Suite ║
╔═══════════════════════════════════════╗
INFO: Testing server at: http://localhost:8080
INFO: Verbose mode: 0
========================================
Checking Server Status
========================================
TEST: Server is accessible
✓ PASS: Server is running at http://localhost:8080
========================================
Testing API Response Format
========================================
TEST: API returns JSON format
✓ PASS: API returns JSON (not S-expressions)
========================================
Testing Status Endpoints
========================================
TEST: Server status endpoint
✓ PASS: Server status endpoint - Response contains 'asteroid-radio'
TEST: Authentication status endpoint
✓ PASS: Authentication status endpoint - Response contains 'loggedIn'
...
========================================
Test Summary
========================================
Tests Run: 25
Tests Passed: 25
Tests Failed: 0
✓ All tests passed!
#+END_EXAMPLE
** Exit Codes
- =0= - All tests passed
- =1= - One or more tests failed or server not accessible
** Requirements
*** Required
- =bash= - Shell script interpreter
- =curl= - HTTP client for testing endpoints
*** Optional
- =jq= - JSON processor for advanced JSON validation (recommended)
Install jq:
#+BEGIN_SRC bash
# Ubuntu/Debian
sudo apt install jq
# macOS
brew install jq
#+END_SRC
** Integration with CI/CD
The test script can be integrated into continuous integration pipelines:
#+BEGIN_SRC yaml
# Example GitHub Actions workflow
- name: Start Asteroid Server
run: ./asteroid &
- name: Wait for server
run: sleep 5
- name: Run tests
run: ./test-server.sh
#+END_SRC
** Extending the Tests
To add new tests, edit =test-server.sh= and add test functions:
#+BEGIN_SRC bash
test_my_new_feature() {
print_header "Testing My New Feature"
test_api_endpoint "/my-endpoint" \
"My endpoint description" \
"expected-field"
}
# Add to main() function
main() {
# ... existing tests ...
test_my_new_feature
# ...
}
#+END_SRC
** Troubleshooting
*** Server not accessible
- Ensure server is running: =./asteroid=
- Check server is on correct port: =8080=
- Verify firewall settings
*** Tests failing
- Run with verbose mode: =./test-server.sh -v=
- Check server logs for errors
- Verify database is initialized
- Ensure all dependencies are installed
*** JSON format issues
- Verify JSON API format is configured in =asteroid.lisp=
- Check =define-api-format json= is defined
- Ensure =*default-api-format*= is set to ="json"=
* Manual Testing Checklist
For features not covered by automated tests:
** Authentication
- [ ] Login with admin/asteroid123
- [ ] Logout functionality
- [ ] Session persistence
- [ ] Protected pages redirect to login
** Music Library
- [ ] Scan library adds tracks
- [ ] Track metadata displays correctly
- [ ] Audio streaming works
- [ ] Search and filter tracks
** Playlists
- [ ] Create new playlist
- [ ] Add tracks to playlist
- [ ] Load playlist
- [ ] Delete playlist
** Player
- [ ] Play/pause/stop controls work
- [ ] Track progress updates
- [ ] Queue management
- [ ] Volume control
** Admin Features
- [ ] View all tracks
- [ ] Scan library
- [ ] User management
- [ ] System status monitoring
* Performance Testing
For load testing and performance validation:
#+BEGIN_SRC bash
# Simple load test with Apache Bench
ab -n 1000 -c 10 http://localhost:8080/api/asteroid/tracks
# Or with wrk
wrk -t4 -c100 -d30s http://localhost:8080/api/asteroid/tracks
#+END_SRC
* Security Testing
** API Security Checklist
- [ ] Authentication required for protected endpoints
- [ ] Authorization checks for admin endpoints
- [ ] SQL injection prevention
- [ ] XSS protection in templates
- [ ] CSRF token validation
- [ ] Rate limiting on API endpoints

View File

@ -1,243 +0,0 @@
#+TITLE: UI Fixes and Improvements - Complete
#+AUTHOR: Asteroid Radio Development Team
#+DATE: 2025-10-04
* Overview
Comprehensive UI fixes and improvements across all pages, including live stream indicators, stream quality display, and Now Playing functionality.
* What Was Completed
** Live Stream Indicators
Fixed red/green indicator inconsistencies across all pages
*** Front Page
- Changed =🔴 LIVE STREAM= to =🟢 LIVE STREAM=
- Added green color styling: =style="color: #00ff00;"=
- Status indicator shows =● BROADCASTING= in green
*** Web Player
- Changed =🔴 Live Radio Stream= to =🟢 Live Radio Stream=
- Consistent green indicator
- Matches front page styling
** Stream Quality Display
*** Problem Fixed
Stream quality showed "128kbps MP3" even when AAC stream was selected
*** Solution Implemented
- Updated default to "AAC 96kbps Stereo"
- Added JavaScript to sync quality display with selected stream
- Quality updates dynamically when user changes streams
*** Implementation
#+BEGIN_SRC javascript
function changeStreamQuality() {
const selector = document.getElementById('stream-quality');
const config = streamConfig[selector.value];
// Update Station Status stream quality display
const statusQuality = document.querySelector('[data-text="stream-quality"]');
if (statusQuality) {
statusQuality.textContent = config.format;
}
// Update stream URL and format
document.getElementById('stream-url').textContent = config.url;
document.getElementById('stream-format').textContent = config.format;
// Update audio player
const audioElement = document.getElementById('live-audio');
const sourceElement = document.getElementById('audio-source');
sourceElement.src = config.url;
sourceElement.type = config.type;
audioElement.load();
}
#+END_SRC
*** Page Load Initialization
#+BEGIN_SRC javascript
window.addEventListener('DOMContentLoaded', function() {
// Set initial quality display to match the selected stream
const selector = document.getElementById('stream-quality');
const config = streamConfig[selector.value];
document.getElementById('stream-url').textContent = config.url;
document.getElementById('stream-format').textContent = config.format;
const statusQuality = document.querySelector('[data-text="stream-quality"]');
if (statusQuality) {
statusQuality.textContent = config.format;
}
});
#+END_SRC
** Now Playing Functionality
*** Investigation Results
- No HTML rendering bug found (was a false alarm in TODO)
- Now Playing working correctly on all pages
- Updates every 10 seconds from Icecast
- Proper text content rendering (no HTML injection)
*** Implementation Details
#+BEGIN_SRC javascript
function updateNowPlaying() {
fetch('/asteroid/api/icecast-status')
.then(response => response.json())
.then(data => {
if (data.icestats && data.icestats.source) {
const mainStream = data.icestats.source;
if (mainStream.title) {
// Parse "Artist - Track" format
const titleParts = mainStream.title.split(' - ');
const artist = titleParts.length > 1 ? titleParts[0] : 'Unknown Artist';
const track = titleParts.length > 1 ? titleParts.slice(1).join(' - ') : mainStream.title;
// Use textContent to prevent HTML injection
document.querySelector('[data-text="now-playing-artist"]').textContent = artist;
document.querySelector('[data-text="now-playing-track"]').textContent = track;
document.querySelector('[data-text="listeners"]').textContent = mainStream.listeners || '0';
}
}
})
.catch(error => console.log('Could not fetch stream status:', error));
}
// Update every 10 seconds
updateNowPlaying();
setInterval(updateNowPlaying, 10000);
#+END_SRC
** API Endpoint Fixes
*** Missing /api/tracks Endpoint
Created endpoint for web player to fetch tracks
#+BEGIN_SRC lisp
(define-page api-tracks #@"/api/tracks" ()
"Get all tracks for web player"
(require-authentication)
(setf (radiance:header "Content-Type") "application/json")
(handler-case
(let ((tracks (db:select "tracks" (db:query :all))))
(cl-json:encode-json-to-string
`(("status" . "success")
("tracks" . ,(mapcar (lambda (track)
`(("id" . ,(gethash "_id" track))
("title" . ,(gethash "title" track))
("artist" . ,(gethash "artist" track))
("album" . ,(gethash "album" track))
("duration" . ,(gethash "duration" track))
("format" . ,(gethash "format" track))))
tracks)))))
(error (e)
(cl-json:encode-json-to-string
`(("status" . "error")
("message" . ,(format nil "Error retrieving tracks: ~a" e)))))))
#+END_SRC
*** Icecast Status Endpoint
Improved XML parsing for better reliability
#+BEGIN_SRC lisp
;; Extract title using register groups for cleaner extraction
(title (multiple-value-bind (match groups)
(cl-ppcre:scan-to-strings "<title>(.*?)</title>" source-section)
(if (and match (> (length groups) 0))
(aref groups 0)
"Unknown")))
#+END_SRC
* Pages Updated
** Front Page (/)
- ✅ Green live indicator
- ✅ Correct stream quality display
- ✅ Now Playing updates
- ✅ Dynamic quality switching
** Web Player (/player)
- ✅ Green live indicator
- ✅ Track library loads correctly
- ✅ Now Playing updates
- ✅ Quality selector working
** Admin Dashboard (/admin)
- ✅ System status indicators
- ✅ Track management working
- ✅ All features functional
* Visual Improvements
** Color Consistency
- Live indicators: Green (#00ff00)
- Status text: Green for active/online
- Error states: Red (#ff0000)
- Info text: Blue (#0066cc)
** Typography
- Consistent font sizes
- Proper heading hierarchy
- Readable contrast ratios
- Mobile-friendly text
** Layout
- Consistent spacing
- Aligned elements
- Responsive design
- Clean card-based UI
* Testing Results
** Browser Compatibility
- ✅ Chrome/Chromium
- ✅ Firefox
- ✅ Edge
- ✅ Safari (expected to work)
** Functionality Tests
- ✅ Stream quality selector updates all displays
- ✅ Live indicators show green when broadcasting
- ✅ Now Playing updates every 10 seconds
- ✅ No HTML injection vulnerabilities
- ✅ Proper error handling
** Performance
- Page load: <500ms
- Now Playing update: <100ms
- Stream quality change: <50ms
- No memory leaks detected
* Files Modified
- =template/front-page.chtml= - Live indicator, quality display, initialization
- =template/player.chtml= - Live indicator, track loading
- =template/admin.chtml= - Status indicators
- =asteroid.lisp= - API endpoints
* Security Improvements
** XSS Prevention
- Using =.textContent= instead of =.innerHTML=
- No raw HTML insertion
- Proper escaping in templates
** API Security
- Authentication required for sensitive endpoints
- Proper error handling
- No information leakage in errors
* Status: ✅ COMPLETE
All UI fixes and improvements implemented and tested. Pages display correctly with proper indicators, accurate information, and smooth user experience.
** Summary of Fixes
- ✅ Live stream indicators (green)
- ✅ Stream quality display (accurate)
- ✅ Now Playing (working correctly)
- ✅ API endpoints (all functional)
- ✅ Visual consistency (achieved)