# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.10.0] - 2026-03-31

### Added

- **Local-dev auth rate limit configuration**: Added `AUTH_RATE_LIMIT_LOCAL_DEV_WINDOW_MS`, `AUTH_RATE_LIMIT_LOCAL_DEV_MAX`, and `AUTH_RATE_LIMIT_LOCAL_DEV_ELECTRON_MAX` so trusted localhost auth flows can use a much softer budget than public traffic.
- **Auth guard coverage for local frontend and Electron hints**: Added focused unit coverage for loopback callback targets, forwarded `localhost:3222` host headers, and Electron-marked local auth requests.

### Changed

- **Lenient auth throttling for localhost `:3222`**: Authentication rate limiting now distinguishes direct loopback traffic from trusted local frontend requests and applies a substantially higher allowance for requests clearly tied to `http://localhost:3222` or `http://127.0.0.1:3222`.
- **Electron-aware local auth throttling**: Requests carrying the `is-electron: true` hint now receive the most permissive local-development auth budget instead of sharing the normal external limit.
- **Forwarded auth request hints**: The frontend auth proxy and Spotify auth client now forward or synthesize the `is-electron` header so local Electron auth/session refresh traffic is identified correctly by the API.
- **Version bump**: Bumped application version from `1.9.4` to `1.10.0`.

## [1.9.3] - 2026-03-02

### Fixed

- **Body-based Spotify refresh token rotation for frontend clients**: `POST /auth/spotify/refresh` now returns the rotated `refreshToken` when the request uses body token fallback (`{ "refreshToken": "..." }`), allowing cross-origin/non-cookie clients to continue refreshing sessions beyond a single rotation.

### Changed

- **Refresh response payload convenience fields**: Refresh responses now also include flat Spotify token fields (`spotifyAccessToken`, `spotifyTokenType`, `spotifyExpiresIn`) in addition to the existing nested `spotify` object for easier frontend consumption.

## [1.9.2] - 2026-03-02

### Added

- **Vercel deployment runbook**: Added a dedicated `VERCEL_DEPLOYMENT.md` with project-linking, environment variable checklist, deploy steps, and post-deploy verification commands.

### Changed

- **Vercel build/install determinism**: Switched Vercel install/build commands to pnpm (`pnpm install --frozen-lockfile`, `pnpm run prisma:generate`) for lockfile-consistent deployments.
- **Vercel function runtime limits**: Added explicit function settings for `api/index.ts` (`memory: 1024`, `maxDuration: 30`) in `vercel.json`.
- **Public URL inference on Vercel**: Config now derives `appUrl` from `VERCEL_PROJECT_PRODUCTION_URL` or `VERCEL_URL` when `APP_URL` is not set, so generated docs/links use a real deployment URL instead of localhost.
- **Node runtime contract**: Added `engines.node` (`>=22 <26`) to make runtime expectations explicit for CI/CD and platform builds.

## [1.9.1] - 2026-03-02

### Fixed

- **Electron loopback OAuth refresh continuity**: Spotify callback handoff now includes `refresh_token` for trusted loopback frontend redirects (`localhost`/`127.0.0.1`/`::1`) in addition to native schemes, enabling desktop clients to refresh sessions without relying on readable CSRF cookies across origins.

### Changed

- **Refresh token handoff documentation**: Clarified `.env.sample` that `AUTH_FRONTEND_NATIVE_INCLUDE_REFRESH_TOKEN` controls refresh-token inclusion for both native and loopback callback targets.

## [1.9.0] - 2026-03-01

### Added

- **Native OAuth Redirect Allowlist**: Added `AUTH_FRONTEND_NATIVE_SCHEMES` to explicitly allow non-HTTP(S) frontend callback schemes (for example Electron deep links such as `darkfloor://...`) during Spotify PKCE login handoff.
- **Native Refresh Token Handoff Toggle**: Added `AUTH_FRONTEND_NATIVE_INCLUDE_REFRESH_TOKEN` to control whether native redirect payloads include `refresh_token` for non-cookie clients.

### Changed

- **Spotify OAuth Redirect Validation**: `frontend_redirect_uri` now validates HTTP(S) targets against `AUTH_FRONTEND_ORIGINS` and native scheme targets against `AUTH_FRONTEND_NATIVE_SCHEMES`.
- **Electron/Desktop OAuth Completion**: Native `frontend_redirect_uri` handoff now includes app refresh tokens by default so desktop clients can call `/api/auth/spotify/refresh` using body token fallback without relying on API-domain cookies.
- **Auth Redirect Log Redaction**: Callback redirect diagnostics now treat `refresh_token` as sensitive and redact it in logs.

## [1.8.3] - 2026-02-25

### Changed

- **Music Metadata Batch Efficiency**: `/music/tracks/batch` now uses the shared metadata cache with request de-duplication to reduce repeated Deezer API calls.
- **Playlist Mutation Throughput**: Playlist add/remove/reorder flows now use indexed bulk order updates and lighter pre-check queries to reduce DB work on large playlists.
- **Listening Stats Aggregation**: `/music/history/stats` now computes totals and top lists via database grouping with targeted track hydration instead of loading full history rows.
- **Playlist Conversion Throughput**: `/music/convert/playlist` now avoids per-track Deezer detail fan-out and batches Spotify track detail lookups via `/v1/tracks?ids=...`.
- **Artist/Album Track Fetching**: Artist/album music routes now fetch per-track Deezer details only when required fields are missing from base results.

