- spotify URL resolution was broken (500 NPE): preferPartnerApi +
customTokenEndpoint depended on dead spotify-tokener (-32000)
- remove tokener service from compose, remove dead SPOTIFY_* env from
bot container (bot code never used them)
- spotify metadata now resolves via standard client credentials,
playback is mirrored to SoundCloud via scsearch providers (ISRC/QUERY)
- AnimalApi: drop Caffeine URL cache (30s TTL made !neko return the same photo)
- RatingsRepository.getExtremeRating(guild, type, excluded, highest) with NOT IN
- !ratingoverview (super-admin only): per-category max/min, excluding bots + super-admin
- RatingsRepositoryTest: 7 new tests for getExtremeRating
- VoiceChannelManager: read trigger_channel_id/category_id live from ConfigRepository instead of caching at construction, so !voice-setup takes effect immediately without restart
- CounterManager: read channel_id/format live from config (same stale-cache fix); count members excluding bots
- CounterSetupPrefixCommand: use bot-excluding member count
- VoiceChannelManagerTest: lenient stubbing for live config reads
- TODO: remove quests, achievements, wiki from roadmap
- LevelRoleCommand: set/remove/clear role mappings per level
- LevelRoleService: reads from ConfigRepository, falls back to defaults
- LevelCommandRegistrar: wires new command
- Создана доменная структура feature/level/ с разделением на domain/service
- ынесены классы LevelUpResult, LevelProgress, UserStats, XpFormula
- Созданы сервисы: LevelService, MessageCooldownService, LeaderboardService
- еремещены команды и листенеры в feature/level/
- далены импорты AudioManager и мертвые ссылки на TTS
- бновлены все тесты
овая функциональность:
- енератор красивых профильных карточек (RankCardGenerator)
- оманда !profile для просмотра карточки с уровнем, XP, статистикой
- оманда !stop для безопасной остановки бота (только админы)
- обавлены ассеты: фоны, иконки, бейджи
Технические улучшения:
- ерсистентный кулдаун через UserStats.lastMessageTime
- бобщенные методы лидерборда через Comparator
- Graceful shutdown с сохранением всех данных
- Fallback на заглушки если ассеты не загрузились