feat(permissions): A3 — история изменений прав (endpoint + UI)

GET /api/permissions/log (admin-only) — последние изменения ролевых прав (или
?user_id= для личных оверрайдов) из admin_audit_log; читаемый текст («включил
«X» для роли «учитель»») с резолвом меток через registry. Клиент LS.permissionsLog.
Вкладка «Доступ · роли»: блок «История изменений прав ролей» с кнопкой «Показать».
Тест: admin видит записи, не-админу 403. permissions 13/13.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-03 14:14:56 +03:00
parent 1b78f675f8
commit 7d474b40c0
5 changed files with 71 additions and 3 deletions
+15
View File
@@ -102,8 +102,23 @@
});
}
async function loadPermLog() {
const box = document.getElementById('perm-log');
if (!box) return;
box.innerHTML = '<p style="color:var(--muted);font-size:12px">Загрузка…</p>';
try {
const log = await LS.permissionsLog();
box.innerHTML = log.length
? log.map(e => `<div style="font-size:12.5px;padding:5px 0;border-top:1px solid var(--border-h,#eee)"><b>${esc(e.actor)}</b> ${esc(e.text)} <span style="color:var(--muted)">· ${esc((e.at || '').replace('T', ' ').slice(0, 16))}</span></div>`).join('')
: '<p style="color:var(--muted);font-size:12px">Изменений пока нет.</p>';
} catch (e) {
box.innerHTML = `<p style="color:var(--danger);font-size:12px">Ошибка: ${esc(e.message)}</p>`;
}
}
window.togglePermission = togglePermission;
window.filterPermissions = filterPermissions;
window.loadPermLog = loadPermLog;
window.AdminSections = window.AdminSections || {};
window.AdminSections.permissions = {