feat(chat): правка и удаление сообщений
- PUT/DELETE /api/chat/threads/:id/messages/:messageId под requireAuth+chatLimiter, доступ через chatMessageFor (тред + принадлежность сообщения) - править может только автор (админу чужое сообщение 403), удалять — автор или админ - мягкое удаление: body='', вложения каскадом из БД + safeUnlink по path, счётчик непрочитанных уменьшается на 1 у своей стороны (GREATEST(col-1,0)) - refreshChatThreadPreview() пересчитывает превью треда по последнему живому сообщению - SSE: publishChat с type, список типов валидируется через CHAT_EVENTS; новые message_update/message_delete подписаны в connectChatStream (admin.js) - аудит chat.message.update с textDiff и chat.message.delete без текста - колонки edited_at/deleted_at в db/init.sql, db/migration.sql, ensureChatTables() и в normalizeRestoreData + restore-INSERT — удалённые сообщения не воскресают - фронтенд: кнопки правки/удаления по наведению, модалка правки (Ctrl+Enter), метка «изменено», плейсхолдер «Сообщение удалено», обновление по SSE - покрытие в api.smoketest.js (правка/удаление/403/400/404) и backup.selftest.js
This commit is contained in:
@@ -956,6 +956,17 @@ body.report-card-open .report-fields{display:flex}
|
||||
.msg-who{font-weight:600;color:var(--text);font-size:.78rem}
|
||||
.msg-role{border:1px solid var(--border);border-radius:5px;padding:0 5px;font-size:.65rem}
|
||||
.msg-time{white-space:nowrap}
|
||||
.msg-edited{font-style:italic}
|
||||
.msg-actions{display:inline-flex;align-items:center;gap:2px;opacity:0;transition:opacity .15s}
|
||||
.msg:hover .msg-actions,.msg-actions:focus-within{opacity:1}
|
||||
.msg-act{background:none;border:none;padding:2px;border-radius:6px;color:var(--muted);cursor:pointer;display:inline-flex}
|
||||
.msg-act:hover{color:var(--accent);background:var(--bg)}
|
||||
.msg-act-del:hover{color:#ef4444}
|
||||
.msg-act svg{width:13px;height:13px}
|
||||
.msg-deleted-body{font-style:italic;color:var(--muted)}
|
||||
.chat-edit-modal{max-width:560px}
|
||||
.chat-edit-modal textarea{min-height:110px;max-height:40dvh}
|
||||
.chat-edit-modal textarea:focus{border-color:var(--accent)}
|
||||
.msg-body{font-size:.88rem;line-height:1.45;white-space:pre-wrap;word-break:break-word}
|
||||
.msg-files{display:flex;flex-wrap:wrap;gap:8px}
|
||||
.msg-file{display:flex;align-items:center;gap:8px;background:var(--bg);border:1px solid var(--border);border-radius:9px;padding:7px 10px;font-size:.78rem;color:var(--text);text-decoration:none;max-width:230px;min-width:0;transition:border-color .15s}
|
||||
@@ -987,6 +998,10 @@ body.report-card-open .report-fields{display:flex}
|
||||
.chat-hint{font-size:.75rem;margin:0}
|
||||
.chat-new-modal{max-width:420px}
|
||||
|
||||
@media(hover:none){
|
||||
.msg-actions{opacity:1}
|
||||
}
|
||||
|
||||
@media(max-width:900px){
|
||||
.chat-layout{grid-template-columns:1fr}
|
||||
.chat-side{max-height:230px}
|
||||
|
||||
Reference in New Issue
Block a user