docsArchitecture

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 modules

Unidirectional Data Flow

UI (Compose) ← StateFlow/Flow ← ViewModel ← Repository ← Data Source
  1. UI Layer — Composables observe StateFlow from ViewModels. No business logic here.
  2. ViewModel Layer — Exposes UI state, handles user actions, calls use cases.
  3. Repository Layer — Abstracts data sources (local Room DB + remote APIs).
  4. 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 point

Key Services

ServiceRole
yt-dlpExtracts audio URLs and metadata from YouTube Music
NewPipe ExtractorAlternative extraction backend for audio streams
Supabase ClientPostgreSQL queries for profiles, playlists, history
Razorpay SDKPayment order creation and signature verification
Telegram BotRemote 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 assets

Data 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         │ interceptor

Communication Patterns

FlowProtocolData Format
App → APIHTTPS RESTJSON
App → SupabaseHTTPS REST + WebSocketJSON
API → yt-dlpChild processJSON + stdout
Web → APIHTTPS RESTJSON
Telegram → APIHTTPS (Webhook/Polling)JSON