### Fixed

- **Favorites Duplicate Handling**: Favorite add/remove now relies on atomic database outcomes (`P2002` conflict handling and delete-count checks) to avoid race-prone pre-check flows.
- **Batch Favorite Input Sanitization**: `POST /music/favorites/batch-check` now safely handles empty `trackIds` input and normalizes repeated/whitespace IDs before querying.

## [1.8.2] - 2026-02-25

### Added

- **Shared Auth Cookie Utility**: Added `parseCookieKeys()` helper used across auth handlers to avoid repeated cookie-header parsing logic.
- **Shared Deezer Metadata Mapper**: Added a reusable Deezer track → `ExtendedTrackMetadata` mapper for music services.

### Changed

- **Auth Debug Logging**: Replaced temporary `console.log` traces in auth callback/guard flows with structured Nest `Logger` calls.
- **Runtime Logging Consistency**: Standardized core logging in bootstrap, startup, auth module fallback warnings, and preview controller diagnostics to use Nest logger APIs.
- **Music Service Type Safety**: Tightened playlist/listening-history/favorites typing by replacing loose `any` usage with Prisma-backed typed structures.
- **Legacy Spotify Import Typing**: Added explicit Deezer response/match interfaces in playlist import flow to remove `Promise<any>` paths.
- **HexMusic Contract Typing**: Added explicit typed return contracts for playlist recommendation/search flows and explicit Prisma JSON persistence boundaries.
- **Crypto Fallback Typing**: Hardened Blowfish fallback module typing in Deezer integration and reduced unsafe dynamic import typing.
- **Base Type Hygiene**: Updated `DeezerTrack` index signature to `unknown` instead of `any`.

### Fixed

- **Duplicate Utility Logic**: Removed duplicated cookie parsing methods from auth controller and Spotify auth guard.
- **Repeated Metadata Mapping**: Removed repeated Deezer metadata object construction across multiple music services.

## [1.8.1] - 2026-02-23

### Added

- **Vercel OIDC Environment Placeholder**: Added `VERCEL_OIDC_TOKEN=<auto_injected_by_vercel>` to `.env.sample` under platform notes for clearer Vercel runtime expectations.

### Changed

- **Root Landing Route Resilience**: `GET /` now serves an inline fallback HTML portal if template rendering fails, avoiding runtime redirects and preserving direct homepage access.
- **Landing Page Error Path**: Updated landing-page controller tests to cover callback-based rendering and fallback HTML behavior.

### Fixed

- **Serverless View Resolution**: Bootstrap now resolves views from multiple candidate directories (`__dirname/views`, `src/views`, `dist/views`) to better support bundled/serverless runtime layouts.
- **Vercel Docs Asset Packaging**: Updated `vercel.json` to include `src/views/**` and `node_modules/swagger-ui-dist/**` in the function bundle so docs/landing assets are available at runtime.

## [1.8.0] - 2026-02-22

### Added

- **Typed Landing Page Template**: Added `src/landing-page.template.ts` and extracted the root-page UI rendering out of `AppService` into a dedicated, testable template module.
- **Runtime URL Utility**: Added `src/common/config/runtime-url.util.ts` to centralize `APP_URL`/port resolution and absolute URL construction.
- **ESLint TSConfig**: Added `tsconfig.eslint.json` to provide type-aware lint coverage for both `src/**/*.ts` and `test/**/*.ts`.

### Changed

- **APP_URL Precedence**: Standardized URL depiction to prioritize `APP_URL` across the landing page, Swagger/OpenAPI server metadata, startup logging, and public config output.
- **Landing Page Rework**: Rebuilt the entire front page with a new layout, clearer docs/spec access, and a route explorer that prefers the absolute OpenAPI URL derived from `APP_URL`.
- **Route Metadata Response**: `GET /routes` now computes totals and module counts dynamically and includes resolved docs/spec URL fields.
- **Swagger Server Listing**: Swagger now marks `APP_URL` as the primary public server and only adds localhost as an extra server in non-production environments.
- **Config Normalization**: `appUrl` config now trims trailing slashes for consistent URL joining.
- **Lint Parser Configuration**: ESLint now uses `tsconfig.eslint.json` via `parserOptions.project`, resolving IDE parser errors for spec files.

### Fixed

- **Strict TypeScript Decorator Imports**: Updated Express request/response imports in the Deezer preview controller to `import type` for strict decorator metadata compatibility.
- **Controller Typing Hygiene**: Tightened root controller typings (explicit return typing and nullish-coalescing cleanup) and refreshed tests to match the new landing page output.

## [1.7.2] - 2026-02-20

### Added

