psb_hack/README.md

258 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Lectio
**Lectio** — Система позволяет создавать курсы с лекциями и заданиями, записываться на них, отмечать прочитанные материалы, загружать решения с файлами любой сложности, а преподавателям — выставлять ручные оценки. Реализована ролевая модель (студент / преподаватель / администратор), автоматический подсчёт прогресса по курсу, детальный журнал успеваемости с максимальными оценками и статусом чтения лекций, а также личный кабинет студента, где он видит только свою успеваемость.
## Технологический стек
* Backend: FastAPI (Python), SQLAlchemy 2.0, PostgreSQL, JWT-аутентификация
* Frontend: React + Vite + JavaScript + Ant Design + RTK Query
* Инфраструктура: Docker, Kubernetes (microk8s), Helm-чарт, cert-manager + Lets Encrypt
## Развернутый дистрибутив
WEB: https://lectio.numerum.team
API: https://api.lectio.numerum.team (с автоматической Swagger-документацией)
Хранение файлов: PersistentVolume с hostPath
## Структура проекта
### API
Бэкенд построен на FastAPI с луковой архитектурой.
```
app/
├── controllers/ — FastAPI-роутеры (auth, courses, lessons, tasks, solutions и т.д.)
├── infrastructure/ — сервисы бизнес-логики (gradebook_service, solutions_service и др.)
├── application/ — репозитории (работа с БД через SQLAlchemy 2.0 async)
├── domain/
│ ├── models/ — SQLAlchemy-модели (ORM)
│ └── entities/ — Pydantic-схемы для запросов/ответов
├── database/ — сессии, Alembic-миграции
├── core/ — константы, настройки
└── main.py, settings.py
```
API спроектирован так, что добавление новых сущностей (например, сертификаты, тесты, группы) требует минимум изменений — достаточно добавить модель, репозиторий, сервис и роутер.
### WEB
Фронтенд реализован на React + Vite + JavaScript с использованием UI-библиотеки Ant Design и state-менеджмента через RTK Query.
```
src/
├── Api/ — RTK Query API-слайсы (authApi, coursesApi, gradebookApi, solutionsApi и др.)
├── App/ — маршрутизация, PrivateRoute, AdminRoute, ErrorBoundary
├── Components/
│ ├── Layouts/ — MainLayout (шапка, сайдбар, адаптивность)
│ ├── Pages/ — все страницы: CoursesPage, CourseDetailPage, GradebookPage, Login, Profile и др.
│ └── Widgets/ — переиспользуемые компоненты (модалки, лоадеры)
├── Redux/ — store + слайсы состояния (auth, courses, modals)
├── Core/ — константы, конфиги (VITE_BASE_URL, роли)
├── Hooks/ — кастомные хуки (useAuthUtils и др.)
└── Styles/ — глобальные стили
```
## Система ролей
В системе реализована строгая ролевая модель с тремя ролями. Права проверяются как на бэкенде (зависимости FastAPI), так и на фронтенде (PrivateRoute / AdminRoute).
### Администратор
- Всё, что может преподаватель
- Управление пользователями (создание, редактирование, удаление, смена роли)
- Управление ролями и статусами
- Просмотр и редактирование всех курсов и их содержимого
- Доступ ко всем журналам успеваемости
### Преподаватель
- Создавать, редактировать и удалять свои курсы
- Добавлять/редактировать лекции и задания
- Назначать себе и другим преподавателям курсы
- Просматривать полный журнал успеваемости по своим курсам
- Выставлять оценки и комментарии к решениям студентов
- Скачивать все файлы решений
### Студент
- Просматривать список всех курсов и записываться на них
- Просматривать лекции и отмечать их как «прочитанные»
- Загружать решения заданий
- Видеть свой прогресс по каждому курсу
- Видеть свою успеваемость в журнале (только свою)
- Редактировать свой профиль (ФИО, фото и т.д.)
## Развертывание проекта
### API
Бэкенд можно запустить тремя способами — от самого простого до полноценного production-деплоймента.
#### 1. Локальный запуск (без Docker)
```bash
# Клонируем репозиторий
git clone https://github.com/AndreiDuvakin/lectio.git
cd lectio/api
# Создаём виртуальное окружение и устанавливаем зависимости
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r req.txt
# Создаём файл .env в корне api/
cp .env.example .env
# Редактируем .env — обязательно заполняем:
DB_DRIVER=postgresql+asyncpg
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=lectio
DB_SCHEMA=public
SECRET_KEY=your_very_strong_secret_key_here
# Применяем миграции
alembic upgrade head
# Запускаем сервер
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
API: http://localhost:8000
#### 2. Запуск через Docker
Обратите внимание, что для хранения файлов необходимо создавать хранилище.
**Вариант A — просто тянуть готовый образ**
```bash
docker run -d \
--name lectio-api \
-p 8000:8000 \
-e DB_DRIVER=postgresql+asyncpg \
-e DB_HOST=host.docker.internal \
-e DB_PORT=5432 \
-e DB_USER=postgres \
-e DB_PASSWORD=your_password \
-e DB_NAME=lectio \
-e DB_SCHEMA=public \
-e SECRET_KEY=supersecretkey123 \
-v ./uploads:/app/uploads \
andreiduvakin/lectio-api:latest
```
**Вариант B — собрать локально**
Запускается из папки api:
```bash
docker build -t lectio-api . -а app/Dockerfile
docker run -d --name lectio-api -p 8000:8000 lectio-api
```
#### 3. Production-развёртывание в Kubernetes
Используется Helm-чарт **k8s/helm/lectio-api**.
```bash
# Устанавливаем чарт (пример для нашего microk8s)
helm upgrade --install lectio-web k8s/helm/lectio-web --namespace lectio-web --create-namespace
```
Что нужно настроить в **values.yaml**:
```
env:
DB_DRIVER: postgresql+asyncpg
DB_HOST: db.numerum.team
DB_PORT: 30000
DB_USER: lectio
DB_NAME: lectio
DB_SCHEMA: public
```
**Secret** с чувствительными данными:
```
# k8s/helm/lectio-api/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: lectio-api-secret
type: Opaque
data:
SECRET_KEY: base64_encoded_very_long_key==
DB_PASSWORD: base64_encoded_password==
```
**ОБРАТИТЕ ВНИМАНИЕ**
В настоящем решении не предоставлен действительный файл **k8s/helm/lectio-api/templates/secrets.yaml** - для предотвращения несанкционированного доступа к нашей базе данных. Для ВАШЕЙ конфигурации нужно создавать свой файл.
PersistentVolume автоматически создаётся через pvc.yaml и монтирует папку /mnt/k8s_storage/lectio-api/uploads на хосте — все загруженные студентами файлы сохраняются между перезапусками.
После деплоя:
API: https://api.lectio.numerum.team/
Swagger/ReDoc: https://api.lectio.numerum.team/docs
Именно так система работает в продакшене прямо сейчас — с HTTPS, Lets Encrypt, персистентным хранилищем и автоматическим масштабированием.
### WEB
Фронтенд можно запустить тремя способами — от локальной разработки до production-развёртывания в Kubernetes.
### 1. Локальный запуск
```bash
git clone https://github.com/AndreiDuvakin/lectio.git
cd lectio/web
# Устанавливаем зависимости
npm install
# Создаём .env файл (в корне web/)
echo "VITE_BASE_URL=http://localhost:8000/api/v1
VITE_ROOT_ROLE_NAME=root" > .env
# Запускаем dev-сервер
npm run dev
```
Приложение будет доступно по адресу: http://localhost:5173
### 2. Запуск через Docker
Запускается из папки web:
**Вариант A — готовый образ**
Готовый образ уже собран с продакшен-настройками!
**VITE_BASE_URL** и **VITE_ROOT_ROLE_NAME** жёстко зашиты в образ на этапе сборки:
```Dockerfile
ENV VITE_BASE_URL=https://api.lectio.numerum.team/api/v1
ENV VITE_ROOT_ROLE_NAME=root
```
Поэтому запуск предельно прост:
```bash
docker run -d \
--name lectio-web \
-p 3000:3000 \
andreiduvakin/lectio-web:latest
```
**Вариант B — сборка локально**
```bash
docker run -d \
--name lectio-web \
-p 3000:3000 \
--build-arg VITE_BASE_URL=http://localhost:8000/api/v1 \
andreiduvakin/lectio-web:latest
```
Приложение доступно по адресу: http://localhost:3000
### 3. Production-развёртывание в Kubernetes
Используется Helm-чарт k8s/helm/lectio-web.
```bash
helm upgrade --install lectio-web k8s/helm/lectio-web --namespace lectio-web --create-namespace
```
Поскольку переменные окружения уже зашиты в образ на этапе **npm run build**, в **values.yaml** ничего передавать не нужно.
После деплоя приложение доступно по адресу:
https://lectio.numerum.team
Именно так работает продакшен прямо сейчас.
## Демонстрация
Видео УСТАНОВКИ и ДЕМОНСТРАЦИИ проекта достпуно по ссылке: https://disk.yandex.ru/i/sDi_GnOUBnpVaA
Пожалуйста, досмотрите видео целиком
## Регистрация
В системе можно зарегистрироваться перейдя на страницу регистрации из страницы авторизации, но по умолчанию вам будет выдана роль Студент без зачисления на курс