Распределение вариантов

This commit is contained in:
2026-09-10 01:03:12 +03:00
commit bbbff6180f
50 changed files with 3537 additions and 0 deletions

108
README.md Normal file
View File

@@ -0,0 +1,108 @@
# LMS: практические занятия по курсу «Промышленное программирование на C»
Минимальное ядро: регистрация, списки студентов, варианты лабораторных и их
распределение. Условие своего варианта студент видит в личном кабинете.
Два микросервиса:
- **lms-api** (`src/backend/lms_api`, :8000) — данные и логика (SQLite), REST `/api/v1`;
- **lms-web** (`src/frontend/lms_web`, :8080) — веб-интерфейс, ходит в API по HTTP.
## Запуск
```bash
make install # .venv + зависимости
make dev # lms-api :8000 + lms-web :8080
# открыть http://127.0.0.1:8080 — при первом запуске создать аккаунт преподавателя
```
Тесты: `make test` (11 проверок, свои порты/БД). В Docker: `make build && make up`
(или `make deploy`); данные — в volume `lms_data`.
## Возможности сейчас
**Преподаватель**
- аккаунт администратора (единственный), смена пароля;
- **Лабораторные** — создаются из JSON-файла с вариантами (см. `examples/lab1.json`):
`variants` с `level: main/advanced`, номером, условием, примерами и указаниями;
если срок сдачи в JSON не задан — автоматически ставится через 25 дней
(3 недели и 4 дня) после создания;
- **Группы** — импорт списков из `.xls/.xlsx` (название из шапки, столбцы:
№ п/п, студенческий номер, ФИО, основа обучения); новым студентам генерируется
пароль (логин = номер студенческого), выгрузка «ФИО, логин, пароль» (xlsx/csv),
сброс пароля;
- **Распределение вариантов**: студенту выбирается уровень (основная /
повышенная), затем по группе раздаются варианты конкретной лабораторной
(уникальны внутри группы, по возможности — между группами; если вариантов
меньше студентов — допустимы повторы), есть ручное назначение номера.
**Студент**
- вход по номеру студенческого и паролю; при первом входе смена пароля обязательна;
- список работ и условие своего варианта (по каждой работе — с примерами
входов/выходов и указаниями).
Остальное (отправка решений, задания на защиту/добор, тренировочные задачи,
оценки) будет добавлено позднее.
## Формат JSON лабораторной (`examples/lab1.json`)
```json
{
"number": 1,
"title": "Одномерные массивы и последовательности",
"semester": "осень",
"deadline": "2026-10-01T23:59",
"points_max": 5,
"goal": "…", "common_requirements": "…",
"variants": [
{ "level": "main", "number": "1", "statement": "…",
"examples": [ { "input": "4\n1 2 3 4", "output": "10", "explanation": "…" } ],
"notes": "…" },
{ "level": "advanced", "number": "21", "statement": "…" }
]
}
```
## Деплой на сервер
### Вариант 1 — Docker (рекомендую)
```bash
# на сервере: скопировать проект, затем
cp .env.example .env
nano .env # FRONTEND_PORT=8080 (или 80), API_PORT=8000
./deploy.sh # соберёт образы и поднимет сервисы
docker compose ps # статус
docker compose logs -f # логи
```
Данные (БД и загрузки) хранятся в volume `lms_data` — переживают перезапуск
и пересборку. Бэкап одной командой:
`docker run --rm -v lms_lms_data:/data -v $PWD:/backup alpine tar czf /backup/lms-backup.tar.gz /data`
Порты для наружу: пользователям нужен только `lms-web` (по умолчанию `:8080`).
`lms-api` достаточно оставить внутри сети compose (в `.env` не публиковать
`API_PORT`, либо ограничить доступ файрволом).
### Вариант 2 — без Docker (процессы через systemd)
```bash
make install
# два юнита (пример /etc/systemd/system/lms-api.service):
# ExecStart=/path/to/lms/.venv/bin/python -m uvicorn lms_api.main:app
# --app-dir /path/to/lms/src/backend --host 0.0.0.0 --port 8000
# Environment=LMS_API_URL=http://127.0.0.1:8000
# и аналогично lms-web на --host 0.0.0.0 --port 8080 (lms_web.main:app, src/frontend)
```
Удобно поставить `lms-web` за nginx (HTTPS, отдача статики проксируется на :8080),
доступ к `/api/v1/*` на :8080 не требуется наружу.
## Структура
```
src/backend/lms_api/ # API: core/{db,security,variants,xls_import}, routers
src/frontend/lms_web/ # веб: routers, templates, static
tests/smoke_test.py # make test
examples/ # ПИ-11БО.xls, ПИ-12БО.xls, lab1.json
Dockerfile docker-compose.yml deploy.sh Makefile data/
```