Files
Learn_System/plans/admin-redesign/phase-3-dashboard.md
T
Maxim Dolgolyov 76e376ee04 chore(plan): admin-redesign 6-phase plan
PLAN.md + 6 subplans + CONTEXT.md

Strategy: Incremental | Mode: Automated | Execution: Orchestrator

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:47:55 +03:00

113 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 3: Dashboard #overview
**Status:** ⬜ Not Started
**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
- [ ] 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'ов где возможно
- [ ] Frontend: новый section `frontend/js/admin/sections/overview.js`:
- Использует структуру из Phase 2
- Загружает `/api/admin/overview`
- Рендерит карточки в `<div id="tab-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
- [ ] HTML: добавить `<div class="tab-pane" id="tab-overview">` в admin.html (перед остальными tab-pane)
- [ ] Nav: добавить admin-nav-item для `overview` (icon: layout-dashboard / activity)
- [ ] Регистрация в ROUTE_TO_SECTION (из Phase 2): `overview: 'overview'`
- [ ] Сделать `#overview` дефолтным route'ом в router (из Phase 1) — если пустой hash, navigate to `#overview` вместо `#stats`
- [ ] Старый `#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` — добавить `<div id="tab-overview">` + nav-item + `<script>` тег
- `frontend/js/admin/admin.js` — изменить default route на `#overview` (если ещё не сделано через router.js config)
## Acceptance Criteria
- `/admin` (без hash) → редирект на `#overview`
- `#overview` показывает реальные данные (новые регистрации видны если кто-то зарегистрировался)
- Карточки кликабельные (click → deep-link в users / sessions с фильтром)
- При отсутствии данных (свежая БД) — empty states, не crash
- Endpoint выполняется <100ms на тестовой БД
- F5 на `#overview` работает
- Auth: только teacher/admin (как остальные /admin/*)
## Notes
### Что считать "требует внимания"
Делаем простые threshold'ы для MVP:
- `bannedThisWeek` > 0 — показать жёлтую карточку с именами
- `failedSessions24h` > 0 — показать список (failed = status != 'completed')
- `pendingMigrations` > 0 — показать красную (но это редкий случай — миграции применяются на старте)
Можно потом расширить до "новых жалоб", "переполненных классов", и т.д. — это уже после merge.
### Дизайн карточек
Bento-grid из 4-6 карточек:
```
+---------+---------+
| 24ч | Внимание|
| метрики | ! |
+---------+---------+
| Топ сессии |
| (table) |
+---------+---------+
| Quick links |
+-------------------+
```
Использовать существующие стили `.stat-card`, `.section-title` из admin.html — не изобретать.
### Что НЕ делать в этой фазе
- Не делать реалтайм WebSocket-обновления (это уже Phase 7+)
- Не делать графики/чарты (пока числа + sparkline опционально)
- Не делать персонализацию (например "ваши классы")
## Review Checklist
- [ ] Endpoint работает и возвращает корректную форму ответа
- [ ] Frontend handles empty state gracefully
- [ ] Click на quick-link корректно навигирует через AdminRouter
- [ ] Нет hardcoded date math (использовать SQL `datetime('now', '-24 hours')`)
- [ ] Roles correct (admin/teacher only, не у students)
- [ ] No SQL injection — параметры через `?` placeholders
- [ ] Build passes
## Handoff to Next Phase
<!-- Implementer: записать, какой shape у overview-ответа,
какие route переходы внедрены, какие deep-links открыты для Phase 6
(например, `#users?filter=banned` или `#sessions?status=failed`). -->