Maxim Dolgolyov 5356096349 fix(api): auto-stringify object bodies in LS.api (apiFetch)
LS.api was passing raw object bodies straight to fetch(), which coerces
them to '[object Object]' — the server then parsed empty JSON and 400'd
on missing fields. This silently broke every POST that uses LS.api
directly (EP.api.startMock, saveAttempt, mockAnswer, etc.).

LS.post already stringified, so most call sites worked. Now apiFetch
mirrors that behavior for plain objects, while FormData / Blob /
URLSearchParams / ArrayBuffer / strings still pass through unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 16:40:42 +03:00
2026-04-12 10:30:38 +03:00

LearnSpace

Образовательная платформа с интерактивной онлайн-доской, системой тестирования, управлением классами и элементами геймификации.

Стек: Node.js · Express · SQLite · Vanilla JS · Canvas API · SSE · WebRTC


Содержание


Возможности

Онлайн-урок (Classroom)

Полнофункциональная интерактивная доска с синхронизацией в реальном времени через SSE.

Инструменты рисования

  • Карандаш со сглаживанием Catmull-Rom
  • Маркер (highlighter) с настраиваемой прозрачностью
  • Лазерная указка (без сохранения)
  • Ластик
  • 11 фигур: прямоугольник, скруглённый прямоугольник, эллипс, линия, стрелка, треугольник, ромб, шестиугольник, звезда, облако, коннектор
  • Стикеры с редактированием
  • Текстовые блоки
  • Вставка изображений
  • Таблицы
  • LaTeX-формулы (KaTeX) с визуальным редактором и категориями символов
  • Система координат с построением графиков функций (встроенный парсер)
  • Числовая ось для неравенств (точки, интервалы)
  • Циркуль с анимацией

Инструмент выделения

  • Перемещение и изменение размера всех объектов
  • Вращение объектов (handle над объектом)
  • Lasso multi-select (резиновая рамка)
  • Shift+click для добавления к выделению
  • Copy / Paste с автосмещением
  • Snap-гайды при выравнивании объектов

Навигация по холсту

  • Zoom: колесо мыши к курсору, Ctrl++/-/0, кнопки в тулбаре
  • Pan: зажатый пробел + перетаскивание
  • Minimap (192×108) в правом нижнем углу при zoom > 1 — клик/drag для прыжка по холсту

Инструменты измерения

  • Линейка: поворот (drag ↺), изменение длины (drag ↔), панель свойств (угол, длина)
  • Транспортир: поворот, изменение радиуса, панель свойств
  • Авто-измерения геометрических фигур (длины, углы, площадь)

Страницы и шаблоны

  • Неограниченное количество страниц на сессию
  • Боковая панель с миниатюрами страниц
  • Шаблоны: чистая страница, сетка, линейки, точки, координатные оси
  • Экспорт страницы в PNG

Коммуникация

  • Чат с реакциями и закреплёнными сообщениями
  • Загрузка файлов в чат
  • Поднятие руки учеником
  • WebRTC аудио/видео
  • Трансляция экрана учителя
  • Курсор учителя виден ученикам в реальном времени
  • Выдача прав рисования отдельным ученикам
  • Личные заметки по уроку (per user)

Учебные материалы

  • Банк вопросов с уровнями сложности и тематиками
  • Конструктор тестов с перемешиванием вопросов
  • Многошаговые уроки с блоками: текст, медиа, формулы, код, викторина
  • Курсы с прогрессом прохождения
  • Карточки (flashcards) со spaced repetition
  • Граф знаний — визуализация связей между темами
  • Интерактивные лабораторные работы (30+ симуляций): физика, химия, биология, математика

Управление классом

  • Создание классов, добавление учеников
  • Задания с дедлайнами, отслеживание сдачи
  • Журнал оценок
  • Объявления и лента активности (Google Classroom-стиль)
  • Шаблоны заданий для переиспользования
  • Live-викторины в реальном времени
  • Аналитика успеваемости

Специализированный контент

  • Биохимия: интерактивные молекулы, реакции, метаболические пути, электрофорез
  • Красная книга: виды, биомы, экосистемы, пищевые сети, популяционные данные, квесты

Геймификация

  • Опыт (XP) и уровни
  • Система достижений
  • Стрики (серии дней)
  • Ежедневные цели и задачи
  • Виртуальный питомец
  • Магазин с внутренней валютой
  • Коллекционирование предметов

Администрирование

  • Управление пользователями и ролями
  • Гранулярные разрешения (RBAC)
  • Feature flags (глобальные и per-class)
  • Журнал аудита
  • Кабинет родителя

Быстрый старт

Требования: Docker, Docker Compose

git clone https://git.dolgolyov-family.by/maxim.dolgolyov/Learn_System.git
cd Learn_System
cp backend/.env.example .env
# Отредактировать .env — задать JWT_SECRET и CLIENT_ORIGIN
docker compose up -d

