- Recognize Amazon Music in learned sources (classifyAsAmazon) and
AddSource dispatch, using CredentialTypeToken (cs1) not cs3
- Exclude Amazon from default sources: an empty-credential Amazon entry
triggers the speaker's AmazonController to fail JSON parsing with
MUSIC_SERVICE_ACCOUNT_LOGIN_FAILED; Amazon must only appear once a
real OAuth token is present
- Merge missing defaults into stored sources at request time so devices
with older Sources.xml still receive all current defaults
- Fix source providers ETag: was time.Now().UnixMilli() (always new),
now a content hash so If-None-Match/304 works correctly
- Include default sources fingerprint in GetETagForAccount so adding a
new default invalidates cached /full responses on speakers
- Refactor createLearnedSource into classifyLearnedSource +
classifyAsX helpers to reduce cyclomatic complexity below linter limit
- Add regression test for two-device scenario matching production setup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: improve Bose SoundTouch parity, Spotify integration, and data
reliability
- Update XML marshaling for ServicePreset and ServiceRecent to match
Bose parity requirements.
- Add support for adding music sources via
`/streaming/account/{account}/source`.
- Implement HandleBoseAccountToken for Spotify OAuth code exchange and
token persistence.
- Implement atomic file writes in the datastore to prevent data
corruption.
- Add startup logic to initialize default sources for existing devices.
- Expand test coverage with new parity regression and Spotify
integration tests.
---------
Co-authored-by: Junie <junie@jetbrains.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>