docs: обновил документацию README.md
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 11s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 13s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 14s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 9s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 11s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 13s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 14s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 9s
This commit is contained in:
@@ -1,165 +1,295 @@
|
||||
# UniVerse
|
||||
|
||||
UniVerse — backend (ASP.NET Core) для университетской платформы расписания, лекций, отзывов и геймификации.
|
||||
UniVerse - веб-платформа для открытых межнаправленческих лекций университета. Система помогает студентам находить занятия других направлений, записываться на них, получать напоминания, оставлять отзывы, а преподавателям и администраторам - видеть аналитику посещаемости и качества обратной связи.
|
||||
|
||||
[Документация API](backend/UniVerse.Api/openapi.json)
|
||||
[Документация бекнда](docs/backend.md)
|
||||
Проект состоит из Vue 3 frontend, ASP.NET Core backend и PostgreSQL-хранилища. Backend предоставляет REST API, интегрируется с Microsoft Entra ID, Modeus API и OpenAI-compatible LLM, а frontend реализует отдельные сценарии для ролей `Student`, `Teacher` и `Admin`.
|
||||
|
||||
## Что внутри
|
||||
- [OpenAPI snapshot](backend/UniVerse.Api/openapi.json)
|
||||
- [Backend notes](docs/backend.md)
|
||||
- [Frontend E2E tests](docs/playwright-tests.md)
|
||||
- [Load testing](docs/load-testing-k6.md)
|
||||
|
||||
- Расписание/события и сущности: курсы, лекции, аудитории (locations)
|
||||
- Отзывы студентов с фоновым LLM-анализом (качество/тональность/теги)
|
||||
- Геймификация: XP/уровни, монеты, достижения
|
||||
- JWT-аутентификация и роли (`Admin`, `Teacher`, `Student`)
|
||||
- Swagger/OpenAPI в Development
|
||||
## Возможности
|
||||
|
||||
## Технологии
|
||||
### Для студента
|
||||
|
||||
- .NET 10 / ASP.NET Core
|
||||
- PostgreSQL + EF Core (Npgsql)
|
||||
- Serilog
|
||||
- Swagger (Swashbuckle)
|
||||
- Каталог открытых лекций с поиском, фильтрацией, карточками и деталями занятия.
|
||||
- Запись на лекцию и отмена записи с учетом лимитов мест и персонального лимита активных записей.
|
||||
- Личный дашборд: ближайшие лекции, прогресс уровня, XP, монеты, достижения и статистика.
|
||||
- Мои лекции: список записей, скачивание `.ics` для одной лекции или всего расписания, ссылка календарной подписки.
|
||||
- Отзывы о лекциях с оценкой `Like`, `Neutral`, `Dislike`.
|
||||
- Уведомления и профиль пользователя.
|
||||
|
||||
## Структура репозитория
|
||||
### Для преподавателя
|
||||
|
||||
Код backend лежит в папке `backend/` и собран в solution `backend/UniVerse.sln`:
|
||||
- Дашборд преподавателя по своим занятиям.
|
||||
- Просмотр списка лекций и записей.
|
||||
- Аналитика отзывов: тональность, информативность, теги LLM и агрегированные показатели.
|
||||
- Работа с отзывами без раскрытия лишних персональных данных студентам.
|
||||
|
||||
- `backend/UniVerse.Api` — Web API (контроллеры, middleware, background services)
|
||||
- `backend/UniVerse.Application` — DTO, интерфейсы сервисов, маппинги
|
||||
- `backend/UniVerse.Domain` — доменные сущности/enum/исключения
|
||||
- `backend/UniVerse.Infrastructure` — EF Core, миграции, реализации сервисов, внешние клиенты
|
||||
### Для администратора
|
||||
|
||||
- Административная панель со статистикой пользователей, лекций, записей и ожидающих LLM-анализа отзывов.
|
||||
- Управление пользователями: роли `Student`, `Teacher`, `Admin`, блокировка и разблокировка аккаунтов.
|
||||
- Управление лекциями и создание новых занятий.
|
||||
- Синхронизация расписания, аудиторий и преподавателей из Modeus.
|
||||
- Модерация отзывов, повторный запуск LLM-анализа и настройка промпта.
|
||||
- Управление курсами, тегами, локациями и достижениями через API.
|
||||
|
||||
### Платформенные функции
|
||||
|
||||
- Microsoft Entra ID login и dev-login для локальной разработки.
|
||||
- JWT access token и refresh flow через cookie.
|
||||
- Ролевая защита маршрутов frontend и endpoint-level авторизация backend.
|
||||
- Фоновая очередь анализа отзывов через LLM.
|
||||
- Геймификация: XP, уровни, монеты, достижения и транзакции.
|
||||
- Email-уведомления и планировщик Quartz.
|
||||
- Rate limiting, Serilog, Prometheus metrics и Swagger UI в Development.
|
||||
- Aspire AppHost для совместного локального запуска API и Vite frontend.
|
||||
- Docker Compose для production-окружения с backend, frontend и PostgreSQL.
|
||||
|
||||
## Архитектура
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Student[Student UI] --> Frontend[Vue 3 frontend]
|
||||
Teacher[Teacher UI] --> Frontend
|
||||
Admin[Admin UI] --> Frontend
|
||||
|
||||
Frontend -->|/api/v1 JSON| Api[ASP.NET Core Web API]
|
||||
Api --> Auth[Auth and RBAC]
|
||||
Api --> App[Application services]
|
||||
App --> Domain[Domain model]
|
||||
App --> Infra[Infrastructure]
|
||||
Infra --> Db[(PostgreSQL)]
|
||||
Infra --> Llm[OpenAI-compatible LLM]
|
||||
Infra --> Modeus[Modeus schedule API]
|
||||
Infra --> Mail[SMTP email]
|
||||
|
||||
Api --> Quartz[Quartz jobs]
|
||||
Quartz --> Mail
|
||||
Api --> Metrics[Prometheus /metrics]
|
||||
```
|
||||
|
||||
Backend следует Clean Architecture:
|
||||
|
||||
- `UniVerse.Api` - controllers, middleware, Swagger, DI, background services.
|
||||
- `UniVerse.Application` - DTO, interfaces, service contracts, mappings, prompts.
|
||||
- `UniVerse.Domain` - entities, enums, domain exceptions, domain services.
|
||||
- `UniVerse.Infrastructure` - EF Core, migrations, external clients, notification and business service implementations.
|
||||
- `UniVerse.AppHost` - Aspire host для локального запуска API и frontend.
|
||||
- `UniVerse.Api.Tests` - unit и integration tests.
|
||||
|
||||
Frontend построен на Vue 3, TypeScript, Vite, Pinia и Vue Router:
|
||||
|
||||
- `src/views/student` - кабинет студента, каталог, карточка лекции, мои лекции, отзывы, профиль, уведомления.
|
||||
- `src/views/teacher` - кабинет преподавателя, лекции, аналитика.
|
||||
- `src/views/admin` - дашборд, пользователи, лекции, отзывы.
|
||||
- `src/api` - typed API client, DTO-типы и мапперы.
|
||||
- `src/components/ui` и `src/components/layout` - переиспользуемые UI и layout-компоненты.
|
||||
|
||||
## Сценарий записи и анализа отзыва
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor S as Student
|
||||
participant UI as Vue frontend
|
||||
participant API as UniVerse API
|
||||
participant DB as PostgreSQL
|
||||
participant Q as ReviewAnalysisQueue
|
||||
participant LLM as LLM API
|
||||
participant G as GamificationService
|
||||
|
||||
S->>UI: Выбирает открытую лекцию
|
||||
UI->>API: POST /api/v1/lectures/{id}/enroll
|
||||
API->>DB: Проверяет лимиты и сохраняет запись
|
||||
API-->>UI: 204 No Content
|
||||
S->>UI: Оставляет отзыв
|
||||
UI->>API: POST /api/v1/reviews
|
||||
API->>DB: Сохраняет отзыв со статусом Pending
|
||||
API->>Q: Ставит отзыв в очередь анализа
|
||||
Q->>LLM: Анализ качества, тональности и тегов
|
||||
LLM-->>Q: Результат анализа
|
||||
Q->>DB: Обновляет отзыв
|
||||
Q->>G: Начисляет XP, монеты и достижения
|
||||
G->>DB: Сохраняет транзакции и награды
|
||||
```
|
||||
|
||||
Основные группы таблиц:
|
||||
|
||||
- Пользователи и доступ: `users`, `user_roles`, `student_profiles`, `teacher_profiles`, `refresh_tokens`.
|
||||
- Расписание: `courses`, `lectures`, `locations`, `tags`, `course_tags`.
|
||||
- Участие и обратная связь: `lecture_enrollments`, `reviews`, `review_prompt_settings`.
|
||||
- Геймификация: `achievements`, `user_achievements`, `coin_transactions`, `level_thresholds`.
|
||||
- Уведомления: `user_notifications`.
|
||||
|
||||
## API
|
||||
|
||||
Базовый префикс: `/api/v1`.
|
||||
|
||||
- `/auth` - Microsoft login, dev-login, refresh, logout, текущий пользователь.
|
||||
- `/users` - профиль, статистика, роли, активность, записи, достижения, транзакции, `.ics`.
|
||||
- `/lectures` - каталог лекций, CRUD, запись, посещаемость, отзывы по лекции.
|
||||
- `/reviews` - создание, список, модерация, повторный анализ, настройка LLM-промпта.
|
||||
- `/courses` - курсы и привязка тегов.
|
||||
- `/tags` - теги и дерево тегов.
|
||||
- `/locations` - аудитории и локации.
|
||||
- `/achievements` - каталог достижений.
|
||||
- `/notifications` - уведомления, отметка прочтения, отправка и планирование.
|
||||
- `/sync` - синхронизация расписания, аудиторий и преподавателей из Modeus.
|
||||
|
||||
В Development Swagger UI доступен по адресу `http://localhost:5019/api/docs`.
|
||||
|
||||
## Стек
|
||||
|
||||
### Frontend
|
||||
|
||||
- Vue 3, TypeScript, Vite.
|
||||
- Pinia, Vue Router.
|
||||
- Playwright E2E tests.
|
||||
- Nginx для production-раздачи и проксирования.
|
||||
|
||||
### Backend
|
||||
|
||||
- .NET 10, ASP.NET Core Web API.
|
||||
- EF Core 10, Npgsql, PostgreSQL.
|
||||
- Swashbuckle/OpenAPI.
|
||||
- Serilog, Prometheus, ASP.NET Core Rate Limiting.
|
||||
- Quartz для отложенных уведомлений.
|
||||
- Aspire AppHost.
|
||||
- xUnit, NSubstitute, WebApplicationFactory.
|
||||
|
||||
### Интеграции
|
||||
|
||||
- Microsoft Entra ID.
|
||||
- Modeus schedule API.
|
||||
- OpenAI-compatible LLM API.
|
||||
- SMTP email.
|
||||
|
||||
## Требования
|
||||
|
||||
- .NET SDK 10 (`dotnet --version` должен показать `10.x`)
|
||||
- PostgreSQL 14+ (или Docker для поднятия Postgres)
|
||||
- .NET SDK 10.x.
|
||||
- Node.js `^20.19.0 || >=22.12.0`.
|
||||
- pnpm.
|
||||
- PostgreSQL 17+ или Docker.
|
||||
- Для production - Docker Engine и Docker Compose.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Основные настройки лежат в `backend/UniVerse.Api/appsettings.json`:
|
||||
Backend читает настройки из `backend/UniVerse.Api/appsettings.json`, `appsettings.Development.json` и переменных окружения в формате `Section__Key`.
|
||||
|
||||
- `ConnectionStrings:DefaultConnection` — строка подключения к Postgres
|
||||
- `Jwt:*` — секрет/issuer/audience и сроки жизни токенов
|
||||
- `Cors:Origins` — origin’ы фронтенда
|
||||
- `Llm:*` — настройки LLM (OpenAI-compatible)
|
||||
- `ModeusApi:*` — настройки интеграции с Modeus
|
||||
Основные секции:
|
||||
|
||||
Можно переопределять через переменные окружения в формате `Section__Key`, например:
|
||||
- `ConnectionStrings:DefaultConnection` - подключение к PostgreSQL.
|
||||
- `Jwt:*` - issuer, audience, secret и сроки жизни токенов.
|
||||
- `AzureAd:*` - Microsoft Entra ID.
|
||||
- `Cors:Origins` - разрешенные origin frontend.
|
||||
- `RateLimiting:*` - глобальный fixed-window limiter.
|
||||
- `Llm:*` - base URL, API key, model и параметры анализа отзывов.
|
||||
- `ModeusApi:*` - base URL, API key и timeout.
|
||||
- `Email:Smtp:*` - SMTP-настройки для уведомлений.
|
||||
|
||||
- `ConnectionStrings__DefaultConnection`
|
||||
- `Jwt__Secret`
|
||||
- `Llm__ApiKey`
|
||||
- `ModeusApi__ApiKey`
|
||||
Frontend использует переменные:
|
||||
|
||||
## Быстрый старт (локально)
|
||||
- `VITE_API_BASE_URL` - базовый адрес API, по умолчанию `/api`.
|
||||
- `VITE_API_PROXY_TARGET` - target для Vite proxy при запуске через Aspire.
|
||||
- `VITE_AUTH_RETURN_URL` - frontend callback URL, по умолчанию `/auth/callback`.
|
||||
|
||||
1) Поднять Postgres (пример через Docker):
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Установить зависимости frontend
|
||||
|
||||
```bash
|
||||
pnpm -C frontend install
|
||||
```
|
||||
|
||||
### 2. Поднять PostgreSQL
|
||||
|
||||
```bash
|
||||
docker run --rm --name universe-postgres \
|
||||
-e POSTGRES_DB=universe \
|
||||
-e POSTGRES_USER=postgres \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-p 5432:5432 \
|
||||
postgres:18
|
||||
-e POSTGRES_DB=universe \
|
||||
-e POSTGRES_USER=postgres \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-p 5432:5432 \
|
||||
postgres:18
|
||||
```
|
||||
|
||||
2) Применить миграции (первый раз потребуется `dotnet-ef`):
|
||||
### 3. Применить миграции
|
||||
|
||||
```bash
|
||||
dotnet tool install --global dotnet-ef
|
||||
|
||||
cd backend
|
||||
dotnet ef database update \
|
||||
--project UniVerse.Infrastructure \
|
||||
--startup-project UniVerse.Api
|
||||
--project UniVerse.Infrastructure \
|
||||
--startup-project UniVerse.Api
|
||||
```
|
||||
|
||||
3) Запустить API:
|
||||
### 4. Запустить backend
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
dotnet run --project UniVerse.Api --launch-profile http
|
||||
dotnet run --project backend/UniVerse.Api --launch-profile http
|
||||
```
|
||||
|
||||
По умолчанию (профиль `http`) API поднимется на `http://localhost:5019`.
|
||||
Swagger UI доступен в Development по адресу: `http://localhost:5019/swagger`.
|
||||
API по умолчанию слушает `http://localhost:5019`.
|
||||
|
||||
## Запуск в Docker
|
||||
|
||||
В `backend/UniVerse.Api/Dockerfile` настроена сборка контейнера API.
|
||||
### 5. Запустить frontend
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
docker build -f UniVerse.Api/Dockerfile -t universe-api .
|
||||
|
||||
docker run --rm -p 8080:8080 \
|
||||
-e ASPNETCORE_URLS=http://+:8080 \
|
||||
-e ConnectionStrings__DefaultConnection="Host=host.docker.internal;Port=5432;Database=universe;Username=postgres;Password=postgres" \
|
||||
universe-api
|
||||
pnpm -C frontend dev
|
||||
```
|
||||
|
||||
Примечание: на Linux `host.docker.internal` может быть недоступен — проще запускать Postgres тоже в Docker и соединять контейнеры в одной сети.
|
||||
Vite frontend по умолчанию слушает `http://localhost:5173` и проксирует `/api` на `http://localhost:5019`.
|
||||
|
||||
## Аутентификация
|
||||
## Запуск через Aspire
|
||||
|
||||
- `POST /api/v1/auth/login/dev` — дев-логин (только в `Development`). Удобно для локальной разработки.
|
||||
- `GET /api/v1/auth/login/microsoft` — старт входа через Microsoft Entra ID (бэкенд сам делает редирект на Microsoft).
|
||||
- `GET /api/v1/auth/callback/microsoft` — callback, куда Microsoft возвращает `code`.
|
||||
- `POST /api/v1/auth/login/microsoft` — обмен `authorizationCode` на токены (полезно для интеграций/ручных тестов). Тело: `{ "authorizationCode": "...", "redirectUri"?: "..." }`.
|
||||
- `POST /api/v1/auth/refresh`, `POST /api/v1/auth/logout`, `GET /api/v1/auth/me`
|
||||
Aspire AppHost запускает API и Vite frontend вместе:
|
||||
|
||||
Для Microsoft Entra ID нужны настройки (через env или appsettings): `AzureAd:TenantId`, `AzureAd:ClientId`, `AzureAd:ClientSecret` (и при необходимости `AzureAd:Instance`, `AzureAd:RedirectUri`, `AzureAd:PostLoginRedirectUri`).
|
||||
```bash
|
||||
pnpm -C frontend install
|
||||
dotnet run --project backend/UniVerse.AppHost/UniVerse.AppHost.csproj
|
||||
```
|
||||
|
||||
Большинство методов API защищены `[Authorize]`.
|
||||
Frontend обычно доступен на `http://localhost:5173`. Target API передается во frontend через `VITE_API_PROXY_TARGET`.
|
||||
|
||||
## Фоновый LLM-анализ отзывов
|
||||
## Docker Compose
|
||||
|
||||
Сервис `LlmProcessingBackgroundService` раз в ~2 минуты берёт отзывы со статусом `Pending` и прогоняет через LLM-клиент.
|
||||
LLM-ключ задаётся через `Llm:ApiKey`.
|
||||
Production compose описан в `docker-compose-prod.yml`:
|
||||
|
||||
Если ключ не задан или внешний сервис недоступен — анализ будет ретраиться, а ошибки логироваться.
|
||||
- `app` - ASP.NET Core backend.
|
||||
- `frontend` - собранный Vue frontend и Nginx.
|
||||
- `db` - PostgreSQL.
|
||||
|
||||
## Интеграция с Modeus
|
||||
Перед запуском задайте переменные окружения для PostgreSQL, JWT, Microsoft auth, CORS и внешних интеграций:
|
||||
|
||||
Эндпоинты синхронизации доступны только администратору:
|
||||
```bash
|
||||
docker compose -f docker-compose-prod.yml up -d
|
||||
```
|
||||
|
||||
- `POST /api/v1/sync/schedule`
|
||||
- `POST /api/v1/sync/rooms`
|
||||
- `POST /api/v1/sync/employees`
|
||||
- `GET /api/v1/sync/status`
|
||||
|
||||
Ключ (если нужен) задаётся через `ModeusApi:ApiKey`.
|
||||
|
||||
## Карта API (high-level)
|
||||
|
||||
Базовый префикс: `/api/v1`.
|
||||
|
||||
- `/auth` — логин/refresh/logout/me
|
||||
- `/users` — профиль/статистика/достижения/транзакции (часть методов — только `Admin`)
|
||||
- `/courses` — курсы и теги (CRUD в основном для `Admin`)
|
||||
- `/lectures` — лекции, записи, посещаемость, отзывы
|
||||
- `/reviews` — отзывы (создание студентом; модерация/реанализ для `Admin`)
|
||||
- `/tags` — теги + дерево тегов
|
||||
- `/locations` — аудитории/локации
|
||||
- `/achievements` — достижения
|
||||
- `/sync` — синхронизация с внешним расписанием (только `Admin`)
|
||||
|
||||
Точные схемы запросов/ответов удобнее смотреть в Swagger.
|
||||
Тестовый compose находится в `docker-compose-test.yml`.
|
||||
|
||||
## Тестирование
|
||||
|
||||
В проекте настроено модульное и интеграционное тестирование (папка `backend/UniVerse.Api.Tests`):
|
||||
|
||||
- **xUnit** в качестве основного фреймворка для тестирования.
|
||||
- **NSubstitute** для создания заглушек (моков) зависимостей сервисов.
|
||||
- Используется `WebApplicationFactory` (`ApiWebApplicationFactory.cs`) для поднятия интеграционного тестового сервера с подменой БД на `InMemory` и отключенными фоновыми сервисами (например, LLM-интеграциями) для изоляции.
|
||||
- Реализованы полные тесты ролевой модели и авторизации (`EndpointAuthorizationTests.cs`), надежно проверяющие все API-конечные точки на политики доступа от имени различных ролей (`Admin`, `Teacher`, `Student`, `Anonymous`).
|
||||
|
||||
Запуск тестов:
|
||||
Backend:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
dotnet test
|
||||
dotnet test backend/UniVerse.sln
|
||||
```
|
||||
|
||||
Frontend type-check и production build:
|
||||
|
||||
```bash
|
||||
pnpm -C frontend build
|
||||
```
|
||||
|
||||
Frontend E2E с mock API:
|
||||
|
||||
```bash
|
||||
pnpm -C frontend test:e2e
|
||||
```
|
||||
|
||||
Load testing helper:
|
||||
|
||||
```bash
|
||||
node frontend/scripts/loadtest-endpoints.js
|
||||
```
|
||||
Reference in New Issue
Block a user