Files
Learn_System/backend/src/routes/admin.js
T
Maxim Dolgolyov bc0ed1892f feat(assistant): авто-здоровье провайдеров + ручная проверка (фича 4/6)
Новый модуль assistant-health.js (по образцу classroom-cleanup): каждые 15 мин
пингует каждого провайдера (pingLLM) → app_settings.assistant_health
{ id:{ok,at,error,ms,fails} }. Авто-понижение: если активный провайдер
не отвечает 2+ раза подряд, а есть здоровый рабочий запасной — автоматически
переключает assistant_active и пишет assistant_failover (баннер «health»).
schedule() из server.js (unref).

Админка: тумблер «Авто-проверка провайдеров», кнопка «Проверить сейчас»
(POST /admin/assistant/health → runHealth), цветной индикатор здоровья на
каждой карточке провайдера (зелёный/красный + время/ошибка в title).
keyless-шлюзы и провайдеры без ключа учтены.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 15:02:37 +03:00

76 lines
3.6 KiB
JavaScript

const router = require('express').Router();
const { authMiddleware, requireRole } = require('../middleware/auth');
const ctrl = require('../controllers/adminController');
router.use(authMiddleware);
/* Features — teachers may read (need to know what's enabled for their classes) */
router.get('/features', requireRole('admin', 'teacher'), ctrl.getFeatures);
router.patch('/features', requireRole('admin'), ctrl.updateFeatures);
router.get('/free-student-features', requireRole('admin', 'teacher'), ctrl.getFreeStudentFeatures);
router.patch('/free-student-features', requireRole('admin'), ctrl.updateFreeStudentFeatures);
/* Everything below is admin-only */
router.use(requireRole('admin'));
/* ⚠️ Сброс системы «чистый запуск» — деструктивно, только admin */
router.get('/reset-system/plan', requireRole('admin'), ctrl.getResetPlan);
router.post('/reset-system', requireRole('admin'), ctrl.resetSystem);
router.get('/assistant', ctrl.getAssistant);
router.put('/assistant', ctrl.saveAssistant);
router.post('/assistant/test', ctrl.testAssistant);
router.post('/assistant/reindex', ctrl.reindexTextbooks);
router.get('/assistant/models', ctrl.getProviderModels);
router.post('/assistant/scan', ctrl.scanModels);
router.post('/assistant/probe', ctrl.probeModel);
router.post('/assistant/models/apply', ctrl.applyModels);
router.post('/assistant/health', ctrl.runHealth);
router.get('/imggen', ctrl.getImggen);
router.put('/imggen', ctrl.saveImggen);
router.post('/imggen/test', ctrl.testImggen);
router.post('/assistant/provider', ctrl.saveProvider);
router.delete('/assistant/provider/:id', requireRole('admin'), ctrl.deleteProvider);
router.post('/assistant/active', ctrl.setActiveProvider);
router.get('/stats', ctrl.getStats);
router.get('/overview', ctrl.getOverview);
router.get('/search', ctrl.globalSearch);
router.get('/users', ctrl.getUsers);
router.patch('/users/:id/role', ctrl.updateRole);
router.get('/users/:id/sessions', ctrl.getUserSessions);
router.delete('/users/:id/sessions', ctrl.clearUserSessions);
router.post('/users/:id/sessions/clear', ctrl.clearUserSessions);
router.patch('/users/:id', ctrl.updateUser);
router.patch('/users/:id/ban', ctrl.banUser);
router.delete('/users/:id', ctrl.deleteUser);
router.get('/sessions', ctrl.getAllSessions);
router.get('/sessions/:id', ctrl.getSessionDetail);
router.delete('/sessions/:id', ctrl.deleteSession);
/* Audit log */
router.get('/audit-log', ctrl.getAuditLog);
router.delete('/audit-log', ctrl.clearAuditLog);
/* Error log */
router.get('/error-log', ctrl.getErrorLog);
router.delete('/error-log', ctrl.clearErrorLog);
/* Security / auth event log */
router.get('/security-log', ctrl.getSecurityLog);
router.delete('/security-log', ctrl.clearSecurityLog);
/* System health */
router.get('/health', ctrl.getHealth);
router.get('/metrics', ctrl.getMetrics);
/* Topics CRUD */
router.get('/topics', ctrl.getTopics);
router.post('/topics', ctrl.createTopic);
router.patch('/topics/:id', ctrl.updateTopic);
router.delete('/topics/:id', ctrl.deleteTopic);
/* Broadcast notifications */
router.post('/broadcast', ctrl.broadcast);
module.exports = router;