Детальний журнал адміністрування
GET /api/admin/audit та Socket.IO-подія audit_new_entry повертають однакові записи. Сервер сам створює аудит після успішних змін; окремого API для довільного запису в журнал немає. Доступ і термін зберігання не змінилися.
Формат API
{
id: 123,
adminId: '…',
adminLogin: 'editor',
operationType: 'edit_song_lyrics',
createdAt: 1790000000000, // Unix milliseconds
data: {
title: 'Пісня', artist: 'Виконавець',
action: 'update', // для текстів: update | clear | offset
details: { // необов'язковий блок, версія 1
version: 1,
changes: [
{ field: 'lyrics', before: 'Старий текст', after: 'Новий текст' },
{ field: 'lyricsStatus', before: 'plain', after: 'synced' },
{ field: 'offset', before: 0, after: -1.5 }
],
info: { source: 'bulk', force: false }
}
}
}changes містить лише змінені поля, а info — контекст операції. Значення можуть бути рядками, числами, булевими значеннями, масивами або null. failureReason може містити об'єкт локалізованого повідомлення. Назви полів та значення enum зберігаються незалежно від мови; клієнт локалізує їх при відображенні. null позначає відсутнє значення.
Клієнт показує ▼/▲ лише за наявності змін або контексту. Повні тексти зберігають перенесення рядків і таймкоди; довгі блоки мають власну прокрутку. Старі записи без details показуються у звичайному вигляді. Для невідомого типу операції слід залишити резервне відображення його ідентифікатора.
Операції й деталі
edit_song_lyrics:lyrics,lyricsStatus(none,plain,synced),offsetу секундах. Очищення та зміна лише зсуву мають окремі підписи. Діє також дляPUT /api/admin/lyrics/cacheіDELETE /api/admin/lyrics/cache.edit_song_meta: зміненіtitle,artist,album,year. Перенесення міститьmovedFromтаmovedTo(day/night) уdata.settings_save: один запис на збереження.data.sectionsперелічує фактично змінені розділи; поля мають шляхиbranding.byLang.uk.dayRadioName,branding.telegram_url,generation.MAX_DAY_DURATION,generation.GROUP_DEFS.A,radioHosts.backgroundMusicMode,artistArts.dayEnabledтощо. Зміна порядку ключів об'єкта не є зміною. Масиви виконавців показуються з попереднім/новим складом і доданими/вилученими елементами. Налаштування джинглів і фраз виділяються окремими блоками. Тривалість ефіру зберігається в секундах, сесій гостей — у хвилинах. Для обраних фраз додається назва файла, коли вона доступна.- Налаштування донатів також мають тип
settings_save, алеsections: ['donations']:currency,pricingMode,fixedPrice,pricePerSecond,tiersEnabled,tierCeiling,blockDonationsWhileChatting.info.clampedпозначає автоматичне обмеження рівня платіжним провайдером. group_create: назва, ефір і пісні вinfo.group_edit: зміни назви, ефіру, складу та порядку пісень.group_delete: назва групи.group_insert: назва, фактична кількість і фактичний порядок вставлених пісень. Пісні містять назву, виконавця та ID, щоб розрізняти однойменні записи.admin_create: початкові права.admin_privileges:privilegesAddedтаprivilegesRemovedуinfo.admin_login_change: попередній/новийlogin.admin_password_reset— окремий тип скидання пароля; зміна власного пароля, активація та видалення залишаються короткими подіями.artist_art_upload:data.replacedвідрізняє заміну від додавання. Для заміниinfoміститьpreviousFile,file,bytes,width,heightнового файла. Копії зображень у журналі не зберігаються.jingle_edit,background_music_edit,phrase_edit: зміниused(позначка «в ефірі») абоmode(перенесення). Групові операції записуються окремо для кожного успішно зміненого файла.queue_addіqueue_remove: пісня та позиція. Пропуск, прийняття/відхилення запиту й завантаження/видалення медіа залишаються короткими подіями.mode_switch:fromMode,targetMode,scheduledAt(Unix ms абоnull),timeZoneта необов'язковийscheduledTime. Запис описує прийнятий запит: на задану дату/час або якнайшвидше після поточного треку, а не підтвердження фактичного завершення перемикання.participant_mute: учасник і змінаmuted; охоплює модератора та ведучого, який заглушує гостя.host_queue_pause,host_queue_resume— успішна зміна стану основної черги.host_background_music: попередня/новаbackgroundTrack.guest_code_generate,guest_code_regenerate: строк дії таexpiresAt; деактивація, кік, бан, розбан і підключення/відключення залишаються короткими.donation_insert_failed: сума, валюта, ID замовлення й локалізована причина уinfo; якщо причина невідома, клієнт показує загальне пояснення.
Одночасна правка метаданих і тексту створює два записи. Збереження без фактичних змін не створює запису редагування. Попередні значення знімаються до зміни, нові — з результату серверного збереження після нормалізації.
Зміни контрактів запитів
POST /api/admin/song-editor/save приймає необов'язкове поле auditContext: { source: 'bulk', force: boolean }. Це лише позначка походження для аудиту: вона не змінює перевірки прав і не запускає пошук чи форсоване оновлення на сервері. Клієнт групового оновлення надсилає її при збереженні.
POST /api/admin/song-groups/:groupId/insert додатково повертає insertedSongIds: string[] у фактичному порядку вставлення поряд із insertedCount. Вставлення через admin_insert_song_group також створює такий самий запис аудиту; формат вхідної події не змінюється.
Деталі зберігаються в наявному JSON-полі даних операції для JSON і SQL провайдерів, тому міграція таблиць не потрібна. Паролі, хеші, токени, коди доступу та платіжні секрети в деталі не включаються. Власні перемикання мікрофона й зміни його гучності не логуються.