Files
Learn_System/backend
Maxim Dolgolyov b1e645157a refactor: split gamificationController.js (859L) → 5 файлов
По образцу classroom-split:

  backend/src/controllers/gamificationController.js  859L → 31L (фасад)
  backend/src/controllers/gamification/
    _shared.js   194L — db, helpers (xpToLevel/levelMinXp/levelMaxXp/
                       rankName/RANKS), GOAL_TIERS, ACHIEVEMENT_DEFS,
                       AVATAR_FRAMES, stmts (все prepared statements)
    service.js   393L — бизнес-логика: awardXP/awardCoins/getXPInfo/
                       updateStreak, seedAchievements/
                       unlockAchievement/pushAchievementNotif/
                       checkAchievements/checkRedBookAchievements,
                       hooks (onLessonComplete/onTestFinished/
                       onClassJoined/onLabExperiment),
                       daily (getDailyGoal/updateDailyGoal),
                       challenges (_currentWeek/ensureChallenges/
                       updateChallenges)
    api.js       152L — HTTP handlers /api/gamification/*: getMe,
                       getFrames, setFrame, setGoalTier,
                       getAchievements, getLeaderboard, getXPHistory,
                       getChallenges, claimChallenge
    admin.js      70L — /api/gamification/admin/*: adminAward,
                       adminReset, adminGamStats, adminGetUser

Фасад gamificationController.js перереэкспортирует ВСЕ 24 функции,
которые были в оригинале. Никаких изменений в:
  - routes/* (импорты не менялись)
  - biochemController, classController, gamesController,
    lessonController, petController, redBookController,
    sessionController, db/seed-permissions, db/legacy-migrate
    (все 10+ внешних импортов 'gamificationController' работают)

Проверено: node --check OK, server restart, /api/gamification/*
возвращает 401 (auth req'd) — маршруты живые. Объект module.exports
содержит все 24 функции (тест: Object.keys чтения фасада).

Самый большой контроллер в проекте теперь хорошо структурирован:
любой разработчик мгновенно находит нужный кусок.
2026-05-16 18:14:15 +03:00
..

LearnSpace Backend — Фаза 1

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

cd backend
npm install

# 1. Скопировать и заполнить переменные окружения
cp .env.example .env

# 2. Создать базу данных в PostgreSQL
createdb learnspace

# 3. Применить миграции (создать таблицы)
npm run migrate

# 4. Загрузить тестовые вопросы
npm run seed

# 5. Запустить сервер
npm run dev

API

Auth

Метод URL Тело Описание
POST /api/auth/register { email, password, name } Регистрация
POST /api/auth/login { email, password } Вход
GET /api/auth/me Текущий пользователь

Предметы

Метод URL Описание
GET /api/subjects Список предметов
GET /api/subjects/:slug/topics Темы предмета

Сессии тестирования

Метод URL Тело Описание
POST /api/sessions { subject_slug, mode, count, topic_id? } Начать тест
POST /api/sessions/:id/answer { question_id, option_id, time_spent_sec? } Отправить ответ
POST /api/sessions/:id/finish Завершить тест + разбор
GET /api/sessions/:id/result Результат завершённого теста
GET /api/sessions/history История тестов

Все /api/sessions/* требуют заголовок:

Authorization: Bearer <token>

Добавление вопросов

Создать JSON-файл в data/ по образцу questions-bio.json:

{
  "subject": "chem",
  "topics": [{ "name": "Органическая химия", "order": 1 }],
  "questions": [
    {
      "topic": "Органическая химия",
      "difficulty": 2,
      "text": "Текст вопроса",
      "options": ["А", "Б", "В", "Г"],
      "answer": 0,
      "explanation": "Объяснение правильного ответа"
    }
  ]
}

Затем повторно запустить npm run seed.

Структура проекта

backend/
├── data/                     ← JSON с вопросами
├── src/
│   ├── server.js             ← точка входа
│   ├── middleware/auth.js    ← JWT верификация
│   ├── db/
│   │   ├── pool.js           ← соединение с PostgreSQL
│   │   ├── migrate.js        ← запуск миграций
│   │   ├── seed.js           ← загрузка вопросов
│   │   └── migrations/       ← SQL-файлы схемы
│   ├── routes/               ← маршруты
│   └── controllers/          ← бизнес-логика
└── .env.example