# Music App — Comprehensive Implementation Plan ## Progress — COMPLETE ✅ | Phase | Status | Details | |---|---|---| | Phase 1: Foundation | ✅ | Monorepo, shared types, backend scaffold, web/mobile apps, Docker | | Phase 2: Core Music | ✅ | Audio pipeline, streaming, upload, scanning, metadata, transcoding | | Phase 3: Core Pages | ✅ | 12 pages, vinyl components, playback controls, API wiring | | Phase 4: Discovery | ✅ | Mood Radio, Internet Radio, New Releases, LoFi Channels | | Phase 5: Social | ✅ | SharePlay, Collab, Account page, playlist sharing | | Phase 6: Polish | ✅ | Framer Motion animations, responsive CSS, accessibility, testing | | Phase 7: Extras | ✅ | Live Events placeholder, final polish | ### Test Results | Suite | Passing | Status | |---|---|---| | Backend Endpoints | 75/75 | ✅ 100% | | Backend Unit Tests | 38/38 | ✅ 100% | | Web TypeScript | 0 errors | ✅ Clean | | Playwright E2E | Written (4 spec files, 30+ tests) | 📝 Ready to run | ### Project Stats **Total Files**: 121 (26 web, 46 backend, 19 shared, 16 mobile, 4 e2e, 2 backend tests, 8 config) ### How to Run ```bash # Backend cd backend && source venv/bin/activate && python -m uvicorn app.main:app --reload --port 8000 # Web cd web && npm run dev # Both (Docker) docker-compose up # Tests cd backend && python tests/test_endpoints.py # endpoint tests cd backend && python -m pytest tests/test_services.py -v # unit tests npx playwright test # e2e (requires web server running) ``` ## 1. Tech Stack | Layer | Technology | |---|---| | **Web Frontend** | React + TypeScript + Vite | | **Web UI** | Radix UI (headless primitives) + Tailwind CSS + Framer Motion (animations) | | **Mobile Frontend** | React Native + Expo | | **Mobile UI** | NativeWind (Tailwind) + custom components | | **Shared Code** | Separate `shared/` workspace package (types, API client, utils) | | **Backend** | Python 3.11 + FastAPI | | **Database** | SQLite + SQLAlchemy ORM | | **Real-time** | WebSockets (`fastapi-websocket`) | | **Audio** | MP3, AAC, FLAC, WAV, OGG (transcoded to OGG for streaming) | | **Lyrics** | Genius API | | **Internet Radio** | RadioBrowser API | | **New Releases** | MusicBrainz API (check library artists for new releases) | | **Mood Analysis** | Keyword/mood scoring on lyrics → 10 mood categories | | **Auth** | None for v1 (single-user mode) | | **Containerization** | Docker + Docker Compose | ## 2. Project Structure ``` music-app/ ├── package.json # Monorepo root (npm workspaces) ├── shared/ # Shared package (workspace) │ ├── src/ │ │ ├── types/ # TypeScript interfaces (Song, Playlist, Mood, etc.) │ │ ├── api/ # API client (fetch wrapper, endpoints) │ │ └── constants/ # Mood categories, nav items, etc. │ └── package.json ├── web/ # React web app │ ├── src/ │ │ ├── app/ # App router, layout, global state │ │ ├── components/ │ │ │ ├── common/ # Button, Icon, Badge, etc. │ │ │ ├── navigation/ # NavHub, BottomNavBar, NowPlayingMiniBar │ │ │ ├── vinyl/ # VinylStack, VinylRecord, VinylSleeve │ │ │ ├── player/ # ProgressBar, PlaybackControls, OverlaySeek │ │ │ └── visual/ # MoodBackground, AlbumArt, etc. │ │ ├── pages/ # 12 page components │ │ ├── hooks/ # useAudioPlayer, useWebSocket, useMood, etc. │ │ ├── store/ # Zustand stores (player, library, ui) │ │ ├── services/ # API calls (imports from shared/) │ │ └── utils/ │ ├── tailwind.config.ts │ └── package.json ├── mobile/ # React Native + Expo │ ├── src/ │ │ ├── components/ # Mobile-specific components │ │ ├── screens/ # 12 screen components │ │ ├── hooks/ │ │ ├── store/ # Zustand (same pattern as web) │ │ ├── services/ # API calls (imports from shared/) │ │ └── navigation/ # React Navigation config │ └── package.json ├── backend/ # Python FastAPI │ ├── app/ │ │ ├── main.py # FastAPI app, CORS, WebSocket setup │ │ ├── routers/ │ │ │ ├── songs.py │ │ │ ├── playlists.py │ │ │ ├── mood.py │ │ │ ├── radio.py │ │ │ ├── search.py │ │ │ ├── lofi.py │ │ │ ├── shareplay.py │ │ │ ├── import_.py │ │ │ ├── settings.py │ │ │ ├── releases.py │ │ │ └── events.py │ │ ├── models/ # SQLAlchemy models │ │ ├── schemas/ # Pydantic schemas │ │ ├── services/ │ │ │ ├── audio.py # Transcoding, streaming, range requests │ │ │ ├── scanner.py # Directory scanning for music files │ │ │ ├── mood_engine.py # Lyrics → mood classification │ │ │ ├── lyrics.py # Genius API client │ │ │ ├── radio_browser.py # RadioBrowser API client │ │ │ ├── musicbrainz.py # MusicBrainz API (new releases) │ │ │ ├── shareplay.py # WebSocket room management │ │ │ └── events.py # Concert listing service │ │ ├── db/ # SQLite setup, migrations │ │ └── ws/ # WebSocket endpoint handlers │ ├── music/ # Music file storage (scanned) │ ├── uploads/ # Web upload destination │ ├── static/ # Album art, mood images, etc. │ ├── requirements.txt │ └── Dockerfile ├── docker-compose.yml # Dev environment (backend + web) ├── .env.example └── PLAN.md ``` ## 3. Page Inventory (12 Pages) ### Page 1: Home - **Navigation Hub** (top): Profile icon + 4 feature tabs (Music, New Music, Mood, LoFi Channel) - **Suggestions Section**: Quick-access cards → Music / New Music features - **Currently Playing Radio**: Shows track currently playing from user's playlist - **Mood Radio Access**: Click-through buttons to select current mood → Mood Radio page - **Bottom Navigation Bar**: Home | Playlist | Search | Internet Radio | Create ### Page 2: Library - **Profile Access** (top) - **Search Bar**: Filter user's playlists - **Vinyl Stacks**: Visual stacks (4 vinyls per stack), each = one playlist. Playlist name below right of stack. - **Bottom Navigation Bar** ### Page 3: Create/Add - **Navigation Hub** (top) - **Tab Layout** (4 tabs): - **Playlist**: Create playlist, add songs from library - **Mood Playlist**: Select mood → generate playlist from mood radio engine - **Radio**: Play randomized songs with DJ-style shuffle - **Collab**: Browse and play shared playlists (simple link sharing) - **Bottom Navigation Bar** ### Page 4: Internet Radio - **Profile Access** (top) - **Search Bar**: Placeholder "What music is calling to you?" + magnifying glass icon - **Currently Airing**: Map view showing local radio stations near user. Shows user location pin + nearest station. Displays current song + artist. - **Radio Station Section**: Scrollable grid of station images → click to play - **Bottom Navigation Bar** ### Page 5: Search - **Profile Access** (top) - **Search Bar**: "What music is calling to you?" + magnifying glass - **Feature Grid**: Colored rectangles → Music, New Music, Live Events, Internet Radio, Mood Radio - **Music Suggestions**: 2 rows × 5 squares of album art (personalized recommendations) - **Your Library**: Vinyl sleeve design (record emerging left). Playlist names below. - **Now Playing Mini-Bar** (above nav): Vinyl icon + song name + artist + play/pause + skip buttons - **Bottom Navigation Bar** ### Page 6: Account - **User Image** + "Welcome [username]" (top) - **Menu Items**: - **Plugins**: Placeholder link (to be developed later) - **Servers**: Configure music folder paths, scan settings, remote servers - **About You**: Listening stats, favorite artists, top genres, listening history - **Internet Radio**: Link to Internet Radio page - **Updates**: App changelog, version info - **Settings & Privacy**: App preferences, audio quality, theme settings ### Page 7: Currently Playing (Now Playing) - **Top**: Playlist name - **Album Art** (center, large) - **Song Name** + **Artist Name** - **Progress Bar**: Elapsed time display. Draggable on bar AND on overlay. - **Overlay Seek**: 25% opacity background overlay follows progress position. Touch/drag anywhere on page to seek. - **Controls** (L→R): Shuffle ↻ | Backward ⏮ | Play/Pause ▶/⏸ | Forward ⏭ | Plus + - **Below Controls**: SharePlay icon + device name - **Behaviors**: Play↔Pause toggle. Shuffle randomizes order. Back/Forward skip songs. Plus toggles song in/out of playlist. SharePlay opens device selector. ### Page 8: SharePlay - **Navigation Hub** (top) - **Bottom Sheet** (draggable notch at top to expand/collapse): - Top left: SharePlay icon - Top right: Person icon + connected user count - "Currently Playing" + host's name - Vinyl image + song name + artist - Progress bar - **Controls**: Skip Back (prev song) | Rewind (backtrack in song) | Play/Pause | Fast Forward (advance in song) | Skip Forward (next song) - "Up Next" + next song preview - "Add Song to Cue" button (+ icon) - **WebSocket sync**: Real-time state sync across all connected devices ### Page 9: Mood Radio - **Navigation Hub** (top) - **"Mood Radio"** label (top left) - **Center**: Blurred stock image in circle, surrounded by circular progress bar - **Below Image**: Mood playlist name (e.g., "I'm Feeling Nostalgic") - **Background**: Dynamic color matching the mood - **Bottom**: "Currently Playing" label → upward notch icon → "Set the Mood" button - **10 Mood Categories**: Sad, Happy, Energetic, Focused, Chill, Romantic, Angry, Nostalgic, Melancholy, Dreamy - **Algorithm**: Fetch lyrics → keyword scoring → mood classification → rank songs → generate playlist ### Page 10: Playlist - **Left Sidebar** (vertical bar): - Back icon (top) - 5 square album cover thumbnails (user's playlists). Active playlist has play button overlay. - Vertical progress bar (elapsed time) - Star icon (top of bar) - Play/Pause button (bottom of bar) - **Main Content**: - Playlist name + SharePlay icon (top) - Album art with vinyl record in corner - Song list: Record icon + song name + duration - **Bottom**: Currently Playing bar ### Page 11: New Releases - **Navigation Hub** (top) - **"New Releases"** heading - **Repeatable Cards**: Artist image (left) + artist name + "Add Song to Playlist" (+ button) + 6 album thumbnails (right). Click album → detail view with song titles + lengths. - **Data Source**: MusicBrainz API checks if artists in user's library have new releases - **Bottom Navigation Bar** ### Page 12: LoFi Channel - **Top**: User profile (left) + "LoFi Channel" (center) - **Channel Cards**: "LoFi" label + playlist name + atmospheric image. Click → stream in-app. - **Streams**: Sourced from public LoFi streams (LoFi Girl, Chillhop, etc.) — proxied through backend - **Bottom Navigation Bar** ### Shared Components (across all pages) - **Navigation Hub**: Profile + feature tabs - **Bottom Navigation Bar**: Home | Playlist | Search | Internet Radio | Create - **Now Playing Mini-Bar**: Compact player (vinyl + song + artist + controls) - **Vinyl Component**: Reusable vinyl record / stack / sleeve visuals - **Search Bar Component**: Reusable with placeholder support ## 4. Backend API Endpoints ``` # Songs GET /api/songs # List all songs (paginated) GET /api/songs/{id} # Get song details POST /api/songs/upload # Upload music file POST /api/songs/scan # Scan configured directories DELETE /api/songs/{id} # Remove song GET /api/songs/{id}/stream # Stream audio (HTTP 206 range) GET /api/songs/{id}/lyrics # Get cached lyrics # Playlists GET /api/playlists # List all playlists POST /api/playlists # Create playlist GET /api/playlists/{id} # Get playlist + songs PUT /api/playlists/{id} # Update playlist DELETE /api/playlists/{id} # Delete playlist POST /api/playlists/{id}/songs # Add song DELETE /api/playlists/{id}/songs/{song_id} # Remove song POST /api/playlists/{id}/share # Generate share link GET /api/playlists/shared/{token} # Access shared playlist # Search GET /api/search?q=... # Search songs/playlists # Mood Radio GET /api/mood/categories # List 10 mood categories POST /api/mood/analyze # Analyze lyrics for mood (per song or library) GET /api/mood/{mood}/playlist # Get generated mood playlist POST /api/mood/save # Save mood playlist as regular playlist POST /api/mood/set # Switch current mood # Internet Radio GET /api/radio/stations # List stations (RadioBrowser) GET /api/radio/nearby # Stations near user location (GEO) GET /api/radio/stations/{id}# Station details GET /api/radio/stream/{id} # Proxy radio stream GET /api/radio/current # Currently playing on active station # LoFi GET /api/lofi/channels # List lo-fi channels GET /api/lofi/stream/{id} # Proxy lo-fi stream POST /api/lofi/add # Add new lo-fi channel # SharePlay WS /ws/shareplay/{room_id} # WebSocket for sync playback POST /api/shareplay/create # Create share room POST /api/shareplay/join # Join room (returns room_id) POST /api/shareplay/leave # Leave room POST /api/shareplay/cue # Add song to cue queue GET /api/shareplay/cue # Get cue queue POST /api/shareplay/control # Send playback command (play/pause/skip) # New Releases GET /api/releases # Check for new releases from library artists GET /api/releases/{artist} # Get new releases for specific artist POST /api/releases/add # Add new release songs to playlist # Live Events (simulated for v1) GET /api/events # List concerts near user POST /api/events # Add event listing # Settings GET /api/settings # Get preferences PUT /api/settings # Update preferences GET /api/settings/servers # List configured music directories POST /api/settings/servers # Add server/directory DELETE /api/settings/servers/{id} # Remove server # Account GET /api/account/stats # Listening stats (top artists, genres, etc.) GET /api/account/history # Listening history ``` ## 5. Database Schema (SQLite) ```sql songs ( id, title, artist, album, duration_sec, genre, file_path, transcoded_path, album_art_path, added_at, file_format, file_size_bytes ) playlists ( id, name, description, cover_art_path, created_at, updated_at, mood_category, is_shared, share_token ) playlist_songs (playlist_id, song_id, position, added_at) mood_categories ( id, name, color_hex, description, background_image, icon_path ) mood_songs (mood_id, song_id, confidence_score, analyzed_at) lyrics_cache ( song_id, lyrics_text, mood_tags_json, analyzed_at, source_url ) lofi_channels ( id, name, stream_url, image_path, description, source_platform, is_active ) radio_stations ( id, name, frequency, stream_url, location_lat, location_lon, genre, country, language, bitrate ) shareplay_rooms ( id, creator_user, created_at, current_song_id, position_sec, is_playing, shuffle_mode, active_connections ) shareplay_cue (room_id, song_id, position, added_by, added_at) user_settings ( key, value, updated_at -- Keys: audio_quality, theme, scan_directories_json, -- user_name, user_avatar, radio_browser_instance ) new_releases_check ( artist_name, last_checked_at, new_albums_json, checked_count ) concert_events ( id, name, venue, location_lat, location_lon, date, description, image_url ) ``` ## 6. Key Technical Implementation Details ### 6.1 Audio Pipeline - **Import**: Accept MP3, AAC, FLAC, WAV, OGG files via upload or directory scan - **Transcoding**: All formats transcoded to OGG Vorbis (backend) for uniform streaming. Uses `ffmpeg` / `pydub`. - **Metadata Extraction**: `mutagen` library extracts ID3 tags, album art, duration, genre - **Streaming**: HTTP 206 range requests for seeking. Backend serves transcoded files. - **Web Player**: `