# LMS Микросервисная система для проведения практических занятий (Kotlin + Spring Boot + PostgreSQL 18). ## Модули - `libs/common-http` — общий формат ошибок и обработчик исключений. - `libs/security-jwt` — выпуск/проверка JWT (RSA) и `PasswordEncoder`. - `libs/markdown` — серверный рендер markdown со спойлерами и санитизацией. - `libs/test-support` — общая тестовая инфраструктура (Testcontainers, `postgres:18`). - `services/identity-service` — аккаунты, студенты, группы, зачисления (схема `identity`). - `services/academic-service` — курсы, статьи, лабораторные, уровни, варианты (схема `academic`). - `services/progress-service` — уровни студентов, распределение вариантов, работы, оценки (схема `progress`). - `services/gateway` — Spring Cloud Gateway, маршрутизация и проверка JWT. - `web` — серверный веб-интерфейс (Thymeleaf + htmx), BFF. ## Требования - JDK 21 (runtime) + Docker (для PostgreSQL 18). Gradle сам скачает toolchain 21 для сборки. - **Не запускать сервисы на JAVA_HOME=Java 25**: на 25 ломается logback внутри fat-jar (NoClassDefFoundError `ThrowableProxy`), что роняет потоки Tomcat. Скрипт `run.sh` использует JDK 21 автоматически. ## Запуск ```bash ./gradlew bootJar -x test # собрать все сервисы ./run.sh start # поднять БД + все 5 сервисов на JDK 21 ./run.sh status # проверить здоровье ./run.sh logs web # посмотреть лог сервиса ./run.sh stop | restart ``` Можно и без скрипта: `docker compose up -d postgres`, затем `/usr/lib/jvm/java-21-openjdk/bin/java -jar ` для каждого сервиса, или `./gradlew :services:identity-service:bootRun` и т.д. по одному. Порты по умолчанию: gateway `:8080`, identity `:8081`, academic `:8082`, progress `:8083`, web `:8090`. Интерфейс: `http://localhost:8090`. ## Текущий функционал Открыть `http://localhost:8090`. При первом запуске создаётся аккаунт администратора (`/setup`); далее — вход по логину и паролю. - **Доступ**: JWT (RSA, ключи identity генерирует при первом старте и хранит в БД), проверка токена на gateway, роли ADMIN/STUDENT, CSRF на всех POST-формах, session fixation-защита; вход студента с обязательной сменой пароля. - **Группы и студенты**: создание groups, импорт `.xls/.xlsx/.csv`, ручное добавление студента (генерация пароля), выгрузка логинов XLSX/CSV, сброс пароля; на странице группы — баллы по каждой лабе и средний балл. - **Лабораторные**: импорт ZIP (`lab.yaml` + `README.md` + `variants/*.md` c front-matter) и старого JSON; создание через UI с произвольным числом уровней; просмотр/редактирование условия (markdown), вариантов, дат; статусы draft/published (клик по бейджу меняет); даты выводятся в московском времени. - **Распределение вариантов**: по уровню студента на лабу (по умолчанию — самый простой), round-robin с уникальностью в группе; ручное назначение варианта. - **Материалы** (`/learn`, публичная читалка): главы → разделы → статьи в markdown (код, спойлеры, картинки; санитизация OWASP); импорт ZIP (`chapters/N-глава/N-раздел/N-статья.md` + `assets/`); создание/переименование/ удаление глав, разделов, статей; перенос статей между разделами. - **Студент**: видит опубликованные лабы, свой вариант с條件ем (markdown), сроки сдачи/защиты и оценки. - UI: светлая/тёмная тема (сохраняется в localStorage), модальные окна вместо отдельных страниц, фавиконка, адаптивная вёрстка без inline-стилей. ## Сборка и тесты ```bash ./gradlew build # сборка всех модулей ./gradlew check # тесты и проверки ``` Переменные окружения для БД: `LMS_DB_URL`, `LMS_DB_USER`, `LMS_DB_PASSWORD`.