dcd19c01433a566a24ddc0aad172b0ff340f6ab4
Tag-supplied years were being passed straight to Postgres' date column without validation. Files with corrupt or 5+ digit years (seen in the wild on a couple of dozen albums) tripped SQLSTATE 22008 and the entire album upsert failed, dropping every track on those albums from the library. Validate the year is within 1..9999 before constructing the date. If it's outside that window, log a warning naming the album and year, and insert the album with no release_date — a soft field shouldn't take down the whole row. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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/:
- Server spec — current implementation focus.
- Client spec — Flutter companion app; work starts once the server reaches its Subsonic-compatible baseline.
Development workflow
- Day-to-day work happens on the
devbranch (or feature branches merged intodev). mainis protected — changes land only via pull request fromdev.- Production builds are cut by tagging a release (
v*) offmain.
CI / container image
Forgejo Actions handles:
- Tests on push to
devand on PRs intomain. - Container image build + push to the Forgejo registry on merge to
main(:main) and onv*tags (:<version>).
Task and milestone tracking: Fable (Minstrel project, id 12).
Releases
38
Languages
Go
39.2%
Kotlin
25%
Dart
14.2%
TypeScript
12%
Svelte
9.3%
Other
0.1%