Architecture
Watermelon follows a modular clean architecture with three independent repositories that communicate via REST APIs.
System Overview
┌─────────────────────────────────────────────────────────────┐
│ User Device │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Watermelon │ │ Chrome/Safari│ │ Telegram │ │
│ │ Android App │ │ Web Browser │ │ Bot │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
└─────────┼─────────────────┼─────────────────┼───────────────┘
│ │ │
│ HTTPS/WSS │ HTTPS │ HTTPS
│ │ │
┌─────────▼─────────────────▼─────────────────▼───────────────┐
│ Watermelon API (Node.js + Express) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Search Ctrl │ │ Stream Ctrl │ │ Payment Ctrl │ │
│ │ yt-dlp │ │ NewPipe │ │ Razorpay │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────┬───────────────────────────────────────────────────┘
│
│ PostgreSQL REST/Realtime
│
┌─────────▼───────────────────────────────────────────────────┐
│ Supabase (PostgreSQL + Auth + Storage) │
│ profiles │ playlists │ favorites │ songs │ history │ etc │
└─────────────────────────────────────────────────────────────┘Android App Architecture
The Android app follows Clean Architecture with 4 layers:
app/ UI layer — Activities, Composables, ViewModels
├── feature-home/ Home screen, categories, trending
├── feature-search/ Search UI, results, filters
├── feature-player/ Player screen, mini-player, queue
├── feature-library/ Library, playlists, favorites, downloads
├── feature-settings/ Settings, premium, autoplay toggle
├── feature-playlist/ Playlist detail, creation, editing
├── feature-radio/ Radio browser, favorites
│
data/ Data layer — Repositories, APIs, DB
├── remote/ Supabase, YouTube, Radio Browser, Watermelon API
├── local/ Room database, DataStore
└── repository/ Repository implementations
│
domain/ Domain layer — Business logic
├── model/ Domain models (Song, Artist, Playlist, etc.)
├── repository/ Repository interfaces
└── player/ PlaybackCommandDispatcher, AutoplayEngine
│
core/ Core utilities shared across modulesUnidirectional Data Flow
UI (Compose) ← StateFlow/Flow ← ViewModel ← Repository ← Data Source- UI Layer — Composables observe
StateFlowfrom ViewModels. No business logic here. - ViewModel Layer — Exposes UI state, handles user actions, calls use cases.
- Repository Layer — Abstracts data sources (local Room DB + remote APIs).
- Data Source Layer — Supabase REST, yt-dlp, NewPipe Extractor, Radio Browser API.
Dependency Injection
Hilt wires all modules:
@HiltAndroidApp
class WatermelonApp : Application()
@HiltViewModel
class HomeViewModel @Inject constructor(
private val musicCatalogRepository: MusicCatalogRepository
) : ViewModel()API Architecture
watermelon-api/
├── src/
│ ├── controllers/ # Request handlers (search, stream, payment)
│ ├── routes/ # Express Router definitions
│ ├── services/ # Business logic (yt-dlp wrapper, caching)
│ ├── middlewares/ # Auth, rate limiting, CORS, error handling
│ └── utils/ # Helpers (validation, formatting, cache)
├── scripts/ # Cross-platform yt-dlp downloader
└── server.js # Entry pointKey Services
| Service | Role |
|---|---|
| yt-dlp | Extracts audio URLs and metadata from YouTube Music |
| NewPipe Extractor | Alternative extraction backend for audio streams |
| Supabase Client | PostgreSQL queries for profiles, playlists, history |
| Razorpay SDK | Payment order creation and signature verification |
| Telegram Bot | Remote queue management via bot commands |
Web Architecture
watermelon-web/
├── app/ # Next.js App Router
│ ├── sections/ # Landing page sections (Hero, Features, Stats)
│ ├── components/ # Reusable UI (Navbar, Buttons, Cards)
│ ├── leaderboard/ # Global leaderboard page
│ └── lib/ # API clients, GitHub integration
├── pages/docs/ # Nextra documentation pages
├── components/ui/ # shadcn/ui primitives
└── public/ # Static assetsData Flow
Next.js Page → API Client (fetchAppStats) → Watermelon API → Supabase
↓
localStorage cache (5s TTL)Database Architecture
See the full Database Schema for table definitions. High-level:
- profiles — User identity, gamification stats, rank tier
- playlists — Playlist metadata with public/private flag
- playlist_songs — Junction table for playlist tracks
- favorites — User → Song likes
- play_sessions — Listening history with duration
- songs — Cached song metadata from YouTube
- user_actions — Analytics (plays, skips, completions)
- achievements — Badge definitions
- user_achievements — User → Badge assignments
- leaderboard — Computed rankings updated hourly
Authentication Flow
User → Supabase Auth (OAuth/Email) → JWT Token
│ │
│ Android App stores token in │ API uses Supabase Service Key
│ EncryptedSharedPreferences │ for admin operations
│ │
└──── JWT included in every ──────────→│ API request via Hilt OkHttp
request via Hilt OkHttp │ interceptorCommunication Patterns
| Flow | Protocol | Data Format |
|---|---|---|
| App → API | HTTPS REST | JSON |
| App → Supabase | HTTPS REST + WebSocket | JSON |
| API → yt-dlp | Child process | JSON + stdout |
| Web → API | HTTPS REST | JSON |
| Telegram → API | HTTPS (Webhook/Polling) | JSON |