edd198cd — fix(server): collage drawScaled uses center-crop instead of stretch
The collage cell scaler was nearest-neighbor stretching non-square album covers to fill a 300×300 cell. Operator saw it on the new_for_you system playlist because album-coherent variants pull fewer unique covers per cell, amplifying the warping. Replaced with cover-fit (preserve aspect, center-crop) matching every other UI surface. Existing collages won't re-render until the next 03:00 system-playlist rebuild.
Closes Scribe #614, #615, server half of #616 from the 2026-06-04 divergent-provider audit.
streamURL helper used everywhere /api/tracks/{id}/stream is built (was inline concat in playlists.go and cast_token.go). New streamURLWithExt for the .ext cast variant.
audioContentType in media.go is the canonical file_format → MIME lookup. mimeForFormat in cast_token.go is a thin wrapper that overrides the unknown-format fallback to audio/mpeg (Sonos rejects octet-stream). Adds mpeg/vorbis/wave aliases. Subsonic's contentTypeForFormat stays frozen.
coverart.ResolveAlbumPath extracted; api/media.go and subsonic/stream.go both delegate (was byte-identical duplicate).
28300e19 — perf(ci): turn off Postgres durability in integration tests
ALTER SYSTEM SET fsync = off / synchronous_commit = off / full_page_writes = off on the throwaway CI Postgres before migrations. Non-fatal so a perms surprise degrades to slow, never red.
Measured before/after on CI runs 474 vs 486:
Package
Before
After
Speedup
integration job wall
10m34s
4m27s
2.4×
go test portion
7m24s
2m16s
3.7×
internal/api
225s
29s
7.8×
internal/recommendation
39s
3.7s
10.5×
internal/playlists
39s
8.3s
4.8×
internal/coverart
21s
4.5s
4.7×
Test plan
CI green on dev (already verified at 28300e19)
On-device: stream URLs return real TrackDuration from Sonos (server change from PR #79; doubles down here)
System playlist collages re-render without stretching after next 03:00 rebuild (or force a regen via /api/playlists/system/{kind}/refresh)
Three commits on top of the prior PR #79 merge.
## Changes
### `edd198cd` — `fix(server): collage drawScaled uses center-crop instead of stretch`
The collage cell scaler was nearest-neighbor stretching non-square album covers to fill a 300×300 cell. Operator saw it on the `new_for_you` system playlist because album-coherent variants pull fewer unique covers per cell, amplifying the warping. Replaced with cover-fit (preserve aspect, center-crop) matching every other UI surface. Existing collages won't re-render until the next 03:00 system-playlist rebuild.
### `024493f2` — `refactor(server): unify stream URL builders + MIME tables + cover-path helper`
Closes Scribe #614, #615, server half of #616 from the 2026-06-04 divergent-provider audit.
- `streamURL` helper used everywhere `/api/tracks/{id}/stream` is built (was inline concat in `playlists.go` and `cast_token.go`). New `streamURLWithExt` for the `.ext` cast variant.
- `audioContentType` in `media.go` is the canonical `file_format → MIME` lookup. `mimeForFormat` in `cast_token.go` is a thin wrapper that overrides the unknown-format fallback to `audio/mpeg` (Sonos rejects octet-stream). Adds `mpeg`/`vorbis`/`wave` aliases. Subsonic's `contentTypeForFormat` stays frozen.
- `coverart.ResolveAlbumPath` extracted; `api/media.go` and `subsonic/stream.go` both delegate (was byte-identical duplicate).
### `28300e19` — `perf(ci): turn off Postgres durability in integration tests`
`ALTER SYSTEM SET fsync = off / synchronous_commit = off / full_page_writes = off` on the throwaway CI Postgres before migrations. Non-fatal so a perms surprise degrades to slow, never red.
**Measured before/after on CI runs 474 vs 486:**
| Package | Before | After | Speedup |
|---|---|---|---|
| integration job wall | 10m34s | 4m27s | 2.4× |
| `go test` portion | 7m24s | 2m16s | 3.7× |
| `internal/api` | 225s | 29s | 7.8× |
| `internal/recommendation` | 39s | 3.7s | 10.5× |
| `internal/playlists` | 39s | 8.3s | 4.8× |
| `internal/coverart` | 21s | 4.5s | 4.7× |
## Test plan
- [ ] CI green on `dev` (already verified at `28300e19`)
- [ ] On-device: stream URLs return real `TrackDuration` from Sonos (server change from PR #79; doubles down here)
- [ ] System playlist collages re-render without stretching after next 03:00 rebuild (or force a regen via `/api/playlists/system/{kind}/refresh`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Closes Scribe #614, #615, server half of #616 surfaced by the 2026-06-04 divergent-provider audit.
- streamURL helper now used everywhere /api/tracks/{id}/stream is built (was inline concat in playlists.go and cast_token.go); add streamURLWithExt for the .ext cast variant.
- audioContentType in media.go is the canonical file_format -> MIME lookup; mimeForFormat in cast_token.go is now a thin wrapper that overrides the unknown-format fallback to audio/mpeg (Sonos rejects octet-stream). Adds mpeg/vorbis/wave aliases. Subsonic's contentTypeForFormat stays frozen per docs.
- coverart.ResolveAlbumPath extracted; api and subsonic both delegate to it.
TRUNCATE-everything ResetDB before every test forces a commit fsync; the CI DB is rebuilt each run so durability buys nothing. ALTER SYSTEM via docker exec (the services: block can't override the postgres command line). Non-fatal so a perms surprise degrades to slow, never red.
Per the playbook the operator shared from another project (~17x speedup observed there). Measure before/after in the next two CI runs.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Three commits on top of the prior PR #79 merge.
Changes
edd198cd—fix(server): collage drawScaled uses center-crop instead of stretchThe collage cell scaler was nearest-neighbor stretching non-square album covers to fill a 300×300 cell. Operator saw it on the
new_for_yousystem playlist because album-coherent variants pull fewer unique covers per cell, amplifying the warping. Replaced with cover-fit (preserve aspect, center-crop) matching every other UI surface. Existing collages won't re-render until the next 03:00 system-playlist rebuild.024493f2—refactor(server): unify stream URL builders + MIME tables + cover-path helperCloses Scribe #614, #615, server half of #616 from the 2026-06-04 divergent-provider audit.
streamURLhelper used everywhere/api/tracks/{id}/streamis built (was inline concat inplaylists.goandcast_token.go). NewstreamURLWithExtfor the.extcast variant.audioContentTypeinmedia.gois the canonicalfile_format → MIMElookup.mimeForFormatincast_token.gois a thin wrapper that overrides the unknown-format fallback toaudio/mpeg(Sonos rejects octet-stream). Addsmpeg/vorbis/wavealiases. Subsonic'scontentTypeForFormatstays frozen.coverart.ResolveAlbumPathextracted;api/media.goandsubsonic/stream.goboth delegate (was byte-identical duplicate).28300e19—perf(ci): turn off Postgres durability in integration testsALTER SYSTEM SET fsync = off / synchronous_commit = off / full_page_writes = offon the throwaway CI Postgres before migrations. Non-fatal so a perms surprise degrades to slow, never red.Measured before/after on CI runs 474 vs 486:
go testportioninternal/apiinternal/recommendationinternal/playlistsinternal/coverartTest plan
dev(already verified at28300e19)TrackDurationfrom Sonos (server change from PR #79; doubles down here)/api/playlists/system/{kind}/refresh)🤖 Generated with Claude Code