feat(lesson-ai): проверка отчёта о занятии по шаблону + история версий
Галочка «Проверить по шаблону» в окне отчёта отправляет текст модели: совпал с шаблоном — остаётся как есть (skipped), не совпал — переписывается в деловом виде (done). Обработка идёт в фоне, HTTP-запрос не ждёт модель, оригинал тьютора сохраняется в text_original. - схема: text_original/text_ai/ai_status/ai_checked_at/ai_error в lesson_reports, таблица lesson_report_versions, ensureLessonReportsTable() - настройки lesson_ai_enabled и lesson_ai_prompt (раздел sec-lesson-ai), значения только 'true'/'false' - worker.js: createLessonReportChecker (FOR UPDATE OF lr SKIP LOCKED, до 3 попыток), хук назовён notifyEvent — notify в createPhotoEnhanceWorker уже занят будильником - server.js: wakeLessonAiWorker, onLessonAiDone (версия, аудит с diff, уведомление lesson.ai.formatted, SSE lesson_report_status), маршруты /versions, /versions/:id/restore и /ai/revert - aiComplete вместо aiCorrectText: общий вызов модели с таймаутом - бэкап/восстановление: lesson_reports и lesson_report_versions в payload - фронтенд: openLessonVersions/restoreLessonVersion в admin.js, бейджи статусов в lessons.js, лейблы аудита, renderAuditPager - docs: раздел 3d в AGENTS.md и Agent Workflow, пункт в README - тесты: контракт lesson-report и настройки уведомления в api.smoketest.js
This commit is contained in:
+9
-2
@@ -82,6 +82,13 @@ const ACTION_LABELS = {
|
||||
'ai.profile.activate': 'Выбран активный профиль ИИ',
|
||||
'export.student': 'Экспорт данных ученика',
|
||||
'export.group_files': 'Экспорт файлов группы (ZIP)',
|
||||
'lesson_report.create': 'Создан отчёт о занятии',
|
||||
'lesson_report.update': 'Изменён отчёт о занятии',
|
||||
'lesson_report.delete': 'Удалён отчёт о занятии',
|
||||
'lesson_report.ai.format': 'ИИ оформил отчёт по шаблону',
|
||||
'lesson_report.ai.error': 'Ошибка проверки отчёта по шаблону',
|
||||
'lesson_report.ai.revert': 'Возвращён оригинал отчёта',
|
||||
'lesson_report.version.restore': 'Восстановлена версия отчёта',
|
||||
};
|
||||
|
||||
const AUDIT_PAGE_SIZE = 50;
|
||||
@@ -202,7 +209,7 @@ function renderTargetDetails(target) {
|
||||
<details class="audit-raw"><summary>Технические данные (JSON)</summary><pre>${esc(fullTarget(target))}</pre></details>`;
|
||||
}
|
||||
|
||||
function renderPager(container, page, totalPages, onPageChange) {
|
||||
function renderAuditPager(container, page, totalPages, onPageChange) {
|
||||
if (totalPages <= 1) { container.innerHTML = ''; return; }
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
@@ -251,7 +258,7 @@ async function loadAudit() {
|
||||
<td style="color:var(--muted);white-space:nowrap">${esc(r.ip || '')}</td>
|
||||
</tr>`).join('');
|
||||
}
|
||||
renderPager(document.getElementById('auditPager'), auditPage, auditTotal, goAuditPage);
|
||||
renderAuditPager(document.getElementById('auditPager'), auditPage, auditTotal, goAuditPage);
|
||||
}
|
||||
|
||||
function goAuditPage(p) {
|
||||
|
||||
Reference in New Issue
Block a user