- **Service Token Exchange Endpoint**: Added `POST /auth/token` and `POST /api/auth/token` to exchange `UNIVERSAL_KEY` for a short-lived bearer token.
- **Scoped Service Token Routing**: Added scoped service-token support for `GET /auth/me` and `GET /cache/stats` (and their `/api/*` aliases) via route metadata.
- **Config Option**: Added optional `AUTH_SERVICE_TOKEN_TTL_SECONDS` environment variable for service-token TTL control.
- **Auth Coverage**: Added auth unit tests for service-token issuance and JWT strategy service-token validation.
- **Frontend Handoff**: Added `NEXTJS_AGENT_HANDOFF.md` with exact Next.js integration steps for token exchange and `/auth/me` + `/cache/stats` proxying.

### Changed

- **JWT Guard Behavior**: JWT guard now enforces service-token route allowlisting and scope checks to avoid broad access on unrelated protected routes.
- **Auth Profile Endpoint**: `GET /auth/me` now returns service-token context when authenticated by the new service token flow.
- **V2 Auth/Ops Route Aliases**: Added explicit aliases for `GET /api/v2/auth/me` and `GET /api/v2/cache/stats`.
- **PKCE Token Exchange**: Spotify PKCE token/refresh exchanges now omit `client_secret` and rely on `client_id + code_verifier` flow.
- **Token Logging Hygiene**: Startup Spotify access token logs are now redacted.

## [1.7.1] - 2026-02-19

### Changed

- **Auth Deployment Guidance**: Clarified `.env.sample` notes for frontend/API auth integration, including CSP `connect-src` requirements for cross-origin `/api/auth/me` and refresh calls.
- **Redis PKCE Configuration Note**: Clarified that Spotify PKCE serverless storage reads `REDIS_URL` only and supports TLS Redis URLs (`rediss://...`, including Upstash).

## [1.7.0] - 2026-02-19

### Added

- **Spotify OAuth2 + PKCE Flow**: Added secure authorization code flow endpoints `GET /api/auth/spotify` and `GET /api/auth/spotify/callback` with per-request PKCE verifier/challenge generation and state validation.
- **Session Refresh Endpoint**: Added `POST /api/auth/spotify/refresh` with app JWT reissue, refresh-token rotation, and automatic Spotify access token refresh.
- **Auth Hardening**: Added CSRF validation for refresh requests, auth endpoint rate limiting, and encrypted token utilities for sensitive OAuth secrets.
- **Serverless PKCE Store**: Added Redis-backed temporary PKCE session storage with TTL for multi-instance/serverless compatibility and in-memory fallback for local development.

### Changed

- **Auth Profile Endpoint**: `GET /api/auth/me` now returns current user details together with Spotify connection status metadata.
- **Spotify Token Storage**: Spotify refresh tokens are now stored encrypted, and legacy Spotify token refresh logic can read encrypted tokens.
- **CORS + Auth Config**: Added `X-CSRF-Token` as an allowed CORS header and introduced new auth/Spotify environment variables for scopes, cookie policy, rate limits, token encryption, and frontend redirect allowlisting.

## [1.6.1] - 2026-02-11

### Added

- **Readiness Checks**: `/health/ready` now includes database, cache, and external API reachability with structured diagnostics.

### Changed

- **QoL Route Responses**: Version endpoint now returns `{ name, version, commitSha, buildTime }`.

## [1.6.0] - 2026-02-11

### Added

- **Stream Query DTO Validation**: Added query DTOs for `/music/stream` and `/music/stream/direct` with strict type coercion and range checks.
- **Auth/Profile Redaction Tests**: Added unit coverage to ensure user/profile payloads never include passwords.
- **Stream Validation E2E Tests**: Added request-level tests for `/music/stream` query parsing and error responses.

### Changed

- **JWT Secret Handling**: Production now requires `JWT_SECRET` or `UNIVERSAL_KEY`; non-production uses a dev fallback with a warning.
- **Auth/Profile Payloads**: User/profile responses now return a safe, selected user shape (no password hashes).
- **API Key Enforcement**: Streaming endpoints now reject requests when `UNIVERSAL_KEY` is not configured.

## [1.5.4] - 2026-02-11

### Added

- **Deezer Playlist Tracks Endpoint**: Added `GET /api/music/playlists/:id` to fetch all playlist tracks in playlist order.

## [1.5.3] - 2026-02-09

### Added

- **Deezer Latest Releases Endpoint**: Added `GET /api/music/releases/latest` to fetch the newest editorial releases with optional `limit`.
- **Deezer Popular Playlists Endpoint**: Added `GET /api/music/playlists/popular` to fetch charting playlists with optional `limit`.
- **Deezer Playlists by Genre Endpoint**: Added `GET /api/music/playlists/by-genre` (best-effort search by genre, with fallback).
- **Deezer Genres (English) Endpoint**: Added `GET /api/music/genres` to return the Deezer genre list in English.

### Changed

- **Deezer API Base Path**: Renamed the Deezer API routes from `/api/deezer/*` to `/api/music/*`.

## [1.5.2] - 2026-02-07

### Added

- **Public Changelog Endpoint**: Exposed `GET /changelog` to serve `CHANGELOG.md` in Markdown and linked it from the landing page.

