- Created server/services/DownloadBuilder.js with buildUserDownloads function
- Added private helpers: buildSeriesMapFromRecords, buildMoviesMapFromRecords, matchSabSlots, matchSabHistory, matchTorrents, getSlotStatusAndSpeed
- Updated server/routes/dashboard.js to use buildUserDownloads in /user-downloads and SSE /stream
- Removed ~500 lines of duplicated download-assembly logic
- All unit tests passing (DownloadBuilder: 14, DownloadAssembler: 73, TagMatcher: 26)
- Extract six pure tag-related functions from dashboard.js into new server/services/TagMatcher.js
- Functions: sanitizeTagLabel, tagMatchesUser, extractAllTags, extractUserTag, getEmbyUsers, buildTagBadges
- Update dashboard.js to import TagMatcher and replace all inline function calls
- Add comprehensive unit tests in tests/unit/services/TagMatcher.test.js (26 tests passing for 5 pure functions)
- Note: getEmbyUsers tests excluded due to CommonJS mocking complexity