Files
muzick/CLAUDE.md
kami 2ee9116d4d
Typecheck / typecheck (backend) (push) Has been cancelled
Typecheck / typecheck (workers) (push) Has been cancelled
Typecheck / typecheck (backend) (pull_request) Has been cancelled
Typecheck / typecheck (workers) (pull_request) Has been cancelled
docs: add the 2026-07-30 engineering review and CLAUDE.md, drop AUDIT.md
REVIEW-2026-07-30.md is the source for the preceding commits. AUDIT.md was
its superseded predecessor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 23:58:45 +04:00

4.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

muzick is a self-hosted music player + recommendation engine (deployed at muzick.kvmx.ru:5174). Three deployable units — backend/ (Fastify API), frontend/ (Vite React SPA), workers/ (BullMQ job processor) — plus Postgres, Redis, and Typesense. All wired together by docker-compose.yml.

Commands

Each unit is its own npm package; cd into it first.

# backend/ and workers/
npm run dev          # tsx watch
npm run typecheck    # tsc --noEmit (also runs as prebuild)
npm run build        # tsc

# backend/ only
npm test             # vitest run
npm run test:watch
npx vitest run src/services/generators.test.ts        # single file
npx vitest run -t "comfortGenerator"                  # single test by name

# frontend/
npm run dev          # vite
npm run build        # vite build
npm run typecheck

# whole stack
docker-compose up -d --build

There is no lint step. typecheck is the gate; the prebuild hook fails the build on type errors.

Architecture

Split by process, sharing one Postgres database. The backend serves the API and the frontend consumes it; the worker runs offline enrichment/analysis. They communicate only through Postgres (source of truth) and Redis (BullMQ queue). There is no shared code package — workers/ and backend/ each carry their own copy of things like queue.ts and pg clients.

  • backend/src/app.ts — the real entry point (server.ts just calls buildApp). Registers all routes, connects pg/redis/typesense, and runs several setInterval background jobs directly in-process: claim-fusion materialized-view refresh (10s), belief decay (hourly), forgotten-profile derivation (nightly). Auth is a single onRequest hook keyed on MUZICK_API_KEY / MUZICK_ADMIN_KEY (both optional — no keys means open); /api/admin/* requires the admin key specifically, /api/health is always exempt.
  • backend/src/services/ — business logic. db.service.ts owns schema application (ensureSchema/runMigrations run on every boot — the docker init-mount only fires on a fresh volume, so migrations live here). session-director.service.ts and generators.service.ts implement the recommendation/vibe logic.
  • workers/src/index.ts — one BullMQ Worker with a switch on job name (scan_library, metadata refresh, audio analysis, artist similarity, image enrichment…). Also registers cron repeatables (integrity sweep, dislike cleanup, stale-session reaper). External metadata clients live in workers/src/integrations/.
  • frontend/src/ — TanStack Router + TanStack Query. services/api.ts is the axios base; per-domain service files wrap endpoints. Zustand stores in store/ hold playback/vibe/toast state. components/ethos/ is the shared Ethos design-system UI.

Domain concepts (from README + spec comments)

  • Rolling Vibe — continuous stream interleaving owned library tracks with "probation" external discoveries. Managed by the session-director.
  • Belief / claim fusion — enrichment produces claims from multiple sources fused into a materialized view; beliefs decay over time. The in-process timers in app.ts keep this fresh.
  • Dislike lifecycle — multi-stage state machine; the worker's cleanup sweep advances it.

Deployment gotchas (see AGENTS.md)

  • Typesense is pinned to 0.25.1 — do not bump casually, the API breaks across majors.
  • Worker uses network_mode: host + a SOCKS5 proxy (SOCKS_PROXY_URL) for all external metadata calls (Last.fm, Discogs, MusicBrainz, etc.).
  • DB schema is backend/src/db/schema.sql, dropped into docker-entrypoint-initdb.d — only applied on a fresh volume. Schema changes for existing volumes must go through db.service.ts migrations.
  • Music dir is a read-only bind from /mnt/hdd1/media/Music/music.
  • Redis host inside compose is infra-redis (external infra-net network); the host-mode worker reaches it at 127.0.0.1:6379.
  • An older muzick.service systemd unit runs the pre-docker backend on port 5213 and may conflict — docker compose is the active deployment.

Working docs

PLANS.md, AUDIT.md, progress.md, and dated SESSION-*.md files track in-flight work and are not part of the running system.