# UniVerse

UniVerse - веб-платформа для открытых межнаправленческих лекций университета. Система помогает студентам находить занятия других направлений, записываться на них, получать напоминания, оставлять отзывы, а преподавателям и администраторам - видеть аналитику посещаемости и качества обратной связи.

Проект состоит из 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)

## Возможности

### Для студента

- Каталог открытых лекций с поиском, фильтрацией, карточками и деталями занятия.
- Запись на лекцию и отмена записи с учетом лимитов мест и персонального лимита активных записей.
- Личный дашборд: ближайшие лекции, прогресс уровня, XP, монеты, достижения и статистика.
- Мои лекции: список записей, скачивание `.ics` для одной лекции или всего расписания, ссылка календарной подписки.
- Отзывы о лекциях с оценкой `Like`, `Neutral`, `Dislike`.
- Уведомления и профиль пользователя.

### Для преподавателя

- Дашборд преподавателя по своим занятиям.
- Просмотр списка лекций и записей.
- Аналитика отзывов: тональность, информативность, теги LLM и агрегированные показатели.
- Работа с отзывами без раскрытия лишних персональных данных студентам.

### Для администратора

- Административная панель со статистикой пользователей, лекций, записей и ожидающих 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.x.
- Node.js `^20.19.0 || >=22.12.0`.
- pnpm.
- PostgreSQL 17+ или Docker.
- Для production - Docker Engine и Docker Compose.

## Конфигурация

Backend читает настройки из `backend/UniVerse.Api/appsettings.json`, `appsettings.Development.json` и переменных окружения в формате `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-настройки для уведомлений.

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. Установить зависимости 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
```

### 3. Применить миграции

```bash
dotnet tool install --global dotnet-ef

cd backend
dotnet ef database update \
  --project UniVerse.Infrastructure \
  --startup-project UniVerse.Api
```

### 4. Запустить backend

```bash
dotnet run --project backend/UniVerse.Api --launch-profile http
```

API по умолчанию слушает `http://localhost:5019`.

### 5. Запустить frontend

```bash
pnpm -C frontend dev
```

Vite frontend по умолчанию слушает `http://localhost:5173` и проксирует `/api` на `http://localhost:5019`.

## Запуск через Aspire

Aspire AppHost запускает API и Vite frontend вместе:

```bash
pnpm -C frontend install
dotnet run --project backend/UniVerse.AppHost/UniVerse.AppHost.csproj
```

Frontend обычно доступен на `http://localhost:5173`. Target API передается во frontend через `VITE_API_PROXY_TARGET`.

## Docker Compose

Production compose описан в `docker-compose-prod.yml`:

- `app` - ASP.NET Core backend.
- `frontend` - собранный Vue frontend и Nginx.
- `db` - PostgreSQL.

Перед запуском задайте переменные окружения для PostgreSQL, JWT, Microsoft auth, CORS и внешних интеграций:

```bash
docker compose -f docker-compose-prod.yml up -d
```

Тестовый compose находится в `docker-compose-test.yml`.

## Тестирование

Backend:

```bash
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
```