## [1.5.1] - 2026-02-07

### Changed

- **Route Reference Section**: Replaced the playful route cards with a concise route list and expandable request/response examples.
- **OpenAPI Sampling**: Improved sample extraction to include parameters, request bodies, and preferred response examples when available.

## [1.5.0] - 2026-02-02

### Added

- **Fileless Decrypted Streaming Cache**: Added an in-memory decrypted track cache to support serverless streaming without filesystem writes, including Range support for cached buffers.
- **Deezer Download Buffer Path**: Added buffer-based download + decrypt + tagging flow to enable fileless streaming.
- **Blowfish ESM Support**: Switched the Blowfish fallback to dynamic `import()` to work in ESM-only environments like Vercel.
- **Queue Sampling Controls**: Added `maxSeeds`, deterministic `sampling`, `seedStride`, and `queueMode` options for spice-up recommendations.

### Changed

- **Serverless Encrypted Streaming**: Encrypted tracks now stream from the decrypted in-memory cache instead of falling back to filesystem downloads.
- **Spice-up Seeding**: All input songs now influence recommendations by chunking seeds into multiple Spotify requests when needed.

## [1.4.1] - 2026-02-02

### Added

- **Spice-up Request Filters**: Added `excludeTrackIds`, `excludeDeezerIds`, and `excludeExplicit` options for Spotify spice-up requests to skip queued or explicit tracks.
- **Spice-up Response Envelope**: Standardized responses to return a consistent `tracks` array with `requestId`, keeping `recommendations` as a deprecated alias.
- **Recommendation Metadata**: Spice-up recommendations now include `deezerId`, deterministic `source`, and optional `reason`/`score` fields for UI.
- **Spice-up Trace Headers**: Responses now include `X-Request-Id` mirroring the body field for easier tracing.
- **Deezer ID Cache**: Added short-lived caching for Deezer track ID resolution to reduce repeated lookups.

### Changed

- **Spotify Track Fields**: Track payloads now include `explicit` and `isrc` when available.
- **Spice-up Responses**: `warnings` is always an array (may be empty) and spice-up POST endpoints return HTTP 200.
- **Spice-up Validation**: Normalize and validate exclusion filters for safer request handling.
- **Test Runs**: Set a localstorage file for Jest to avoid noisy Node warnings.

## [1.4.0] - 2026-01-29

### Changed

- **CORS Loopback Support**: Allow localhost/127.0.0.1/::1 origins (any port, http/https) to enable local health checks and dev tooling.
- **Music Streaming Decryption Fallback**: Added a JS Blowfish fallback to keep `/music/stream` working when OpenSSL legacy ciphers are unavailable, with `egoroof-blowfish` as a dependency.

## [1.3.1] - 2026-01-28

### Added

- **PM2 Cluster Mode Defaults**: Run 4 clustered instances in production with per-instance DB pool environment defaults (`DB_POOL_MAX`, `DB_POOL_MIN`, `DB_POOL_IDLE_TIMEOUT`, `DB_POOL_CONNECTION_TIMEOUT`).

### Changed

- **Prisma PG Pool Configuration**: `PrismaPg` now reads `DB_POOL_*` environment variables to size and tune the Postgres pool for clustered deployments.
- **Preview Image Inputs**: `/api/track/:id/preview` now accepts Deezer track URLs/URIs and uses shared query decoding for more resilient OG requests.
- **Node OpenSSL Compatibility**: Standardized `NODE_OPTIONS=--openssl-legacy-provider` across all primary runtime entrypoints:
  - Updated `npm` scripts (`start`, `dev`, `debug`, `start:prod`) to always launch Node/Nest with `--openssl-legacy-provider`.
  - Ensured PM2 production and development environments set `NODE_OPTIONS=--openssl-legacy-provider` via `ecosystem.config.cjs`.
  - Updated Docker production image to export `NODE_OPTIONS=--openssl-legacy-provider` so containerized runs use the legacy OpenSSL provider by default.

### Fixed

- **OG Preview Image Reliability**: Cover image selection now tries multiple sources (album/track/artist/Deezer md5) with timeouts and fallbacks, and supports non-Deezer track shapes.
- **Streaming Error Clarity**: Deezer download failures now return specific error messages (missing `DEEZER_ARL`/`d-fi-core`, 320kbps not available) instead of a generic upstream error.

## [1.3.0] - 2026-01-14

### Added

- **Default Preview Image Endpoint**: Added `GET /api/preview/default` route that generates a default darkfloor.art preview image featuring the Emily the Strange logo centered (slightly to the north) with "darkfloor.art" and "- lossless music -" text underneath. Uses the same ethereal dark background as track previews.

### Changed

- **Default Preview Image Layout**: Adjusted the default preview image to use a smaller icon (400px max instead of 500px) with increased top margin (60px offset instead of 40px) for better visual balance.
- **Default Preview Image Footer**: Updated footer text from "- lossless music" to "- lossless music -" with dashes on both sides.

### Fixed

