Phase 7: deployment, data import, UI hardening and security fixes

Docker/prod deployment:
- multi-stage Dockerfile (JDK21 build, JRE21 run), docker-compose.prod.yml,
  nginx config for lms.our-place.ru, deploy.sh; DEPLOY/IMPORT guides (UI flow)
- Fix Docker 401: LMS_JWT_JWK_SET_URI for academic/progress; forward-headers

Variant distribution (lab page only):
- round-robin by student level, shared random queue across selected groups,
  least-used variants, manual pins always preserved; occupied/dup labels
- setup page: single form + one «Сохранить всё», batch level/variant for
  selected students (checkboxes)

Grades, defense, materials:
- publication gate + comment lists; defense CSV import (2/3 cols, quotes)
- additional task after defense ("начать заново"); enroll/unenroll students
  from group page; temporary-password lock (no navigation until changed) and
  persistent "Смена пароля"; forced change once
- chapter page /learn/{c}; header: LMS home, Войти, user -> dashboard,
  compact theme toggle; responsive mobile header
- markdown: single newlines are soft breaks; highlight.js with light/dark themes
- lab/content imports ZIP-only (lab.yaml+README+variants/assets,
  chapters tree+assets); duplicate lab numbers rejected; variant ordering
  and date defaults honored

Fixes:
- 500 on student create (@MapsId set before persist); broken dialogs/JS refs in group page
This commit is contained in:
2026-09-14 22:01:46 +03:00
parent 5e60cc3819
commit cdf4fb0ee0
58 changed files with 3967 additions and 884 deletions

View File

@@ -3,9 +3,14 @@
<head><title th:text="${section.title} + ' — LMS'">Раздел</title></head>
<body>
<div id="content">
<a th:href="@{/learn}" class="nav-link">← Все материалы</a>
<h1 class="page-title mt-4" th:text="${section.title}">Раздел</h1>
<p class="text-sm text-muted mb-6">Глава: <span th:text="${chapter.title}">—</span></p>
<nav class="text-sm mb-4 breadcrumb">
<a th:href="@{/learn}" class="nav-link">Материалы</a>
<span class="nav-sep">/</span>
<a th:href="@{/learn/{c}(c=${chapter.slug})}" class="nav-link" th:text="${chapter.title}">Глава</a>
<span class="nav-sep">/</span>
<span th:text="${section.title}">Раздел</span>
</nav>
<h1 class="page-title" th:text="${section.title}">Раздел</h1>
<div class="card card-flush">
<table>
<thead><tr><th>Статья</th></tr></thead>