A professional NestJS backend service for audio file upload, storage, and streaming.
- Audio File Upload: Support for MP3, WAV, FLAC formats
- File Validation: Type and size validation (max 50MB)
- Secure Storage: Local storage with unique filename generation
- Audio Streaming: Range request support for audio seeking
- Track Management: CRUD operations for track metadata
- Search & Filter: Search by title, artist, album; filter by genre
- Waveform Generation: Background processing with BullMQ, retry logic, and DLQ support
- API Documentation: Auto-generated Swagger documentation
- Database Integration: PostgreSQL with TypeORM
- Comprehensive Testing: Integration tests for all endpoints
/**
- Compression Measurement Script
- This script measures the effectiveness of HTTP response compression
- on key API endpoints by comparing response sizes with different
- compression algorithms (brotli, gzip, none).
- Usage: node scripts/measure-compression.js
- Requirements: Server must be running on the configured port */
- Framework: NestJS
- Database: PostgreSQL with TypeORM
- File Upload: Multer
- Validation: class-validator
- Documentation: Swagger/OpenAPI
- Testing: Jest with Supertest
- Node.js (v18+)
- PostgreSQL
- npm or yarn
- Install dependencies:
npm install- Set up environment variables:
cp .env.example .env
# Edit .env with your database and storage configuration- Set up the database:
# Create database
createdb tiptune
# The application will auto-create tables on first run (in development)
# Run search migration (full-text + fuzzy search)
npm run migration:run- Run the application:
# Development
npm run start:dev
# Production
npm run build
npm run start:prodOnce running, visit http://localhost:3001/api/docs for interactive API documentation.
API routes are versioned under /api/v1/* (except health probes and /api/version).
The normalized repository doc for the backend surface lives at api-documentation.md.
POST /api/v1/files/upload- Upload audio fileGET /api/v1/files/:filename- Download fileGET /api/v1/files/:filename/stream- Stream audio fileGET /api/v1/files/:filename/info- Get file informationDELETE /api/v1/files/:filename- Delete file
GET /api/v1/search?q=...&type=artist|track&genre=...&sort=...&page=...&limit=...- Full-text search (artists/tracks, filters, sort, pagination)GET /api/v1/search/suggestions?q=partial- Autocomplete suggestions
See src/search/README.md for details.
GET /api/v1/notifications- Get user notifications (paginated)GET /api/v1/notifications/unread-count- Get unread notification countPATCH /api/v1/notifications/:id/read- Mark notification as readPATCH /api/v1/notifications/read-all- Mark all notifications as read
See docs/notification-websocket-guide.md for complete WebSocket notification delivery guide.
POST /api/v1/tracks- Create track with file uploadGET /api/v1/tracks- Get all tracksGET /api/v1/tracks/public- Get public tracks onlyGET /api/v1/tracks/search?q=query- Search tracksGET /api/v1/tracks/artist/:artist- Get tracks by artistGET /api/v1/tracks/genre/:genre- Get tracks by genreGET /api/v1/tracks/:id- Get track by IDPATCH /api/v1/tracks/:id- Update trackPATCH /api/v1/tracks/:id/play- Increment play countDELETE /api/v1/tracks/:id- Delete track
GET /api/v1/tracks/:trackId/waveform- Get waveform data for a trackPOST /api/v1/tracks/:trackId/waveform/regenerate- Trigger waveform regenerationGET /api/v1/tracks/:trackId/waveform/status- Get waveform generation status
- MP3 (audio/mpeg)
- WAV (audio/wav)
- FLAC (audio/flac, audio/x-flac)
- 50MB (configurable via MAX_FILE_SIZE env var)
curl -X POST http://localhost:3001/api/tracks \
-F "file=@track.mp3" \
-F "title=My Track" \
-F "artist=John Doe" \
-F "genre=rock" \
-F "isPublic=true"# Run unit tests
npm test
# Run e2e tests
npm run test:e2e
# Run with coverage
npm run test:covTipTune uses environment variables for configuration.
For a complete list of variables, descriptions, and defaults, see the Canonical Environment Variable Reference.
src/
├── app.module.ts # Root module
├── main.ts # Application entry point
├── waveform/ # Waveform generation module
│ ├── waveform.controller.ts
│ ├── waveform.service.ts
│ ├── waveform-generator.service.ts
│ ├── waveform.processor.ts
│ ├── waveform.module.ts
│ ├── entities/
│ │ └── track-waveform.entity.ts
│ └── dto/
│ └── waveform.dto.ts
├── storage/ # File storage module
│ ├── storage.controller.ts
│ ├── storage.service.ts
│ ├── storage.module.ts
│ └── dto/
│ └── upload-file.dto.ts
├── tracks/ # Track management module
│ ├── tracks.controller.ts
│ ├── tracks.service.ts
│ ├── tracks.module.ts
│ ├── entities/
│ │ └── track.entity.ts
│ └── dto/
│ └── create-track.dto.ts
└── ...
- Create new module:
nest generate module feature - Add controller:
nest generate controller feature - Add service:
nest generate service feature - Add entities and DTOs as needed
# Run migrations (e.g. search indexes)
npm run migration:run
# Revert last migration
npm run migration:revertThe search feature requires the migration AddSearchIndexes (pg_trgm, tsvector columns, GIN indexes). See src/search/README.md.
This project is proprietary and confidential.