- **Build Errors**: Fixed TypeScript compilation errors for Netlify serverless function by:
  - Excluding `netlify` folder from TypeScript build in `tsconfig.build.json`
  - Adding `@ts-expect-error` suppressions for `serverless-http` (no TypeScript definitions) and `dist/src/bootstrap` import (not available during build, only at runtime)
  - Updated `nest-cli.json` to explicitly use `tsconfig.build.json`
  - The Netlify function now compiles separately during Netlify's build process

## [1.2.2] - 2026-01-22

### Added

- **Netlify Deployment Support**: Full serverless deployment configuration for Netlify
  - Created `netlify/functions/api.ts` serverless function handler using `serverless-http`
  - Added `netlify.toml` configuration with routing rules to route all requests to serverless function
  - Configured function timeout to 30 seconds for longer-running operations
  - Added redirect rule to route all paths (`/*`) to `/.netlify/functions/api`
  - Included necessary files (`dist/**`, `node_modules/**`, `prisma/**`) in function bundle
  - Function uses same `createApp()` bootstrap as Vercel for consistency

- **Automatic Serverless Detection for Music Streaming**: Intelligent environment detection
  - Added `isVercelEnvironment()` function to detect Vercel/serverless environments
  - `/music/stream` endpoint automatically switches to direct streaming on Vercel/Netlify
  - No filesystem operations on serverless platforms (streams directly from Deezer)
  - Traditional servers continue using filesystem caching for better performance
  - Same route works everywhere - no code changes needed based on deployment platform

- **Serverless HTTP Support**: Added `serverless-http` package for Netlify compatibility
  - Wraps Express apps for serverless environments
  - Handles Netlify event format conversion automatically
  - Maintains compatibility with existing Express-based NestJS setup

### Changed

- **Node.js Version Requirements**: Updated to support Node.js 24.x
  - Updated `.nvmrc` from `18` to `24`
  - Updated `package.json` engines from `">=18.0.0 <22.0.0"` to `">=24.0.0"`
  - Required for Prisma 7.3.0 compatibility (requires Node 20.19+, 22.12+, or 24.0+)

- **Build Process**: Moved `prisma generate` from postinstall to build command
  - Changed `"build": "nest build"` to `"build": "prisma generate && nest build"`
  - Changed `"postinstall": "prisma generate"` to `"postinstall": "prisma generate || true"`
  - Prevents build failures when Prisma can't generate during install phase
  - Ensures Prisma generates with proper environment variables during build

- **Dependency Organization**: Moved build-critical packages to dependencies
  - Moved `dotenv` from `devDependencies` → `dependencies` (required for Prisma config)
  - Moved `ts-node` from `devDependencies` → `dependencies` (required for TypeScript config loading)
  - Moved `typescript` from `devDependencies` → `dependencies` (required for Prisma TypeScript config)
  - Ensures packages are available during Netlify production builds (which skip devDependencies)

- **TypeScript Return Types**: Fixed controller method return types for NestJS compatibility
  - Changed `streamMusic()` return type to `Promise<void>` (uses `@Res()` decorator)
  - Changed `streamMusicDirect()` return type to `Promise<void>` (uses `@Res()` decorator)
  - Fixed all `return res.status().json()` calls to use `res.status().json(); return;` pattern
  - Resolves TypeScript compilation errors (TS2322) in strict mode

- **Type Safety Improvements**: Added type guards for stream result handling
  - Added runtime check for `filePath` property before destructuring
  - Prevents TypeScript error (TS2339) when accessing properties on union types
  - Improved error handling for unexpected stream result types

- **Logging**: Replaced `console.log` with NestJS Logger service
  - Changed `console.log()` to `this.logger.log()` in `music.service.ts`
  - Maintains consistent logging format and levels across application

### Fixed

- **TypeScript Compilation Errors**: Fixed all TypeScript errors preventing Netlify builds
  - Fixed TS2339: Property 'filePath' does not exist (added type guard)
  - Fixed TS2322: Type 'Response' not assignable (changed return types to `Promise<void>`)
  - All methods using `@Res()` now properly return `void` instead of Response objects

- **Netlify Build Configuration**: Resolved Prisma and TypeScript loading issues
  - Fixed Prisma config loading by ensuring `ts-node` and `dotenv` are in dependencies
  - Fixed Node version compatibility by updating to Node 24
  - Fixed build command to run Prisma generate before NestJS build

- **Serverless Streaming**: Fixed automatic detection and routing
  - Vercel detection now works correctly using `VERCEL`, `VERCEL_ENV`, and `VERCEL_URL` environment variables
  - Direct streaming mode properly handles encrypted vs non-encrypted tracks
  - Error handling improved for unsupported encrypted tracks in serverless mode

### Technical Details

- Netlify function handler uses `serverless-http` to wrap Express app
- Function caches handler instance for improved cold start performance
- All routes are redirected to single serverless function via Netlify redirects
- Build process ensures Prisma client is generated before TypeScript compilation
- TypeScript strict mode compliance across all controller methods

## [1.1.0] - 2026-01-22

### Added