Платформа будет доступна на http://localhost:3000.

Первый пользователь с ролью admin создаётся через seed:

docker compose exec app npm run seed

Ручная установка

Требования: Node.js 18+

# 1. Клонировать и установить зависимости
git clone https://git.dolgolyov-family.by/maxim.dolgolyov/Learn_System.git
cd Learn_System/backend
npm install

# 2. Конфигурация
cp .env.example .env
# Отредактировать .env

# 3. Миграции и начальные данные
npm run migrate
npm run seed        # опционально — тестовые вопросы и пользователи

# 4. Запуск
npm start           # production
npm run dev         # development (nodemon)

Сервер запустится на http://localhost:3000.
Фронтенд раздаётся Express-ом из папки frontend/.


Переменные окружения

Файл: backend/.env (шаблон: backend/.env.example)

Переменная Описание По умолчанию
PORT Порт сервера 3000
JWT_SECRET Секрет для подписи токенов обязательно
JWT_EXPIRES_IN Срок жизни токена 7d
CLIENT_ORIGIN CORS — адрес фронтенда http://localhost:3000
DB_PATH Путь к файлу БД ./backend/data/learnspace.db
UPLOADS_DIR Папка для загруженных файлов ./backend/uploads
NODE_ENV Окружение (production/development) development

Архитектура

Learn_System/
├── backend/
│   ├── src/
│   │   ├── server.js          # Express app, 28 route groups
│   │   ├── config.js
│   │   ├── sse.js             # Server-Sent Events broadcast
│   │   ├── controllers/       # 30 контроллеров
│   │   ├── routes/            # 28 файлов маршрутов
│   │   ├── middleware/        # auth, RBAC, rate limit, validate
│   │   ├── db/
│   │   │   ├── migrate.js     # Auto-migration при старте (76 таблиц)
│   │   │   ├── db.js          # better-sqlite3 singleton
│   │   │   └── migrations/    # SQL-файлы схемы
│   │   └── utils/
│   └── package.json
├── frontend/
│   ├── *.html                 # 43 страницы
│   ├── css/ls.css             # Общая дизайн-система
│   └── js/
│       ├── whiteboard.js      # Движок доски (~3200 строк)
│       ├── classroom-rtc.js   # WebRTC модуль
│       └── labs/              # 30+ физических симуляций
├── js/
│   ├── api.js                 # window.LS.* — клиентское API
│   └── mobile.js              # Мобильная адаптация
├── docker-compose.yml
└── Dockerfile

Ключевые технические решения

Синхронизация доски

  • Штрихи сохраняются батчами через POST /api/classroom/:id/strokes
  • Загрузка с ?since_seq=N — клиент получает только новые штрихи
  • Live-превью через POST /stroke-preview → SSE stroke_preview событие
  • Двухслойный canvas: статический слой (_strokes) + динамический (_selection/guides/laser)

Real-time (SSE)

  • Один SSE-поток на пользователя: GET /api/classroom/:id/events
  • События: stroke_batch, stroke_preview, stroke_deleted, page_changed, chat_message, cursor_move, hand_raised, screen_share, и др.
  • Compression отключён для SSE-потоков

База данных

  • SQLite через better-sqlite3 (синхронный API)
  • Автоматические миграции при каждом старте сервера
  • 76 таблиц, транзакционная запись батчей штрихов

Аутентификация

  • JWT Bearer token
  • Роли: admin, teacher, student, free_student
  • RBAC middleware с кешированием разрешений
  • Rate limiting: 6000 req/min для classroom, 600 req/min для остальных

API

Базовый URL: http://localhost:3000/api

Аутентификация: Authorization: Bearer <token>

Группа Базовый путь Назначение
Auth /auth Регистрация, вход, профиль
Classroom /classroom Онлайн-урок, доска, чат, WebRTC
Classes /classes Управление классами
Assignments /assignments Задания и сдача работ
Questions /questions Банк вопросов
Sessions /sessions Тестовые сессии
Courses /courses Теоретические курсы
Lessons /lessons Уроки с блоками контента
Gamification /gamification XP, ачивки, стрики
Files /files Загрузка и хранение файлов
Live /live Live-викторины
Analytics /analytics Статистика
Admin /admin Управление платформой

Полная документация по endpoint'ам — в backend/src/routes/.


Роли пользователей

Роль Доступ
admin Полный доступ ко всему, включая панель администратора
teacher Создание классов, уроков, заданий, проведение онлайн-уроков
student Прохождение тестов, участие в уроках, доступ к материалам
free_student Ограниченный доступ (настраивается feature flags)

Разрешения настраиваются гранулярно через /api/permissions.


Лицензия

Частный проект. Все права защищены.

S
Description
No description provided
Readme 65 MiB
Languages
HTML 62.3%
JavaScript 36.6%
CSS 0.9%
Python 0.1%
PowerShell 0.1%