Skip to content

Детальний журнал адміністрування ​

GET /api/admin/audit та Socket.IO-подія audit_new_entry повертають однакові записи. Сервер сам створює аудит після успішних змін; окремого API для довільного запису в журнал немає. Доступ і термін зберігання не змінилися.

Формат API ​

js
{
  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 провайдерів, тому міграція таблиць не потрібна. Паролі, хеші, токени, коди доступу та платіжні секрети в деталі не включаються. Власні перемикання мікрофона й зміни його гучності не логуються.