- **Vercel Deployment Support**: Full serverless deployment configuration
  - Added `api/index.ts` serverless function entrypoint using ExpressAdapter
  - Created `vercel.json` configuration for routing all requests to serverless function
  - Extracted `src/bootstrap.ts` with reusable `createApp()` function for both local and serverless environments
  - Added `postinstall` script to automatically run `prisma generate` during Vercel builds
  - Function configured with 30-second max duration for longer-running operations
  - Cached Express server instance for improved cold start performance

- **Enhanced Preview Image Generation**: Complete redesign of social media preview images
  - **Ethereal Dark Background**: Multi-layered gradient system with purple/cyan glows
    - Base dark background (`#0a0a0f`)
    - Primary radial glow from center (purple → cyan) using `lighter` composite operation
    - Secondary cyan glow from top-left corner
    - Linear overlay gradient for depth using `overlay` composite operation
    - Vignette effect darkening edges (`rgba(0, 0, 0, 0.6)`)
  - **Album Cover Enhancements**:
    - 400x400px album cover on left side with rounded corners (20px radius)
    - Cyan glow border with shadow effects
    - Musical note (♪) placeholder for missing covers
  - **Text Rendering Improvements**:
    - Track title: 64px bold system-ui, white with cyan glow and shadow offsets
    - Artist name: 48px system-ui, light purple with purple glow
    - Album name: 36px system-ui, muted with cyan glow
    - All text uses consistent `textBaseline: 'top'` for proper alignment
    - Shadow offsets (2px horizontal, 4px vertical) for depth
  - **Visual Elements**:
    - Cyan gradient accent line under text area
    - Duration display (MM:SS format) in bottom right
    - Footer: "Listen on darkfloor.one now" with subtle cyan glow

- **Comprehensive ESLint & Prettier Configuration**: Professional code quality setup
  - Enhanced ESLint flat config with TypeScript type-checked rules
  - Type safety rules: consistent type imports, nullish coalescing enforcement
  - Code quality rules: prefer const, arrow functions, template literals
  - NestJS-optimized rules: disabled `class-methods-use-this` and `max-classes-per-file`
  - Prettier integration with auto-formatting on save
  - Comprehensive `.prettierignore` for build outputs and generated files

### Changed

- **Preview Image Service**: Complete refactor with fixed composite operations
  - Fixed invisible gradients by changing `screen` → `lighter` for radial glows
  - Fixed darkening issues by changing `multiply` → `overlay` for depth gradients
  - Improved `roundRect()` helper to use `arcTo()` for more precise rounded corners
  - All fonts changed from `Arial` to `system-ui` for better rendering
  - Enhanced shadow effects with proper offsets for all text elements
  - Improved error handling and placeholder fallbacks

- **Code Quality Improvements**:
  - Replaced logical OR (`||`) with nullish coalescing (`??`) for safer optional chaining
  - Fixed all type assertion issues and unnecessary type casts
  - Improved import organization and consistency
  - Enhanced error handling with proper type guards

- **Bootstrap Architecture**: Refactored application initialization
  - Extracted shared bootstrap logic into `src/bootstrap.ts`
  - `main.ts` now uses `createApp()` for local/server deployment
  - `api/index.ts` uses `createApp()` with ExpressAdapter for serverless
  - Maintains all existing functionality (CORS, Swagger, OpenAPI routes)

### Fixed

- Fixed composite operation issues causing invisible background gradients
- Fixed text rendering with proper shadow offsets and quality settings
- Fixed type safety issues in preview image and controller code
- Fixed formatting inconsistencies across codebase
- Removed unnecessary type assertions that didn't change expression types

### Technical Details

- Preview images now generate 40-60KB PNG files with visible ethereal backgrounds
- Serverless function uses cached Express instance to reduce cold start overhead
- ESLint configuration uses project service for efficient type checking
- All code now follows consistent formatting with Prettier integration
- Type-safe codebase with comprehensive ESLint rules for NestJS patterns

## [1.0.1] - 2026-01-22

### Added

- **Routes Documentation**: Added preview image endpoints to the routes documentation
  - `POST /api/track/preview` - Generate preview image from track query, ID, or object
  - `GET /api/track/:id/preview` - Generate preview image from Deezer track ID
  - Routes now appear in the `/routes` endpoint response

### Changed

- **PM2 Process Name**: Renamed PM2 process from `darkfloor-api` to `darkfloor-api-v2`
  - Updated `ecosystem.config.cjs` with new process name
  - Updated all PM2 npm scripts to use `darkfloor-api-v2`
  - Prevents conflicts with existing `darkfloor-api` process running on the same server
  - All PM2 management commands (`pm2:restart`, `pm2:stop`, `pm2:logs`, etc.) now target the new process name

## [1.0.0] - 2026-01-20

### Added

- **CORS Configuration**: Comprehensive CORS setup for production deployment
  - Configured allowed origins: `starchildmusic.com`, `www.starchildmusic.com`, `darkfloor.art`, `www.darkfloor.art`, and `localhost:3000` for development
  - Proper CORS headers: `Access-Control-Allow-Origin` (validated against whitelist, not wildcard), `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`, `Access-Control-Allow-Credentials`, `Access-Control-Max-Age` (86400 seconds)
  - Automatic OPTIONS preflight request handling with 200 OK response

