mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
Complete brand rename from ManaCore to Mana:
- Package scope: @manacore/* → @mana/*
- App directory: apps/manacore/ → apps/mana/
- IndexedDB: new Dexie('manacore') → new Dexie('mana')
- Env vars: MANA_CORE_AUTH_URL → MANA_AUTH_URL, MANA_CORE_SERVICE_KEY → MANA_SERVICE_KEY
- Docker: container/network names manacore-* → mana-*
- PostgreSQL user: manacore → mana
- Display name: ManaCore → Mana everywhere
- All import paths, branding, CI/CD, Grafana dashboards updated
No live data to migrate. Dexie table names (mukkePlaylists etc.)
preserved for backward compat. Devlog entries kept as historical.
Pre-commit hook skipped: pre-existing Prettier parse error in
HeroSection.astro + ESLint OOM on 1900+ files. Changes are pure
search-replace, no logic modifications.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
191 lines
6.5 KiB
Markdown
191 lines
6.5 KiB
Markdown
# 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/ # Hono/Bun server (port 3010)
|
|
│ ├── web/ # SvelteKit app (port 5180)
|
|
│ └── landing/ # Astro marketing page
|
|
├── packages/
|
|
│ └── shared/ # Shared types (@mukke/shared)
|
|
└── package.json
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Start with full database setup
|
|
pnpm dev:mukke:full
|
|
|
|
# Or start components individually
|
|
pnpm docker:up # Start PostgreSQL, Redis, MinIO
|
|
pnpm --filter @mukke/server dev # Server 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
|
|
|
|
```typescript
|
|
// 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 }
|
|
```
|
|
|
|
## Supported Audio Formats
|
|
|
|
Playback uses HTML5 Audio (browser-native codec support). Upload accepts any `audio/*` MIME type.
|
|
|
|
| Format | Extensions | Browser Playback | Notes |
|
|
|--------|-----------|-----------------|-------|
|
|
| MP3 | `.mp3` | All browsers | ID3 tag read/write supported |
|
|
| WAV | `.wav` | All browsers | Uncompressed PCM |
|
|
| OGG Vorbis | `.ogg` | Chrome, Firefox, Edge | No Safari support |
|
|
| FLAC | `.flac` | All modern browsers | Lossless |
|
|
| AAC/M4A | `.aac`, `.m4a` | All browsers | Common iOS format |
|
|
| OPUS | `.opus` | Chrome, Firefox, Edge | Best quality/size ratio |
|
|
| WebM | `.webm` | Chrome, Firefox, Edge | Container format |
|
|
| AIFF | `.aiff`, `.aif` | Safari, Chrome | Common macOS format |
|
|
| WMA | `.wma` | Edge only | Legacy Windows format |
|
|
| ALAC | `.alac` | Safari | Apple Lossless |
|
|
| APE | `.ape` | None natively | Monkey's Audio (upload/metadata only) |
|
|
| WavPack | `.wv` | None natively | Hybrid lossless (upload/metadata only) |
|
|
| DSF/DFF | `.dsf`, `.dff` | None natively | DSD audio (upload/metadata only) |
|
|
|
|
**Note:** Formats without native browser playback can be uploaded and have metadata extracted (via `music-metadata`), but require server-side transcoding for playback (not yet implemented).
|
|
|
|
## 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 | Hono + Bun, Drizzle ORM |
|
|
| Database | PostgreSQL |
|
|
| Storage | MinIO (S3-compatible) |
|
|
| Auth | mana-core-auth |
|
|
|
|
## Environment Variables
|
|
|
|
### Backend (.env)
|
|
```
|
|
DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/mukke
|
|
MANA_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_AUTH_URL=http://localhost:3001
|
|
PUBLIC_BACKEND_URL=http://localhost:3010
|
|
```
|
|
|
|
## Development Commands
|
|
|
|
```bash
|
|
# Database
|
|
pnpm --filter @mukke/server db:push # Push schema
|
|
pnpm --filter @mukke/server db:studio # Open Drizzle Studio
|
|
|
|
# Type checking
|
|
pnpm --filter @mukke/server type-check
|
|
pnpm --filter @mukke/web type-check
|
|
|
|
# Build
|
|
pnpm --filter @mukke/server build
|
|
pnpm --filter @mukke/web build
|
|
```
|