# Phase 3: Dashboard #overview **Status:** ✅ Implemented (pending review) **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** fullstack **Parallelizable with:** Phase 4, Phase 5 ## Objective Сделать `#overview` дефолтным route'ом admin-панели — landing-страница "что требует внимания". Заменяет нынешние обезличенные stat-cards (totalUsers, totalTests, ...) на actionable digest за последние 24-48 часов. ## Tasks - [x] Backend: новый endpoint `GET /api/admin/overview`: ```js { newUsers24h: number, // регистрации за 24ч newSessions24h: number, // запущенных тестов bannedThisWeek: [{ id, name, banned_at }], failedSessions24h: number, // тесты со статусом не completed topSessions24h: [{ id, user_name, subject, score, total, finished_at }], // топ-5 за 24ч activeUsers24h: number, // unique last_login за 24ч pendingMigrations: number, // если возможно проверить recentErrors: [{ id, type, message, created_at }] // если есть audit log с типом 'error' } ``` - Контроллер: `backend/src/controllers/adminController.js` → новая функция `getOverview` - Route: добавить в `backend/src/routes/admin.js` - Auth: admin или teacher (как остальные admin/* — RBAC same) - Performance: один запрос для каждого поля, простые COUNT/SELECT, без JOIN'ов где возможно - [x] Frontend: новый section `frontend/js/admin/sections/overview.js`: - Использует структуру из Phase 2 - Загружает `/api/admin/overview` - Рендерит карточки в `
` секции: - **Активность 24ч** — registr, sessions, active users (число + спарклайн если есть данные) - **Требует внимания** — banned this week (если >0), failed sessions (если >5%), pending migrations - **Топ-сессии** — таблица top-5 за день с click→drilldown - **Quick links** — "Все пользователи", "Все сессии", "Создать тест" (deep-link в соответствующие routes) - LS.skeleton при загрузке, LS.state.error на fail - [x] HTML: добавить `
` в admin.html (перед остальными tab-pane) - [x] Nav: добавить admin-nav-item для `overview` (icon: layout-dashboard / activity) - [x] Регистрация в ROUTE_TO_SECTION (из Phase 2): `overview: 'overview'` - [x] Сделать `#overview` дефолтным route'ом в router (из Phase 1) — если пустой hash, navigate to `#overview` вместо `#stats` - [x] Старый `#stats` остаётся как доступный route (legacy backend stats), но не дефолтный ## Files to Modify/Create - `backend/src/controllers/adminController.js` — добавить `getOverview` функцию (~60-90L) - `backend/src/routes/admin.js` — добавить `router.get('/overview', requireAdmin, getOverview)` - `frontend/js/admin/sections/overview.js` — новый, ~250-350L - `frontend/admin.html` — добавить `
` + nav-item + `