- **Health Check Endpoint**: New `/health` endpoint providing critical system status
  - Returns JSON with overall health status (`healthy` or `degraded`)
  - Database connectivity check with latency measurement
  - Process uptime and environment information
  - Timestamp for monitoring and debugging

- **Enhanced Smart Tracks Requests (Spice-Up)**: Major improvements to recommendation generation
  - **Multi-Strategy Search**: Intelligent track search with multiple fallback strategies
    - Full query search (name + artist + album)
    - Artist + track search
    - Track-only search
    - Artist-only search for popular tracks
  - **Fuzzy Matching & Scoring**: Advanced string similarity matching with confidence scoring
    - Confidence scores (0-1) for each search result
    - Weighted matching based on track name (40%), artist (40%), album (20%), and popularity (10%)
    - Minimum confidence threshold (0.3) to ensure quality matches
  - **Intelligent Diversity Modes**: Enhanced recommendation diversity with four modes
    - `strict`: Conservative seeds, tight ranges for similar recommendations
    - `balanced`: Moderate variety with good seed coverage (new default)
    - `diverse`: Maximum seeds and wide ranges for high variety
    - `wild`: Experimental combinations with extreme ranges for maximum exploration
  - **Dynamic Seed Selection**: Adaptive seed counts based on input size
    - Scales seed count with input size using square root scaling
    - Capped at maximum of 5 tracks and 4 artists for optimal recommendations
  - **Performance Optimizations**:
    - **Parallel Processing**: Song searches now run in parallel using `Promise.all()` instead of sequential processing
    - **Smart Caching**: TTL-based in-memory caching for search results (10 minutes) and recommendations (30 minutes)
    - Automatic cache cleanup to prevent memory bloat
  - **Enhanced Error Handling**:
    - Partial success responses when some songs can't be found
    - Detailed error messages with specific failure reasons
    - Confidence reporting for each song search
    - Warning system listing specific issues
  - **Cross-Platform Support**: Unified spice-up endpoint combining multiple platforms
    - New `/api/spotify/recommendations/spice-up/unified` endpoint
    - Supports Spotify, Last.fm, and Deezer (extensible)
    - Intelligent fallback: prefers Spotify, falls back to other platforms if needed
  - **Seed Quality Analysis**: Comprehensive metrics and feedback
    - Overall seed quality score (0-1) with detailed breakdown
    - Artist diversity analysis
    - Popularity range analysis (min, max, average)
    - Audio feature diversity scoring
    - Actionable recommendations for improving seed quality
  - **Enhanced Response Format**:
    - Detailed song results with match confidence, search method, and found track
    - Seed quality metrics with actionable feedback
    - Platform tracking showing which platforms were used
    - Structured warnings and error details

### Changed

- **BREAKING**: Default diversity mode changed from `normal` to `balanced` for better default recommendations
- **BREAKING**: Spice-up response format enhanced with additional fields:
  - `foundSongs`: Number of songs successfully found
  - `songResults`: Detailed results for each input song
  - `seedQuality`: Seed quality analysis metrics
  - `warnings`: Warning messages for partial failures
- CORS configuration updated to use specific origin validation instead of wildcard patterns
- Improved diversity parameter calculation with adaptive ranges based on input size
- Enhanced audio feature ranges including tempo, liveness, speechiness, and acousticness

### Technical Details

- Search strategies now use confidence-based selection with multiple fallback patterns
- Cache keys generated from query parameters to maximize cache hit rates
- Parallel search execution reduces total request time significantly
- Seed quality analysis provides actionable insights for users
- Cross-platform endpoint architecture allows easy extension to additional music services

## [0.4.5] - 2026-01-17

### Changed

- Bumped package version for the January 17, 2026 release

## [0.4.3] - 2025-12-03

### Added

- **OpenAPI JSON Download**: Added `/openapi.json` endpoint to download OpenAPI specification in JSON format
  - Endpoint serves the OpenAPI specification as a downloadable JSON file
  - Follows the same pattern as the existing `/openapi.yaml` endpoint
  - Automatically generates filename based on hostname (e.g., `songbird.starchildmusic.com.json`)
  - JSON is formatted with proper indentation for readability

### Technical Details

- OpenAPI JSON endpoint now serves a properly formatted JSON file
- OpenAPI JSON endpoint now uses the same hostname as the OpenAPI YAML endpoint

## [0.4.2] - 2025-12-02

### Added

- **OpenAPI JSON Download**: Added `/openapi.json` endpoint to download OpenAPI specification in JSON format
  - Endpoint serves the OpenAPI specification as a downloadable JSON file
  - Follows the same pattern as the existing `/openapi.yaml` endpoint
  - Automatically generates filename based on hostname (e.g., `songbird.starchildmusic.com.json`)
  - JSON is formatted with proper indentation for readability

- **Docker Support**: Full Dockerization of the application
  - Multi-stage Dockerfile for optimized production builds
  - `.dockerignore` file to exclude unnecessary files from Docker context
  - Health check endpoint for container monitoring
  - Docker Compose example with PostgreSQL database
  - Comprehensive Docker documentation in README
  - Support for volume mounts for persistent data (output/downloads, logs)
  - Automatic Prisma client generation in Docker build process

