# Workspace

## Overview

pnpm workspace monorepo для приложения **Global Music Scanner** —
веб-инструмента аудита дискографий артистов сразу из нескольких стрим-сервисов
(Apple Music, Deezer, Tidal, Qobuz) с обогащением через MusicBrainz и
Songlink/Odesli. Russian/English UI.

## Артефакты

- **`artifacts/global-music-scanner`** (`web`, путь `/`) — основное React + Vite
  SPA. Tailwind v4, 100% клиент, без бэкенда (кроме общего CORS-прокси).
- **`artifacts/api-server`** (`api`, путь `/api`) — минимальный Express-сервер.
  Сейчас единственный реальный эндпоинт — `/api/proxy` для запросов к Qobuz и
  Tidal (см. ниже). Заготовки под Drizzle/PostgreSQL пока не используются.
- **`artifacts/mockup-sandbox`** (`design`) — стандартный canvas-песочница
  Replit для прототипов компонентов.

## Stack

- **Monorepo tool**: pnpm workspaces (с `minimumReleaseAge: 1440` для security)
- **Node.js**: 24
- **TypeScript**: 5.9 (strict, см. `tsconfig.base.json`)
- **Frontend**: React 19, Vite 7, Tailwind v4, lucide-react, exceljs (lazy)
- **Backend**: Express 5, pino, express-rate-limit
- **Validation/codegen**: Zod (`zod/v4`), Orval (только заготовки, не используются
  Music Scanner'ом)

## Глобальная архитектура запросов

Apple Music / iTunes API и Deezer Public API поддерживают JSONP — браузер
обращается к ним напрямую. Tidal и Qobuz браузерные запросы блокируют;
используется каскад из `src/lib/cors-proxies.ts`:

1. **Внутренний прокси** `/api/proxy?url=…` (api-server). Whitelist хостов
   (`www.qobuz.com`, `api.tidal.com`), ручной обход редиректов с
   ре-валидацией хоста (защита от SSRF), rate-limit 60 req/min/IP.
2. **Direct fetch** — пропускается для Qobuz/Tidal через `skipDirectFetch: true`.
3. **RACE из 8 публичных CORS-прокси** — побеждает первый успешный ответ.

Подробнее: `artifacts/global-music-scanner/src/services/README.md`.

## Key Commands

- `pnpm run typecheck` — полный typecheck по всем пакетам
- `pnpm run build` — typecheck + build
- `pnpm --filter @workspace/global-music-scanner run dev` — фронтенд
- `pnpm --filter @workspace/api-server run dev` — api-server (tsx watch)
- `pnpm --filter @workspace/api-spec run codegen` — кодогенерация Orval (только
  если будете использовать API-контракты; сейчас Music Scanner их не трогает)

## Replit-specifics

- Каждый артефакт регистрируется через `.replit-artifact/artifact.toml` и
  стартует через workflow (НЕ через `pnpm dev` в корне).
- Глобальный reverse-proxy матчит пути от наиболее специфичных, поэтому
  `/api` (api-server) и `/` (frontend) живут параллельно без конфликтов.
- В application code используйте относительные URL — proxy и в dev, и в проде
  всё разрулит сам.

См. skill `pnpm-workspace` для общих конвенций монорепо.
