# Minstrel Self-hosted music server with OpenSubsonic compatibility plus an extended API for server-side smart shuffle, a dual-like model (general + contextual), session-aware radio, ListenBrainz scrobble/similarity, and Lidarr integration. Go + Postgres, packaged as a Docker container. > State and intelligence belong on the server, not the client. ## Specs Authoritative v1 scope lives under [`docs/`](./docs): - [Server spec](./docs/smart-music-server-spec.md) — current implementation focus. - [Client spec](./docs/smart-music-client-spec.md) — Flutter companion app; work starts once the server reaches its Subsonic-compatible baseline. ## Development workflow - Day-to-day work happens on the `dev` branch (or feature branches merged into `dev`). - `main` is **protected** — changes land only via pull request from `dev`. - Production builds are cut by tagging a release (`v*`) off `main`. ## CI / container image Forgejo Actions handles: - Tests on push to `dev` and on PRs into `main`. - Container image build + push to the Forgejo registry on merge to `main` (`:main`) and on `v*` tags (`:`). Task and milestone tracking: Fable (`Minstrel` project, id 12). ## Development Minstrel has two concurrent dev processes: 1. **Backend:** `docker compose up` — starts Postgres and Minstrel on `:4533`. 2. **Frontend:** `cd web && npm install && npm run dev` — Vite dev server on `:5173` with HMR. The Vite dev server proxies `/api/*` and `/rest/*` to the backend on `:4533`, so session cookies work correctly when the SPA is loaded from the Vite origin. ### Production build `docker build -t minstrel .` runs the SvelteKit build inside a `node` stage, copies the output into the `golang` stage, and `//go:embed`s it into the final binary. The resulting container serves the SPA from `/` alongside the API surfaces. No separate static-file server is required.