### Technical Details

- Dockerfile uses Node.js 20 Alpine for smaller image size
- Multi-stage build separates dependencies, build, and production stages
- Production stage only includes runtime dependencies
- Health check verifies API availability on container startup
- Environment variables can be provided via `.env` file or Docker environment

## [0.4.1] - 2025-12-02

### Changed

- UNIVERSAL_API_KEY is now UNIVERSAL_KEY

## [0.4.0] - 2025-12-02

### Changed

- **BREAKING**: Unified authentication keys into a single `UNIVERSAL_KEY` environment variable
  - Replaced `JWT_SECRET` with `UNIVERSAL_KEY` (JWT secret now uses the same key)
  - Removed unused `DEEZER_API_KEY` from validation schema
  - `UNIVERSAL_KEY` is now used for both API key validation and JWT token signing
  - Updated configuration and documentation to reflect this change
  - Minor fixes, openapi.yaml now reflects the url of the server
  - ecosystem.config.js is now ecosystem.config.cjs
  - fixed file annotation headers, updated tree.txt

### Migration Guide

If you're upgrading from 0.3.0 or earlier:

- Remove `JWT_SECRET` and `DEEZER_API_KEY` from your `.env` file
- Ensure `UNIVERSAL_KEY` is set in your `.env` file
- The same key value can be used for all authentication purposes

## [0.3.0] - 2025-12-02

### Changed

- **BREAKING**: Enabled strict TypeScript compiler options for better type safety
  - Enabled `strictNullChecks`, `noImplicitAny`, `strictBindCallApply`, `forceConsistentCasingInFileNames`, and `noFallthroughCasesInSwitch`
  - This improves type safety across the entire codebase

### Fixed

- Removed all `eslint-disable` comments and replaced with proper TypeScript types
- Fixed type safety issues in `music.service.ts` by adding proper return types and type guards
- Fixed type safety issues in `deezer-integration.service.ts` by:
  - Adding proper interface for `d-fi-core` API
  - Replacing `any` types with `DeezerSearchResponse` and proper type guards
  - Adding null checks for optional API
- Fixed type safety issues in `lastfm.service.ts` by:
  - Adding generic type parameter to `makeRequest` method
  - Replacing `any` return types with proper Last.fm API response types
  - Adding proper type guards for Last.fm track and artist data
- Fixed type safety issues in `playlist-conversion.service.ts` by:
  - Replacing `any[]` with proper `DeezerTrackSearchResult[] | SpotifyTrack[]` types
  - Adding proper type guards for API responses
- Fixed type safety issues in `metadata-cache.service.ts` by:
  - Replacing `any` with `DeezerTrackSearchResult` type
  - Adding proper error type checking
- Removed eslint-disable comments from all controllers:
  - `music.controller.ts`
  - `playlist.controller.ts`
  - `favorites.controller.ts`
  - `listening-history.controller.ts`
- Removed eslint-disable comments from services:
  - `listening-history.service.ts`
  - `playlist.service.ts`

### Technical Details

- All service methods now have explicit return types
- All API responses are properly typed using interfaces from `types.ts`
- Error handling uses proper type guards (`error instanceof Error`)
- Dynamic imports (like `d-fi-core`) are properly typed with interfaces
- All `any` types have been replaced with proper TypeScript types

## [0.2.2] - 2025-12-01

### Fixed

- Fixed TypeScript configuration by removing deprecated `ignoreDeprecations` and `baseUrl` options
- Fixed 90 error handling type errors across all service files by adding proper type narrowing for caught errors
- Fixed 42 DTO property initialization errors by adding definite assignment assertions
- Improved error handling in Deezer, Last.fm, Spotify, and Music services with proper AxiosError type checking
- Enhanced Prisma error handling with explicit type assertions for better type safety

### Changed

- Updated error handling to use `error: unknown` with proper type guards
- Added AxiosError imports to HTTP service files for better type safety
- All DTO classes now use definite assignment assertions (`!`) for required properties

### Technical Details

- Total of 132 TypeScript errors resolved
- Updated files across multiple modules: logging, deezer, lastfm, spotify, music
- All DTOs updated for strict TypeScript compliance

## [0.2.1] - Previous Release

### Added

- Playlist conversion feature in music module
- Deezer track downloading setup
- Enhanced music module with Deezer integration
- User features and playlist management

### Changed

- Enhanced AppController and AppService with new API route functionality
- Updated TypeScript configuration
- Refactored HTML generation in AppService
# Changelog

All notable changes to this project will be documented in this file.

## [1.9.4] - 2026-03-12

### Added
- Added MVP Spotify playlist import backend support via `POST /music/playlists/import/spotify`.
- Added import request validation DTO for Spotify playlist ID or URL input.
- Added deterministic import reporting with matched, unmatched, and skipped counts plus ordered unmatched rows.
- Added focused unit tests for Spotify playlist import behavior and response stability.

### Changed
- Bumped application version from `1.9.3` to `1.9.4`.
