music-app/PLAN.md
2026-07-03 01:06:35 +00:00

618 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |