managarten/apps/mukke/CLAUDE.md
Till JS 3da6cf2bd4 docs(mukke): add ID3 tag endpoints to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:42:44 +01:00

5.3 KiB

Mukke - Music Workspace

Mukke is a web application for managing your music library, playing tracks, and creating synchronized lyrics. It combines a music player with a beat/lyrics editor featuring waveform visualization, BPM detection, timestamp markers, and exports to multiple formats.

Architecture

apps/mukke/
├── apps/
│   ├── backend/          # NestJS API (port 3010)
│   ├── web/              # SvelteKit app (port 5180)
│   └── landing/          # Astro marketing page
├── packages/
│   └── shared/           # Shared types (@mukke/shared)
└── package.json

Quick Start

# Start with full database setup
pnpm dev:mukke:full

# Or start components individually
pnpm docker:up                        # Start PostgreSQL, Redis, MinIO
pnpm --filter @mukke/backend dev      # Backend on port 3010
pnpm --filter @mukke/web dev          # Web on port 5180
pnpm --filter @mukke/landing dev      # Landing page

Backend API Endpoints

Songs (Library)

  • POST /songs/upload - Upload song and get presigned URL
  • GET /songs - List user's songs (with sort/filter)
  • GET /songs/:id - Get song details
  • PUT /songs/:id - Update song metadata
  • PUT /songs/:id/favorite - Toggle favorite
  • PUT /songs/:id/play - Increment play count
  • DELETE /songs/:id - Delete song
  • GET /songs/search?q= - Search songs
  • POST /songs/:id/extract-metadata - Extract ID3 tags from file into DB (+ cover art to S3)
  • POST /songs/:id/write-tags - Write DB metadata as ID3 tags back into MP3 file
  • GET /songs/:id/cover-url - Get presigned URL for cover art

Playlists

  • GET /playlists - List user's playlists
  • POST /playlists - Create playlist
  • GET /playlists/:id - Get playlist with songs
  • PUT /playlists/:id - Update playlist
  • DELETE /playlists/:id - Delete playlist
  • POST /playlists/:id/songs - Add song to playlist
  • DELETE /playlists/:id/songs/:songId - Remove song
  • PUT /playlists/:id/songs/reorder - Reorder songs

Library (Aggregates)

  • GET /library/albums - Get albums (grouped)
  • GET /library/artists - Get artists (grouped)
  • GET /library/genres - Get genres (grouped)
  • GET /library/stats - Library statistics

Projects (Editor)

  • GET /projects - List user's projects
  • GET /projects/:id - Get project with beat and lyrics
  • POST /projects - Create project
  • POST /projects/from-song/:songId - Create project from library song
  • PUT /projects/:id - Update project
  • DELETE /projects/:id - Delete project

Beats

  • GET /beats/project/:projectId - Get beat for project
  • GET /beats/:id - Get beat with markers
  • GET /beats/:id/download-url - Get presigned download URL
  • POST /beats/upload - Create beat and get upload URL
  • PUT /beats/:id/metadata - Update BPM, duration, waveform data
  • DELETE /beats/:id - Delete beat

Markers

  • GET /markers/beat/:beatId - Get markers for beat
  • POST /markers - Create marker
  • POST /markers/bulk - Bulk create markers
  • PUT /markers/:id - Update marker
  • PUT /markers/bulk - Bulk update markers
  • DELETE /markers/:id - Delete marker

Lyrics

  • GET /lyrics/project/:projectId - Get lyrics with synced lines
  • POST /lyrics/project/:projectId - Create/update lyrics content
  • POST /lyrics/:id/sync - Sync line timestamps

Export

  • GET /export/:projectId?format=lrc|srt|json - Export project

Database Schema

// songs - Music library
{ id, userId, title, artist, album, albumArtist, genre, trackNumber, year, duration,
  storagePath, coverArtPath, fileSize, bpm, favorite, playCount, lastPlayedAt, addedAt, updatedAt }

// playlists - User playlists
{ id, userId, name, description, coverArtPath, createdAt, updatedAt }

// playlist_songs - Playlist-Song join table
{ id, playlistId, songId, sortOrder, addedAt }

// projects - Editor projects
{ id, userId, title, description, songId, createdAt, updatedAt }

// beats - Audio files for editor
{ id, projectId, storagePath, filename, duration, bpm, bpmConfidence, waveformData }

// markers - Section markers
{ id, beatId, type, label, startTime, endTime, color, sortOrder }

// lyrics - Full lyrics text
{ id, projectId, content }

// lyric_lines - Synced lines
{ id, lyricsId, lineNumber, text, startTime, endTime }

Key Technologies

Component Technology
Frontend SvelteKit 2, Svelte 5, Tailwind CSS 4
Waveform wavesurfer.js 7.x
BPM Detection Web Audio API (peak detection)
Metadata music-metadata (server-side)
Backend NestJS 10, Drizzle ORM
Database PostgreSQL
Storage MinIO (dev) / Hetzner S3 (prod)
Auth mana-core-auth

Environment Variables

Backend (.env)

DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/mukke
MANA_CORE_AUTH_URL=http://localhost:3001
S3_ENDPOINT=http://localhost:9000
S3_REGION=us-east-1
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET=mukke-storage

Web (.env)

PUBLIC_MANA_CORE_AUTH_URL=http://localhost:3001
PUBLIC_BACKEND_URL=http://localhost:3010

Development Commands

# Database
pnpm --filter @mukke/backend db:push     # Push schema
pnpm --filter @mukke/backend db:studio   # Open Drizzle Studio

# Type checking
pnpm --filter @mukke/backend type-check
pnpm --filter @mukke/web type-check

# Build
pnpm --filter @mukke/backend build
pnpm --filter @mukke/web build