426 lines
22 KiB
HTML
426 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>ТЗ Галикон</title>
|
||
<style>
|
||
body{font:14px/1.7 -apple-system,Arial,sans-serif;max-width:900px;margin:40px auto;padding:20px;color:#222}
|
||
h1{font-size:26px;border-bottom:3px solid #00E5FF;padding-bottom:8px}
|
||
h2{font-size:20px;margin-top:28px;color:#0F1218;border-bottom:1px solid #ddd;padding-bottom:4px}
|
||
h3{font-size:16px;margin-top:20px;color:#333}
|
||
table{width:100%;border-collapse:collapse;margin:12px 0;font-size:13px}
|
||
td,th{padding:6px 10px;border:1px solid #ccc;text-align:left}
|
||
th{background:#f0f0f0;font-weight:700}
|
||
code{background:#f4f4f4;padding:2px 6px;border-radius:4px;font-size:13px}
|
||
pre{background:#f8f8f8;padding:12px;border-radius:8px;font-size:12px;overflow-x:auto}
|
||
ul{margin:8px 0;padding-left:20px}
|
||
li{margin:4px 0}
|
||
strong{color:#0F1218}
|
||
@media print{body{margin:0;padding:10px}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>Техническое задание: Галикон</h1>
|
||
<br>
|
||
<h2>1. Общее описание</h2>
|
||
<br>
|
||
<p>**Название:** Галикон — мобильное веб-приложение для спортсменов, тренеров и родителей.</p>
|
||
<br>
|
||
<p>**Цель:** Единая платформа для юных спортсменов (дети от 10 лет): дневник тренировок, контроль здоровья, рейтинги, чаты, игры, нормативы, сравнение с чемпионами. Аналогов в мире нет.</p>
|
||
<br>
|
||
<p><strong>Пользователи:</strong></p>
|
||
<p>- Спортсмен (основной пользователь)</p>
|
||
<p>- Тренер (видит своих учеников)</p>
|
||
<p>- Родитель (видит профиль ребёнка)</p>
|
||
<p>- Администратор (управление пользователями)</p>
|
||
<br>
|
||
<br>
|
||
<h2>2. Технический стек</h2>
|
||
<br>
|
||
<table>
|
||
<tr><th>Слой</th><th>Технология</th></tr>
|
||
</table>
|
||
<table>
|
||
<br>
|
||
<br>
|
||
<h2>3. Функциональные требования</h2>
|
||
<br>
|
||
<h3>3.1. Регистрация и вход</h3>
|
||
<br>
|
||
<p><strong>Регистрация — 8 шагов:</strong></p>
|
||
<li>ФИО (string, обязательно)</li>
|
||
<li>Логин (латиница, уникальный) + пароль (хеширование bcrypt, минимум 6 символов)</li>
|
||
<li>Вид спорта (select из 39 олимпийских видов)</li>
|
||
<li>Роль: спортсмен / тренер / родитель (если родитель — поле «Имя ребёнка»)</li>
|
||
<li>Дата рождения → возраст вычисляется автоматически. Аватарка (эмодзи на выбор) или загрузка фото (JPEG/PNG, макс 5 МБ)</li>
|
||
<li>Страна (select) → город (datalist с подсказками по стране)</li>
|
||
<li>Клуб, тренер (ФИО), разряд/звание, цель (произвольный текст)</li>
|
||
<li>Телефон (обязательно, валидация формата) + Email (обязательно)</li>
|
||
<br>
|
||
<p><strong>Вход:</strong></p>
|
||
<p>- Логин + пароль</p>
|
||
<p>- JWT access token (15 мин) + refresh token (30 дней)</p>
|
||
<p>- Rate limiting: 5 попыток → блокировка на 1 минуту</p>
|
||
<p>- Автовыход через 30 минут бездействия</p>
|
||
<br>
|
||
<p><strong>Безопасность:</strong></p>
|
||
<p>- Пароли: bcrypt с солью</p>
|
||
<p>- CSP-заголовки</p>
|
||
<p>- Санитизация всех пользовательских вводов (XSS-защита)</p>
|
||
<p>- HTTPS обязательно</p>
|
||
<p>- CORS только для доверенных доменов</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.2. Профиль спортсмена</h3>
|
||
<br>
|
||
<p><strong>Отображение:</strong></p>
|
||
<p>- Аватар, ФИО, вид спорта, роль</p>
|
||
<p>- Дата рождения, возраст, страна, город</p>
|
||
<p>- Клуб, тренер, разряд, цель</p>
|
||
<p>- Телефон, email</p>
|
||
<br>
|
||
<p><strong>Значки (геймификация):</strong></p>
|
||
<p>Автоматический подсчёт по данным пользователя:</p>
|
||
<p>- 🏊 Первая тренировка (1+ запись в дневнике)</p>
|
||
<p>- 📖 10 тренировок</p>
|
||
<p>- 🔥 30 тренировок</p>
|
||
<p>- 🏆 Рекордсмен (есть достижения)</p>
|
||
<p>- 🎯 Снайпер (победа в игре «Угадай число»)</p>
|
||
<p>- ⚡ Молния (реакция < 300 мс)</p>
|
||
<p>- 🧠 Знаток (викторина 5+/8)</p>
|
||
<p>- 💪 100 км (суммарный километраж > 100)</p>
|
||
<br>
|
||
<p><strong>Достижения:</strong></p>
|
||
<p>Пользователь добавляет: название, дата, описание. Отображаются списком.</p>
|
||
<br>
|
||
<p><strong>Отчёт для тренера (PDF):</strong></p>
|
||
<p>- Генерация PDF на сервере (Puppeteer / wkhtmltopdf)</p>
|
||
<p>- Содержит: ФИО, спорт, клуб, тренер, разряд, цель, значки, достижения, последние 10 записей дневника</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.3. Дневник тренировок</h3>
|
||
<br>
|
||
<p><strong>Поля записи:</strong></p>
|
||
<p>- Дата (date, обязательно)</p>
|
||
<p>- Тип тренировки (select: Скорость / Техника / Выносливость / ОФП / Соревнование)</p>
|
||
<p>- Километраж (число, км)</p>
|
||
<p>- Лучшее время (строка)</p>
|
||
<p>- Самочувствие (1-5)</p>
|
||
<p>- Заметка (текст)</p>
|
||
<br>
|
||
<p><strong>История:</strong></p>
|
||
<p>- Список записей, сортировка по дате (новые сверху)</p>
|
||
<p>- Удаление записи</p>
|
||
<br>
|
||
<p><strong>Агрегация (для тренера):</strong></p>
|
||
<p>- Всего тренировок</p>
|
||
<p>- Суммарный километраж</p>
|
||
<p>- Среднее самочувствие</p>
|
||
<p>- График прогресса по времени (библиотека Chart.js)</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.4. Календарь соревнований</h3>
|
||
<br>
|
||
<p><strong>Добавление события:</strong></p>
|
||
<p>- Название (string)</p>
|
||
<p>- Дата (date)</p>
|
||
<p>- Место (string)</p>
|
||
<br>
|
||
<p><strong>Отображение:</strong></p>
|
||
<p>- Предстоящие (сортировка по дате)</p>
|
||
<p>- Прошедшие (сортировка по дате, обратная)</p>
|
||
<br>
|
||
<p><strong>Дополнительно (желательно):</strong></p>
|
||
<p>- Push-уведомление за день до события</p>
|
||
<p>- Цветовое кодирование по типу (соревнование / сборы / тренировка)</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.5. Чаты</h3>
|
||
<br>
|
||
<p><strong>Архитектура:</strong></p>
|
||
<p>- WebSocket-соединение (Socket.io)</p>
|
||
<p>- Комнаты: личные (1-на-1), групповые</p>
|
||
<p>- Сообщения хранятся в PostgreSQL</p>
|
||
<p>- Индикатор «прочитано/не прочитано»</p>
|
||
<br>
|
||
<p><strong>Функции:</strong></p>
|
||
<p>- Список чатов с другими пользователями</p>
|
||
<p>- Фильтр по роли: Все / Спортсмены / Тренеры / Родители</p>
|
||
<p>- Отправка текстовых сообщений</p>
|
||
<p>- Счётчик непрочитанных</p>
|
||
<p>- Групповые чаты (создание, добавление участников)</p>
|
||
<br>
|
||
<p><strong>Встроенные игры (в чате):</strong></p>
|
||
<li>**Крестики-нолики** — пошаговая игра, синхронизация через WebSocket</li>
|
||
<li>**Угадай число (1-100)** — 7 попыток, победа < 5 попыток = +2 звезды</li>
|
||
<li>**Реакция** — измерение времени реакции, рекорд < 300 мс = +1 звезда</li>
|
||
<li>**Спорт-викторина** — 8 вопросов, результат 5+/8 = +1-5 звёзд</li>
|
||
<br>
|
||
<br>
|
||
<h3>3.6. Рейтинговая система</h3>
|
||
<br>
|
||
<p><strong>Звёзды начисляются за:</strong></p>
|
||
<p>- Победы в играх</p>
|
||
<p>- Высокие результаты викторины</p>
|
||
<p>- Голоса других пользователей</p>
|
||
<br>
|
||
<p><strong>Рейтинг:</strong></p>
|
||
<p>- Топ-5 спортсменов по звёздам</p>
|
||
<p>- Отображение: место, ФИО, звёзды, результаты викторины, победы в играх</p>
|
||
<p>- Топ-3 выделены золотом/серебром/бронзой</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.7. Инструменты</h3>
|
||
<br>
|
||
<p><strong>Нормативы:</strong></p>
|
||
<p>- Статическая таблица разрядов по плаванию (50 м бассейн): МСМК → 2 юношеский</p>
|
||
<p>- Дистанции: 50 м, 100 м, 400 м вольный стиль</p>
|
||
<br>
|
||
<p><strong>Сравнение с чемпионами:</strong></p>
|
||
<p>- Данные Калеба Дрессела по возрастам (14-18 лет)</p>
|
||
<p>- Пользователь вводит своё время и возраст → сравнение</p>
|
||
<p>- Показывает: текущий результат → КМС → результат Дрессела в этом возрасте</p>
|
||
<br>
|
||
<p><strong>Анализ видео:</strong></p>
|
||
<p>- Загрузка видео (MP4, макс 200 МБ)</p>
|
||
<p>- Плеер с покадровой перемоткой (шаг 0.033 сек, 0.1 сек, 1 сек)</p>
|
||
<p>- Счётчик текущего кадра</p>
|
||
<p>- Play/Pause</p>
|
||
<br>
|
||
<p><strong>Витамины:</strong></p>
|
||
<p>- Чек-лист на сегодня: D3, Омега-3, Магний, Цинк, BCAA</p>
|
||
<p>- Сохранение истории по дням</p>
|
||
<br>
|
||
<p><strong>Сон и пульс:</strong></p>
|
||
<p>- Запись часов сна и утреннего пульса</p>
|
||
<p>- Средние значения за 7 дней</p>
|
||
<br>
|
||
<p><strong>Анализы:</strong></p>
|
||
<p>- Гемоглобин, Ферритин, Витамин D, Витамин B12</p>
|
||
<p>- История значений с датами</p>
|
||
<br>
|
||
<p><strong>Видеоуроки:</strong></p>
|
||
<p>- Список поисковых запросов для YouTube (12 тем по технике плавания)</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.8. Кабинет тренера</h3>
|
||
<br>
|
||
<p><strong>Поиск учеников:</strong></p>
|
||
<p>- Автоматически: все пользователи, у которых поле «Тренер» совпадает с ФИО тренера</p>
|
||
<br>
|
||
<p><strong>Отображение по каждому ученику:</strong></p>
|
||
<p>- Аватар, ФИО, вид спорта, разряд, цель</p>
|
||
<p>- Суммарный километраж</p>
|
||
<p>- Последние 5 тренировок (дата, тип, км, время)</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.9. Кабинет родителя</h3>
|
||
<br>
|
||
<p><strong>Привязка ребёнка:</strong></p>
|
||
<p>- Родитель вводит логин ребёнка → привязка (сохраняется в профиле родителя)</p>
|
||
<br>
|
||
<p><strong>Отображение:</strong></p>
|
||
<p>- Профиль ребёнка (как у спортсмена)</p>
|
||
<p>- Статистика: всего тренировок, км, среднее самочувствие</p>
|
||
<p>- Значки ребёнка</p>
|
||
<p>- Дневник тренировок (последние 15 записей)</p>
|
||
<p>- Цель и тренер ребёнка</p>
|
||
<p>- Кнопка «Отвязать»</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.10. Админ-панель</h3>
|
||
<br>
|
||
<p><strong>Доступ:</strong></p>
|
||
<p>- Отдельный мастер-пароль администратора</p>
|
||
<br>
|
||
<p><strong>Функции:</strong></p>
|
||
<p>- Просмотр всех пользователей (ФИО, роль, логин, спорт, клуб, звёзды)</p>
|
||
<p>- Удаление пользователя</p>
|
||
<p>- Сброс пароля пользователя</p>
|
||
<br>
|
||
<br>
|
||
<h3>3.11. PWA (Progressive Web App)</h3>
|
||
<br>
|
||
<p><strong>Требования:</strong></p>
|
||
<p>- manifest.json с иконками (192x192, 512x512)</p>
|
||
<p>- Service Worker для офлайн-доступа</p>
|
||
<p>- Установка на домашний экран (iOS/Android)</p>
|
||
<p>- Режим standalone (без адресной строки браузера)</p>
|
||
<p>- Splash screen на iOS</p>
|
||
<br>
|
||
<br>
|
||
<h2>4. Нефункциональные требования</h2>
|
||
<br>
|
||
<tr><th>Фронтенд</th><th>React / Vue 3 + TypeScript, PWA</th></tr>
|
||
<tr><td>Бэкенд</td><td>Node.js (Express/Fastify) или Go</td></tr>
|
||
<tr><td>База данных</td><td>PostgreSQL</td></tr>
|
||
<tr><td>Кэш</td><td>Redis</td></tr>
|
||
<tr><td>Файлы</td><td>S3-совместимое хранилище (MinIO)</td></tr>
|
||
<tr><td>Чат</td><td>WebSocket (Socket.io)</td></tr>
|
||
<tr><td>Push-уведомления</td><td>Firebase Cloud Messaging / Web Push API</td></tr>
|
||
<tr><td>Авторизация</td><td>JWT + refresh tokens</td></tr>
|
||
<tr><td>Хостинг</td><td>Docker + Kubernetes или VPS</td></tr>
|
||
<tr><td>Параметр</td><td>Значение</td></tr>
|
||
</table>
|
||
<table>
|
||
<br>
|
||
<br>
|
||
<h2>5. API (основные эндпоинты)</h2>
|
||
<br>
|
||
<pre>POST /api/auth/register — регистрация
|
||
POST /api/auth/login — вход
|
||
POST /api/auth/refresh — обновление токена
|
||
GET /api/profile — профиль текущего пользователя
|
||
PUT /api/profile — обновление профиля
|
||
GET /api/profile/:id — профиль другого пользователя
|
||
POST /api/achievements — добавить достижение
|
||
GET /api/diary — дневник (список)
|
||
POST /api/diary — новая запись
|
||
DELETE /api/diary/:id — удалить запись
|
||
GET /api/events — календарь
|
||
POST /api/events — добавить событие
|
||
DELETE /api/events/:id — удалить событие
|
||
GET /api/chats — список чатов
|
||
GET /api/chats/:id/messages — сообщения чата
|
||
POST /api/chats/:id/messages — отправить сообщение
|
||
WS /ws/chat — WebSocket для чата
|
||
POST /api/vote/:userId — проголосовать за пользователя
|
||
GET /api/ranking — рейтинг (топ)
|
||
GET /api/coach/students — ученики тренера
|
||
POST /api/parent/link — привязать ребёнка
|
||
GET /api/admin/users — список пользователей (админ)
|
||
DELETE /api/admin/users/:id — удалить пользователя (админ)
|
||
POST /api/admin/users/:id/reset-password — сброс пароля (админ)
|
||
GET /api/report/pdf — PDF-отчёт для тренера
|
||
POST /api/upload/avatar — загрузка аватара
|
||
POST /api/upload/video — загрузка видео
|
||
POST /api/upload/photo — загрузка фото
|
||
</pre>
|
||
<br>
|
||
<br>
|
||
<h3>3.12. Аналитика и дашборды</h3>
|
||
<br>
|
||
<p><strong>Дашборд спортсмена — главный экран аналитики:</strong></p>
|
||
<br>
|
||
<p><strong>График прогресса (50 м в/с):</strong></p>
|
||
<p>- Линейный график: дата по оси X, время по оси Y</p>
|
||
<p>- Целевая линия (23″) и текущая линия тренда</p>
|
||
<p>- Автоматический расчёт скорости прогресса (секунд в месяц)</p>
|
||
<p>- Прогноз: когда будет достигнута цель при текущем темпе</p>
|
||
<br>
|
||
<p><strong>Радарная диаграмма навыков:</strong></p>
|
||
<p>- 6 осей: старт, поворот, подводная фаза, гребок, выносливость, финиш</p>
|
||
<p>- Оценки 1-10 выставляет тренер или сам спортсмен</p>
|
||
<p>- Сравнение с предыдущим месяцем</p>
|
||
<br>
|
||
<p><strong>Круговые диаграммы тренировок:</strong></p>
|
||
<p>- Распределение по типам: скорость / техника / выносливость / ОФП</p>
|
||
<p>- За текущий месяц и за всё время</p>
|
||
<br>
|
||
<p><strong>Тепловая карта активности:</strong></p>
|
||
<p>- Календарь GitHub-style: каждый день — квадратик</p>
|
||
<p>- Цвет зависит от километража (0 — серый, 5+ км — ярко-голубой)</p>
|
||
<p>- Видно пропуски тренировок и интенсивные периоды</p>
|
||
<br>
|
||
<p><strong>Счётчики (KPI):</strong></p>
|
||
<p>- Всего тренировок, общий километраж, лучший результат</p>
|
||
<p>- Среднее самочувствие, динамика пульса, средний сон</p>
|
||
<p>- Недельная/месячная нагрузка</p>
|
||
<br>
|
||
<p><strong>Сравнительная аналитика:</strong></p>
|
||
<p>- Сравнение своего прогресса со средним по возрастной группе</p>
|
||
<p>- Сравнение с товарищами по клубу (анонимно)</p>
|
||
<p>- Процентиль: «Ты быстрее 78% пловцов твоего возраста»</p>
|
||
<br>
|
||
<p><strong>Экспорт данных:</strong></p>
|
||
<p>- CSV-выгрузка всех тренировок</p>
|
||
<p>- Excel-отчёт с графиками (автоматическая генерация)</p>
|
||
<p>- PDF-дашборд для тренера</p>
|
||
<br>
|
||
<p><strong>Технологии:</strong></p>
|
||
<p>- Chart.js / ECharts / D3.js для визуализации</p>
|
||
<p>- Данные агрегируются на бэкенде (SQL-запросы с GROUP BY)</p>
|
||
<p>- Кэширование агрегаций в Redis (обновление раз в час)</p>
|
||
<br>
|
||
<p><strong>API для аналитики:</strong></p>
|
||
<pre>GET /api/analytics/progress/:metric — график прогресса по метрике
|
||
GET /api/analytics/radar — радарная диаграмма
|
||
GET /api/analytics/heatmap — тепловая карта (год)
|
||
GET /api/analytics/distribution — распределение типов тренировок
|
||
GET /api/analytics/kpi — ключевые показатели
|
||
GET /api/analytics/compare — сравнение с группой
|
||
GET /api/analytics/export/csv — CSV-выгрузка
|
||
GET /api/analytics/export/dashboard — PDF-дашборд
|
||
</pre>
|
||
<br>
|
||
<p><strong>Дашборд тренера:</strong></p>
|
||
<p>- Сводка по всем ученикам: таблица с сортировкой по любому столбцу</p>
|
||
<p>- Групповой график прогресса (все ученики на одном графике)</p>
|
||
<p>- Выделение отстающих (красная зона) и лидеров (зелёная зона)</p>
|
||
<p>- Уведомления: ученик не тренировался 3+ дня → алерт тренеру</p>
|
||
<p>- Экспорт сводного отчёта по группе</p>
|
||
<br>
|
||
<p><strong>Дашборд родителя:</strong></p>
|
||
<p>- Упрощённая версия: график прогресса ребёнка, счётчики</p>
|
||
<p>- Уведомления о новых достижениях и значках</p>
|
||
<p>- Еженедельный email-отчёт (опционально)</p>
|
||
<br>
|
||
<br>
|
||
<h2>6. База данных (основные таблицы)</h2>
|
||
<br>
|
||
<pre>users: id, login, password_hash, name, sport, role, birth_date, age,
|
||
country, city, club, coach, rank, goal, phone, email,
|
||
avatar_url, photo_url, stars, quiz_score, games_won,
|
||
created_at, updated_at
|
||
|
||
achievements: id, user_id, title, date, description
|
||
|
||
diary_entries: id, user_id, date, type, km, best_time, feel, note
|
||
|
||
events: id, user_id, title, date, location
|
||
|
||
messages: id, chat_id, from_user_id, to_user_id, text, read, created_at
|
||
|
||
chats: id, type (direct/group), name
|
||
|
||
chat_members: chat_id, user_id
|
||
|
||
vitamins: id, user_id, date, vitamin_type, taken
|
||
|
||
sleep_log: id, user_id, date, hours, pulse
|
||
|
||
tests: id, user_id, test_type, value, date
|
||
|
||
parent_links: parent_id, child_id
|
||
|
||
votes: voter_id, target_id, created_at
|
||
</pre>
|
||
<br>
|
||
<br>
|
||
<h2>7. Этапы разработки</h2>
|
||
<br>
|
||
<tr><th>Язык интерфейса</th><th>Русский</th></tr>
|
||
<tr><td>Адаптивность</td><td>Mobile-first, поддержка десктопа</td></tr>
|
||
<tr><td>Браузеры</td><td>Chrome 90+, Safari 14+, Firefox 90+</td></tr>
|
||
<tr><td>Производительность</td><td>First paint < 2 сек, взаимодействие < 100 мс</td></tr>
|
||
<tr><td>Доступность</td><td>WCAG 2.1 AA</td></tr>
|
||
<tr><td>Масштабируемость</td><td>До 100 000 пользователей</td></tr>
|
||
<tr><td>Резервное копирование</td><td>Ежедневный бэкап БД</td></tr>
|
||
<tr><td>Этап</td><td>Содержание</td><td>Срок</td></tr>
|
||
</table>
|
||
<table>
|
||
<br>
|
||
<p>**Итого:** ~10 недель на MVP командой из 2-3 разработчиков.</p>
|
||
<br>
|
||
<table>
|
||
<tr><th>1</th><th>База данных, API авторизации, регистрация</th><th>2 недели</th></tr>
|
||
<tr><td>2</td><td>Профиль, дневник, календарь</td><td>2 недели</td></tr>
|
||
<tr><td>3</td><td>Чаты (WebSocket) + игры</td><td>2 недели</td></tr>
|
||
<tr><td>4</td><td>Рейтинг, кабинет тренера, кабинет родителя</td><td>1 неделя</td></tr>
|
||
<tr><td>5</td><td>Инструменты (нормативы, сравнение, видео, витамины)</td><td>1 неделя</td></tr>
|
||
<tr><td>6</td><td>Админ-панель, PDF-отчёт</td><td>1 неделя</td></tr>
|
||
<tr><td>7</td><td>PWA, тестирование, деплой</td><td>1 неделя</td></tr>
|
||
</table>
|
||
|
||
</body>
|
||
</html> |