337 lines
16 KiB
Markdown
337 lines
16 KiB
Markdown
# Пошаговая инструкция по разработке Галикона
|
||
|
||
## Этап 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 <token>
|
||
- Декодируй 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 (установка на телефон)
|
||
- [ ] Тесты + деплой
|