- Remove committed .coverage and test-results/ (196K screenshots); gitignore them - Fix hardcoded /home/userpath + venv/bin/python in test_endpoints.py (relative backend dir + sys.executable) - Fix concatenated 'import json' in settings.py; bare excepts -> Exception; SQLAlchemy-safe is_active.is_(True); __all__ on models/schemas barrels - ruff clean (93 fixes), MIT LICENSE, PLAN.md -> docs/, README Tests section - 300 tests pass, 93.7% coverage
618 lines
28 KiB
Markdown
618 lines
28 KiB
Markdown
# 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**: `<audio>` element + custom UI. Framer Motion for progress animations.
|
||
- **Mobile Player**: `react-native-track-player` (background playback support)
|
||
|
||
### 6.2 Mood Radio Engine
|
||
1. Fetch lyrics for each song via Genius API → cache in `lyrics_cache`
|
||
2. Keyword scoring: Each mood has a weighted word list (e.g., Sad: "cry, alone, tears, hurt, lonely" with weights)
|
||
3. Score each song against all 10 moods → assign highest-scoring mood
|
||
4. Confidence threshold: Only include songs scoring >60% for a mood
|
||
5. Playlist generation: Rank by confidence, return top 30-50 songs per mood
|
||
6. Personalization: Weight songs from user's library higher than external sources
|
||
|
||
### 6.3 SharePlay WebSocket System
|
||
- Room-based architecture. Host creates room → others join via token
|
||
- State sync: Current song ID, playback position, play/pause state, shuffle mode
|
||
- Tick sync: Host broadcasts position every 2 seconds. Clients adjust drift.
|
||
- Conflict resolution: Host commands override guest commands
|
||
- Presence: Connected user count, user list
|
||
- Cue queue: FIFO queue of songs. "Add to Cue" appends. Auto-loads on song end.
|
||
- Controls: Play, Pause, Skip Back, Rewind (-15s), Fast Forward (+15s), Skip Forward
|
||
|
||
### 6.4 Internet Radio
|
||
- RadioBrowser API: Open network of radio stations (no API key needed)
|
||
- GEO filtering: Use user's browser/device location → filter stations by distance
|
||
- Stream proxying: Backend proxies streams to avoid CORS issues
|
||
- Currently playing: Some stations provide now-playing metadata via RadioBrowser
|
||
|
||
### 6.5 LoFi Channels
|
||
- Curated list of public LoFi streams (LoFi Girl, Chillhop, etc.)
|
||
- YouTube streams: Use Piped API or Invidious to get direct stream URLs
|
||
- Proxied through backend for uniform playback experience
|
||
- In-app playback (no external navigation)
|
||
|
||
### 6.6 New Releases
|
||
- MusicBrainz API: Check if artists in user's library have new releases
|
||
- Periodic check: Background task runs daily, stores results in `new_releases_check`
|
||
- Detail view: Album info, track list with song titles and durations
|
||
- "Add to Playlist" action per song
|
||
|
||
### 6.7 Live Events (Concert Listings)
|
||
- Simulated for v1: Static data / placeholder concert listings
|
||
- UI built now, real data integration later
|
||
- GEO-based filtering (near user's location)
|
||
|
||
## 7. Design System
|
||
|
||
### Visual Identity
|
||
- **Theme**: Warm, vinyl-inspired aesthetic. Dark mode primary, light mode secondary.
|
||
- **Color Palette**: Deep blacks, warm ambers, accent colors per mood
|
||
- **Typography**: Display font for headings (e.g., Space Grotesk), sans-serif for body
|
||
- **Vinyl Motif**: Consistent vinyl record visual language across all pages
|
||
- **Animations**: Framer Motion for page transitions, hover effects, vinyl spin animations
|
||
|
||
### Mood Color Mapping
|
||
| Mood | Color | Background Tone |
|
||
|---|---|---|
|
||
| Sad | Deep blue (#1a2a4a) | Cool, muted |
|
||
| Happy | Warm yellow (#f5c542) | Bright, sunny |
|
||
| Energetic | Electric red (#e63946) | Bold, intense |
|
||
| Focused | Forest green (#2d6a4f) | Calm, sharp |
|
||
| Chill | Teal (#48957e) | Relaxed, smooth |
|
||
| Romantic | Rose (#bc6a7e) | Soft, warm |
|
||
| Angry | Crimson (#9d0208) | Sharp, hot |
|
||
| Nostalgic | Sepia (#a67c52) | Warm, vintage |
|
||
| Melancholy | Purple (#5a189c) | Deep, reflective |
|
||
| Dreamy | Lavender (#9b5de5) | Light, ethereal |
|
||
|
||
## 8. Implementation Phases
|
||
|
||
### Phase 1: Foundation (8-10 tasks)
|
||
1. Monorepo setup (npm workspaces, 3 packages)
|
||
2. Shared package: TypeScript types, API client, constants
|
||
3. Backend: FastAPI scaffold, SQLite setup, CORS config
|
||
4. Web: React + Vite + Tailwind + Radix UI + Framer Motion setup
|
||
5. Mobile: React Native + Expo + NativeWind setup
|
||
6. Docker Compose: Backend + web dev environment
|
||
7. CI/CD pipeline (GitHub Actions: lint, test, build)
|
||
8. Design system: Color tokens, typography, component foundations
|
||
|
||
### Phase 2: Core Music Infrastructure (12-15 tasks)
|
||
9. Song model + schema + CRUD endpoints
|
||
10. Music file upload endpoint (multipart, validation)
|
||
11. Directory scanner service (recursive, format detection)
|
||
12. Metadata extraction (mutagen: tags, album art, duration)
|
||
13. Audio transcoding pipeline (ffmpeg → OGG)
|
||
14. Streaming endpoint (HTTP 206 range requests)
|
||
15. Global audio player store (Zustand, play/pause/seek/state)
|
||
16. Web audio player component
|
||
17. Mobile audio player component (react-native-track-player)
|
||
18. Shared/ mobile API client integration
|
||
|
||
### Phase 3: Core Pages (15-20 tasks)
|
||
19. Navigation Hub component (profile + feature tabs)
|
||
20. Bottom Navigation Bar component (shared across pages)
|
||
21. Now Playing Mini-Bar component
|
||
22. Vinyl visual components (record, stack, sleeve)
|
||
23. **Home page**: NavHub + suggestions + currently playing + mood access + BottomNav
|
||
24. **Library page**: Profile + search + vinyl stacks + BottomNav
|
||
25. **Playlist page**: Left sidebar (back, thumbnails, progress, controls) + main content (name, art, song list) + BottomNav
|
||
26. **Now Playing page**: Full-screen player, album art, progress bar, overlay seek, controls, share play
|
||
27. Progress bar component (draggable bar + overlay seek)
|
||
28. Playback controls component
|
||
29. **Search page**: Profile + search bar + feature grid + suggestions + library + mini player + BottomNav
|
||
30. Search functionality (backend + frontend integration)
|
||
|
||
### Phase 4: Discovery Features (15-20 tasks)
|
||
31. Genius API integration (lyrics fetching, caching)
|
||
32. Mood engine: Keyword scoring system, mood classification
|
||
33. Mood categories table seeding (10 moods + colors + images)
|
||
34. Mood playlist generation endpoint
|
||
35. **Mood Radio page**: NavHub + blurred circle image + circular progress + mood name + colored background + "Set the Mood" button
|
||
36. Mood selection UI
|
||
37. RadioBrowser API integration (station discovery)
|
||
38. GEO-based station filtering
|
||
39. Radio stream proxying
|
||
40. Map component for nearby stations
|
||
41. **Internet Radio page**: Profile + search + map view + station grid + BottomNav
|
||
42. MusicBrainz API integration (artist lookup, new releases)
|
||
43. Background release checker (scheduled task)
|
||
44. **New Releases page**: NavHub + repeatable cards + album detail view + BottomNav
|
||
45. LoFi channel configuration (stream URLs from public sources)
|
||
46. LoFi stream proxying
|
||
47. **LoFi Channel page**: Profile + title + channel cards + in-app playback + BottomNav
|
||
48. New Releases → "Add to Playlist" integration
|
||
|
||
### Phase 5: Social/Collaboration (12-15 tasks)
|
||
49. **Create/Add page**: NavHub + tabbed interface (Playlist/Mood/Radio/Collab) + BottomNav
|
||
50. Playlist creation workflow (name, select songs, save)
|
||
51. Mood playlist creation (select mood → generate → save)
|
||
52. Radio creation (randomized shuffle from library)
|
||
53. Collab: Playlist share link generation
|
||
54. Collab: Shared playlist access via token
|
||
55. **Account page**: Profile image + welcome + menu items (Plugins placeholder, Servers config, About You stats, Internet Radio link, Updates changelog, Settings)
|
||
56. Settings page: Preferences, audio quality, theme
|
||
57. Server configuration UI (add/remove scan directories)
|
||
58. Listening stats computation + display
|
||
59. WebSocket server setup (SharePlay rooms)
|
||
60. SharePlay room management (create/join/leave)
|
||
61. WebSocket state sync (position ticks, drift correction)
|
||
62. **SharePlay page**: NavHub + bottom sheet + controls + cue queue + presence
|
||
63. Cue queue management
|
||
|
||
### Phase 6: Polish + Infrastructure (10-12 tasks)
|
||
64. Framer Motion page transitions
|
||
65. Vinyl spin animations (idle + playing states)
|
||
66. Mood background transitions (color interpolation)
|
||
67. Circular progress animation (Mood Radio)
|
||
68. Bottom sheet drag gesture (SharePlay)
|
||
69. Responsive design adjustments (web breakpoints)
|
||
70. Platform-specific adaptations (mobile gesture handling)
|
||
71. Performance optimization (lazy loading, image caching, virtual lists)
|
||
72. Error handling + loading states across all pages
|
||
73. Accessibility audit (ARIA, keyboard nav, screen reader)
|
||
74. Unit tests (backend services, mood engine, utilities)
|
||
75. Integration tests (API endpoints, critical flows)
|
||
76. Docker production configuration
|
||
77. Deployment documentation
|
||
|
||
### Phase 7: Live Events + Extras (4-6 tasks)
|
||
78. Concert events model + endpoints (placeholder data)
|
||
79. Live Events section in Search page feature grid
|
||
80. Concert listing UI (placeholder)
|
||
81. LoFi stream research (find 5-10 public LoFi streams)
|
||
82. Additional polish iterations
|
||
|
||
## 9. Estimated Effort Summary
|
||
|
||
| Phase | Tasks | Effort |
|
||
|---|---|---|
|
||
| 1. Foundation | 8 | ~3 days |
|
||
| 2. Core Music | 12 | ~5 days |
|
||
| 3. Core Pages | 15 | ~7 days |
|
||
| 4. Discovery | 18 | ~8 days |
|
||
| 5. Social | 15 | ~6 days |
|
||
| 6. Polish | 14 | ~5 days |
|
||
| 7. Extras | 6 | ~2 days |
|
||
| **Total** | **88 tasks** | **~36 days** |
|
||
|
||
## 10. Risk Areas
|
||
|
||
1. **Audio transcoding performance**: Large music libraries will take time to transcode. Solution: Async transcoding with progress tracking, transcode on-demand for first play.
|
||
2. **Genius API rate limits**: Lyrics fetching is rate-limited. Solution: Aggressive caching, batch processing, graceful degradation.
|
||
3. **YouTube stream reliability**: LoFi streams from YouTube may break. Solution: Maintain multiple sources, fallback to self-hosted content.
|
||
4. **WebSocket stability**: SharePlay sync requires reliable connections. Solution: Reconnection logic, state recovery, drift correction.
|
||
5. **Cross-platform consistency**: Web and mobile may drift visually. Solution: Shared design tokens, regular cross-platform reviews.
|
||
6. **RadioBrowser variability**: Different instances have different data quality. Solution: Configurable instance, fallback list.
|
||
|
||
## 11. Decision Log
|
||
|
||
| Decision | Choice | Rationale |
|
||
|---|---|---|
|
||
| Platform | Web + Mobile (both) | Maximize reach |
|
||
| Web Framework | React + TypeScript + Vite | Modern, fast DX |
|
||
| Web UI | Radix UI + Tailwind + Framer Motion | Design-forward, accessible, animatable |
|
||
| Mobile Framework | React Native + Expo | Share patterns with web |
|
||
| Mobile UI | NativeWind + custom components | Tailwind consistency + unique vinyl aesthetic |
|
||
| Backend | Python + FastAPI | Good for AI/ML features |
|
||
| Database | SQLite | Simple single-server deployment |
|
||
| Shared Types | Separate shared/ package | Single source of truth for web + mobile |
|
||
| Music Import | Upload + directory scanning | Flexible import options |
|
||
| Music Source | Local + self-hosted server | User owns their library |
|
||
| Scope | Full implementation (all pages) | Build everything |
|
||
| Mood Analysis | Pre-built mood categories | Keyword scoring on lyrics |
|
||
| Mood Categories | Extended 10 moods | Comprehensive coverage |
|
||
| Lyrics Source | Genius API | Largest lyrics database |
|
||
| Audio Formats | All (MP3, AAC, FLAC, WAV, OGG) | Full format support |
|
||
| Seek Interaction | Both overlay + bar | Flexible seeking |
|
||
| Internet Radio | Real radio streams | RadioBrowser API integration |
|
||
| LoFi Channels | Self-hosted streams in-app | In-app playback, no external navigation |
|
||
| SharePlay | WebSockets sync | Real-time multi-device sync |
|
||
| Collab Feature | Simple sharing | Share links, no friend system |
|
||
| Create Page Layout | Tabs on one page | Compact, discoverable |
|
||
| Plan Scope | Full stack + infra | Complete coverage |
|
||
| Account Items | Plugins=placeholder, Servers=config, About You=stats, Updates=changelog | Practical v1 scope |
|
||
| Live Events | Concert listings (simulated) | UI built now, data later |
|
||
| Episodes | Songs only | Not podcast support |
|
||
| New Releases | User's library artists + external | MusicBrainz integration | |