Compare commits

...

3 Commits

Author SHA1 Message Date
Цвылев Александр Вадимович 61fe1bd26f chore: bump submodules — hardening + Subsonic lyrics + tests
mcma-backend fb7827d: post-review hardening (likes DISTINCT ON, batched reco
hydration, threaded/atomic transcode cache), Subsonic getLyricsBySongId, and
DB-free tests for lyrics/transcode/reco.
mcma-webui 22f7fd2: player listener cleanup + resume-on-URL-change, bounded
radio queue/exclude, bounded bulk re-enrich concurrency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 11:07:45 +03:00
Цвылев Александр Вадимович 048dd1d8bf chore: bump submodules to Phase 4 tips (radio/similar)
mcma-backend -> 591a938 (radio + similar, metadata fallback)
mcma-webui  -> ac6b76b (radio wired into the queue)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 02:41:19 +03:00
Цвылев Александр Вадимович 01b4267964 chore: sloppyslop working state — bump submodules + env/ignore/CLAUDE docs
Point mcma-backend + mcma-webui at their sloppyslop tips (lyrics, transcoding,
admin/storage/maintenance/instance UI, batch metadata, NowPlaying+lyrics).
Includes the CORS note in .env.example, TODO/ ignore, and the project CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 21:41:54 +03:00
5 changed files with 111 additions and 2 deletions
+5
View File
@@ -35,6 +35,11 @@ REFRESH_TOKEN_TTL_SECONDS=2592000
# Public self-service sign-up (POST /auth/register). Set to false to make
# accounts admin-only. Backend authority; pair with PUBLIC_ENABLE_REGISTRATION.
ALLOW_REGISTRATION=true
# CORS: browser origins allowed to call the API. Defaults to "*" (safe here —
# auth is a bearer token, not cookies). The web UI can connect cross-origin
# (e.g. the direct :8000 port, a LAN IP), which needs this. Restrict in
# hardened setups: CORS_ALLOW_ORIGINS=http://localhost:8881,http://localhost:3000
# CORS_ALLOW_ORIGINS=*
# media / storage (paths inside the container)
MEDIA_PATH=/data/media
+1
View File
@@ -1,6 +1,7 @@
.env
*.zip
plans/
TODO/
modern-sk/
data/
.DS_Store
+103
View File
@@ -0,0 +1,103 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this repo is
`mcma-compose` is the **dev-orchestration superproject** for *mycoolmusicapp* — a self-hosted music
app. It contains no application code of its own: `docker-compose.yml`, `nginx.conf`, `Makefile`, and
`.env.example`. The actual code lives in two **git submodules**:
- `mcma-backend/` — Python / FastAPI (async), arq background workers, Alembic migrations.
- `mcma-webui/` — TypeScript / React, built with Rsbuild.
Both submodules are pulled from `ssh://git@git.ollyhearn.ru:49239` (see `.gitmodules`). **They may be
empty** — clone with `git clone --recurse-submodules`, or run `git submodule update --init` in an
existing checkout, before you can touch or build app code.
## The stack
`make up` builds and starts six services (see `docker-compose.yml`):
| Service | Image / context | Role |
|----------|-------------------|------|
| `db` | postgres:16-alpine | PostgreSQL, data in `./data/pgdata` |
| `redis` | redis:7-alpine | arq broker + cache, data in `./data/redisdata` |
| `api` | `mcma-backend` | FastAPI via `uvicorn --reload` |
| `worker` | `mcma-backend` | `arq app.workers.arq_worker.WorkerSettings` background jobs |
| `webui` | `mcma-webui` | Rsbuild dev server with HMR |
| `nginx` | nginx:1.27-alpine | **single entrypoint**, reverse proxy |
Key architectural points that span multiple files:
- **nginx is the only public port.** It routes `/api/` and `/health` → `api:8000`, everything else
(including the `/rsbuild-hmr` websocket) → `webui:3000`. The browser never talks to webui directly;
HMR is proxied through nginx, which is why compose sets `RSBUILD_HMR_CLIENT_PORT` to `NGINX_PORT`.
- **The entrypoint is `http://localhost:8881`**, not `:80`. Compose maps `${NGINX_PORT:-8881}:80`
(README says `:80`, but the `.env.example` default is `8881`). `api:8000` is also exposed directly
for docs/debugging (`/docs`).
- **Source is bind-mounted** into `api`, `worker`, and `webui`, so edits in the submodules hot-reload
with no rebuild. Named-volume mounts (`/app/.venv`, `/app/node_modules`) shadow the host dir to
preserve the image's installed deps — if you change dependencies you must rebuild (`make build`).
- **`api` and `worker` share the same image** and both need `db` + `redis` healthy before starting.
- **`DATABASE_URL` / `REDIS_URL` are overridden inside compose** to use service names
(`db`, `redis`). The localhost values in `.env` are only the fallback for host-run processes.
- **Persistent state and media live under `./data/`** (gitignored): `pgdata`, `redisdata`, `media`,
`transcode-cache`, and `youtube` (drop a yt-dlp `cookies.txt` here — optional).
## Commands
Everything runs **inside the containers** via the `Makefile`, which wraps `docker compose exec`.
The stack must be up (`make up`) before `test`/`lint`/`migrate`/shell targets work. Run `make help`
for the full list.
```bash
make up # create .env from .env.example, build images, start the whole stack
make build # rebuild images (with cache); needed after dependency changes
make rebuild # rebuild with --no-cache
make down # stop + remove containers
make clean # down -v — DESTROYS db/redis volumes
make logs-api # tail a single service's logs (also logs, logs-webui)
make sh-api # bash into api (also sh-webui, db-shell, redis-cli)
```
Migrations (Alembic, run in the `api` container):
```bash
make migrate # alembic upgrade head
make makemigration m="add_tracks" # autogenerate a revision
make downgrade # roll back one
```
Quality — these shell out to the tools inside each container:
```bash
make test # test-api (pytest) + test-webui (npm test)
make test-api # pytest — for a single test: make sh-api, then `pytest path::test`
make test-webui # npm test
make lint # ruff check . (api) + npm run lint (webui)
make fmt # ruff format . (api) + npm run format (webui)
```
There is **no dev docker-compose for prod**. Prod images are built straight from each submodule's
`dockerfiles/Dockerfile.prod`:
```bash
make prod-build # builds mcma-backend:prod and mcma-webui:prod
```
## Environment
`.env` is a single combined file at the repo root, created from `.env.example` by `make env` /
`make up` (never committed; it's gitignored). It is injected into `api`, `worker`, and `webui`.
Backend features degrade gracefully when optional keys are unset:
- `ACOUSTID_API_KEY` + `MUSICBRAINZ_OWNER_EMAIL` — enable AcoustID/MusicBrainz metadata enrichment.
- `YOUTUBE_ENABLED` / `YOUTUBE_COOKIES_PATH` — YouTube Music source via yt-dlp.
- `ALLOW_REGISTRATION` (backend) must be kept in sync with `PUBLIC_ENABLE_REGISTRATION` (frontend).
## Working across submodules
When a change touches app behavior, the code is in `mcma-backend/` or `mcma-webui/` — commit there
first, then the superproject records the new submodule commit. Recent superproject history is mostly
`chore: bump mcma-backend/mcma-webui` commits that pin updated submodule SHAs.