# Пошаговая инструкция по разработке Галикона ## Этап 0. Подготовка окружения (1 день) 1. Установи Node.js 20 LTS 2. Установи PostgreSQL 16 3. Установи Redis 7 4. Создай проект: - Фронтенд: `npx create-react-app galikon-frontend --template typescript` - Бэкенд: `mkdir galikon-backend && cd galikon-backend && npm init -y && npm i express cors bcrypt jsonwebtoken pg redis socket.io multer` 5. Настрой ESLint + Prettier 6. Создай репозиторий на GitHub/GitLab, запушь --- ## Этап 1. Авторизация и пользователи (неделя 1-2) ### Шаг 1.1 — База данных Создай миграцию users: ```sql CREATE TABLE users ( id SERIAL PRIMARY KEY, login VARCHAR(50) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, name VARCHAR(200) NOT NULL, sport VARCHAR(100), role VARCHAR(20) DEFAULT 'athlete', birth_date DATE, age INTEGER, country VARCHAR(100), city VARCHAR(100), club VARCHAR(200), coach VARCHAR(200), rank VARCHAR(100), goal TEXT, phone VARCHAR(30), email VARCHAR(200), avatar_url TEXT, photo_url TEXT, child_name VARCHAR(200), stars INTEGER DEFAULT 0, quiz_score INTEGER DEFAULT 0, games_won INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); ``` ### Шаг 1.2 — Регистрация (POST /api/auth/register) - Прими JSON: login, password, name, sport, role, birth_date, country, city, club, coach, rank, goal, phone, email - Проверь: login уникален, phone в формате +7..., email содержит @ - Захешируй пароль bcrypt (12 раундов) - Вычисли возраст из birth_date - Сохрани в базу - Верни объект пользователя + accessToken + refreshToken ### Шаг 1.3 — Вход (POST /api/auth/login) - Прими login + password - Найди пользователя по логину - Сравни пароль через bcrypt.compare() - Сгенерируй JWT accessToken (15 мин) и refreshToken (30 дней) - Реализуй rate limiting: 5 попыток → блок 1 мин (храни в Redis) ### Шаг 1.4 — Middleware авторизации - Проверяй заголовок Authorization: Bearer - Декодируй JWT, доставай userId - Клади пользователя в req.user - Если токен просрочен → 401 ### Шаг 1.5 — Обновление токена (POST /api/auth/refresh) - Прими refreshToken - Проверь в Redis (не отозван ли) - Сгенерируй новую пару токенов ### Шаг 1.6 — Экран регистрации (фронтенд) - 8 компонентов-шагов (Step1Name, Step2Login, Step3Sport, Step4Role, Step5Birth, Step6Location, Step7Club, Step8Contacts) - Компонент StepIndicator (точки 1-8) - Валидация на каждом шаге - На шаге 2: индикатор силы пароля (слабый/средний/сильный) - На шаге 4: выбор роли кнопками, поле «Имя ребёнка» для родителя - На шаге 5: календарь даты + авто-возраст + аватарки эмодзи + загрузка фото - На шаге 6: выбрать страну → загрузить города (API /api/locations/cities?country=...) - На шаге 8: телефон + email с валидацией --- ## Этап 2. Профиль и дневник (неделя 3-4) ### Шаг 2.1 — Таблицы БД ```sql CREATE TABLE achievements ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), title VARCHAR(300), date DATE, description TEXT ); CREATE TABLE diary_entries ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), date DATE NOT NULL, type VARCHAR(50), km DECIMAL(5,1), best_time VARCHAR(20), feel INTEGER CHECK(feel BETWEEN 1 AND 5), note TEXT, created_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE events ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), title VARCHAR(300), date DATE NOT NULL, location VARCHAR(300) ); ``` ### Шаг 2.2 — API профиля - GET /api/profile — вернуть текущего пользователя - PUT /api/profile — обновить поля (name, sport, club, coach, goal, phone, email) - POST /api/achievements — добавить достижение - GET /api/achievements — список достижений ### Шаг 2.3 — API дневника - GET /api/diary?limit=20&offset=0 — список записей - POST /api/diary — новая запись (валидация: date обязательно) - DELETE /api/diary/:id — удалить запись - GET /api/diary/stats — агрегация: всего записей, суммарный км, среднее feel ### Шаг 2.4 — API календаря - GET /api/events — все события - POST /api/events — новое событие (title + date обязательно) - DELETE /api/events/:id — удалить ### Шаг 2.5 — Система значков (геймификация) - Бэкенд: эндпоинт GET /api/badges — вычисляет значки на основе данных пользователя - Логика: 1+ запись в дневнике = 🏊, 10+ = 📖, 30+ = 🔥, есть достижения = 🏆 и т.д. - Фронтенд: компонент BadgeGrid — сетка значков (полученные — цветные, нет — серые) ### Шаг 2.6 — Компоненты фронтенда - ProfilePage: аватар, ФИО, спорт, клуб, тренер, значки, достижения - DiaryPage: форма записи + список (с бесконечным скроллом) - CalendarPage: форма добавления + предстоящие/прошедшие события - Кнопка «PDF-отчёт» → GET /api/report/pdf (генерирует PDF на сервере через puppeteer) --- ## Этап 3. Чаты и WebSocket (неделя 5-6) ### Шаг 3.1 — Таблицы БД ```sql CREATE TABLE chats (id SERIAL PRIMARY KEY, type VARCHAR(20), name VARCHAR(200)); CREATE TABLE chat_members (chat_id INTEGER REFERENCES chats(id), user_id INTEGER REFERENCES users(id)); CREATE TABLE messages ( id SERIAL PRIMARY KEY, chat_id INTEGER REFERENCES chats(id), from_user_id INTEGER REFERENCES users(id), text TEXT NOT NULL, read BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW() ); ``` ### Шаг 3.2 — WebSocket сервер - Установи socket.io на сервер - При подключении: аутентифицируй через JWT (передавай в handshake) - Присоединяй пользователя к его комнатам (socket.join(`user:${userId}`)) - События: - `chat:message` — отправить сообщение в чат - `chat:read` — отметить прочитанным - `chat:typing` — печатает... ### Шаг 3.3 — REST API чатов - GET /api/chats — список чатов пользователя - POST /api/chats — создать чат (прямой или групповой) - GET /api/chats/:id/messages?limit=50 — сообщения чата - POST /api/chats/:id/messages — отправить (дублирует WebSocket для надёжности) ### Шаг 3.4 — Фронтенд чата - ChatList: список чатов с фильтром по роли (Все/Спортсмены/Тренеры/Родители) - ChatView: сообщения + поле ввода + автоскролл вниз - Счётчик непрочитанных (useEffect + WebSocket) ### Шаг 3.5 — Игры в чате - TicTacToe: компонент с сеткой 3×3, ходы через WebSocket - GuessNumber: компонент с полем ввода, попытки, подсказки «больше/меньше» - Reaction: компонент с кругом, меняющим цвет (красный→зелёный), замер времени - SportQuiz: 8 вопросов, варианты ответов, подсчёт очков - При победе → POST /api/games/win — начислить звёзды --- ## Этап 4. Рейтинг и голосование (неделя 7) ### Шаг 4.1 — Таблица голосов ```sql CREATE TABLE votes ( voter_id INTEGER REFERENCES users(id), target_id INTEGER REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW(), PRIMARY KEY(voter_id, target_id) ); ``` ### Шаг 4.2 — API рейтинга - POST /api/vote/:userId — проголосовать (один голос на пользователя) - GET /api/ranking?limit=10 — топ спортсменов по звёздам - Звёзды = голоса + бонусы за игры (автоматически) ### Шаг 4.3 — Фронтенд - Компонент RankingList: топ-10, золото/серебро/бронза - Кнопка «Проголосовать» у каждого пользователя --- ## Этап 5. Кабинет тренера и родителя (неделя 8) ### Шаг 5.1 — Кабинет тренера - API: GET /api/coach/students — найти всех пользователей, где поле coach совпадает с именем тренера - Для каждого ученика: аватар, ФИО, спорт, разряд, цель, суммарный км, последние 5 тренировок - Фронтенд: компонент StudentsPage с карточками учеников ### Шаг 5.2 — Кабинет родителя - API: POST /api/parent/link — привязать ребёнка по логину (проверка: ребёнок существует, роль athlete) - API: GET /api/parent/child — получить профиль и статистику ребёнка - Фронтенд: ChildPage — форма привязки + профиль ребёнка + кнопка «Отвязать» --- ## Этап 6. Инструменты (неделя 9) ### Шаг 6.1 — Нормативы - Статический JSON с таблицей разрядов - Компонент NormsTable — отображение таблицы ### Шаг 6.2 — Сравнение с чемпионами - Статические данные Дрессела (14-18 лет) - Компонент ChampionCompare: ввод времени + возраста → сравнение ### Шаг 6.3 — Анализ видео - Компонент VideoAnalyzer: загрузка видео + плеер + кнопки покадровой перемотки - Используй HTML5 video API: video.currentTime += 0.033 ### Шаг 6.4 — Витамины и здоровье - Таблицы: vitamin_log (user_id, date, vitamin_type, taken), sleep_log (user_id, date, hours, pulse), test_results (user_id, test_type, value, date) - API: GET/POST для каждого лога - Чек-лист витаминов на сегодня - Лог сна и пульса с графиком за 7 дней ### Шаг 6.5 — Видеоуроки - Статический список поисковых запросов YouTube (12 тем) --- ## Этап 7. Аналитика и дашборды (неделя 10) ### Шаг 7.1 — Бэкенд для аналитики - GET /api/analytics/progress — вернуть массив {date, time} для графика прогресса - GET /api/analytics/heatmap — годовая тепловая карта [{date, km}] - GET /api/analytics/kpi — ключевые показатели - GET /api/analytics/compare — сравнение со средним по возрасту - GET /api/analytics/export/csv — CSV-файл всех тренировок - GET /api/analytics/export/dashboard — PDF-отчёт ### Шаг 7.2 — Фронтенд дашборда - Установи Chart.js: `npm i chart.js react-chartjs-2` - Компонент ProgressChart: линейный график время/дата + линия цели - Компонент RadarChart: радарная диаграмма навыков - Компонент HeatmapCalendar: календарь активности (как на GitHub) - Компонент KPICards: счётчики (тренировки, км, время, сон) - Компонент TrainingPie: круговая диаграмма типов тренировок ### Шаг 7.3 — Дашборд тренера - Компонент CoachDashboard: таблица учеников + групповой график - Цветовое кодирование строк (зелёный — лидер, красный — отстающий) - Алерты при отсутствии тренировок 3+ дня ### Шаг 7.4 — Дашборд родителя - Компонент ParentDashboard: упрощённый график ребёнка + счётчики --- ## Этап 8. Админ-панель (неделя 10) ### Шаг 8.1 - Middleware adminAuth — проверка роли admin - GET /api/admin/users — список всех пользователей - DELETE /api/admin/users/:id — удалить - POST /api/admin/users/:id/reset-password — сброс пароля ### Шаг 8.2 - Компонент AdminPanel: таблица пользователей с кнопками удалить/сбросить --- ## Этап 9. PWA (неделя 11) ### Шаг 9.1 - Создай manifest.json в public/ - Иконки: 192×192 и 512×512 PNG - Service worker (workbox-webpack-plugin) - Офлайн-режим: кэширование статики - Настрой `"display": "standalone"` ### Шаг 9.2 - Мета-теги для iOS (apple-mobile-web-app-capable и т.д.) - Splash screen для iOS --- ## Этап 10. Тестирование и деплой (неделя 11-12) ### Шаг 10.1 — Тесты - Unit-тесты: Jest для компонентов и API-хендлеров - E2E: Playwright для критических сценариев (регистрация, вход, дневник, чат) ### Шаг 10.2 — Деплой - Собрать фронтенд: `npm run build` - Настроить Docker: - Dockerfile для бэкенда (Node.js) - Dockerfile для фронтенда (Nginx) - docker-compose.yml (frontend + backend + PostgreSQL + Redis) - Развернуть на VPS (Hetzner, DigitalOcean) или AWS ### Шаг 10.3 — Мониторинг - Логирование: Winston + Sentry - Мониторинг ошибок: Sentry - Uptime: UptimeRobot --- ## Итоговый чек-лист - [ ] Регистрация (8 шагов) с валидацией - [ ] Вход с JWT + refresh токеном - [ ] Профиль: значки, достижения, PDF-отчёт - [ ] Дневник тренировок с историей - [ ] Календарь соревнований - [ ] Чаты (WebSocket) + 4 игры - [ ] Рейтинг с голосованием - [ ] Кабинет тренера (ученики и их прогресс) - [ ] Кабинет родителя (привязка ребёнка) - [ ] Нормативы, сравнение с чемпионами, анализ видео - [ ] Витамины, сон, анализы - [ ] Видеоуроки (12 тем) - [ ] Дашборд: графики, тепловая карта, KPI - [ ] Админ-панель - [ ] PWA (установка на телефон) - [ ] Тесты + деплой