feat(chat): скрытие и плановое удаление диалогов

Админ может скрыть диалог тьютора (мягкое удаление), снять скрытие,
отменить плановое удаление или удалить диалог физически через TTL
общей настройки корзины.

- chat_threads: deleted_at, purge_at (init.sql, migration.sql, ensureChatTables)
- маршруты hide / restore / unschedule / permanent под requireAdmin + аудит
- purgeScheduledDeletions() + hardDeleteChatThread() с safeUnlink по вложениям
- скрытые диалоги видны тьютору как обычно; новое сообщение тьютора
  авто-возвращает диалог в список (thread_update по SSE)
- UI: кнопка «Скрытые» с бейджем и действия в карточке треда
- бэкап: deleted_at/purge_at в normalizeRestoreData
This commit is contained in:
dev
2026-10-05 19:32:56 +03:00
parent 1740c341a0
commit 7d282d4f3d
10 changed files with 333 additions and 20 deletions
+5
View File
@@ -274,6 +274,11 @@ function connectChatStream() {
try { p = JSON.parse(ev.data); } catch { return; }
if (p && typeof onChatMessageDelete === 'function') onChatMessageDelete(p);
});
chatStream.addEventListener('thread_update', ev => {
let p = null;
try { p = JSON.parse(ev.data); } catch { return; }
if (p && typeof onChatThreadUpdate === 'function') onChatThreadUpdate(p);
});
chatStream.onerror = () => {
if (chatStream) { chatStream.close(); chatStream = null; }
clearTimeout(chatReconnectTimer);