Files
magistr/AGENTS.md
Zuev d69eab1c12
All checks were successful
Build and Push Docker Images / build-and-push-backend (push) Successful in 3m37s
Build and Push Docker Images / build-and-push-frontend (push) Successful in 11s
Build and Push Docker Images / deploy-to-k8s (push) Successful in 1m10s
chore: Update Gitea workflow actions to newer versions, add AGENTS.md, and modify gitignore.
2026-03-17 01:30:48 +03:00

202 lines
13 KiB
Markdown
Executable File
Raw 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.
# AGENTS.md - Руководство для агентных помощников
## Обзор проекта
Проект представляет собой систему управления университетским расписанием.
- **Backend**: Java 17, Spring Boot 3.2.5 (Мультитенантная архитектура: отдельная БД для каждого клиента)
- **Frontend**: Vanilla JavaScript + HTML/CSS (без фреймворков)
- **Database**: PostgreSQL (множество БД, управляются через Flyway)
- **Локальный URL**: localhost:80
- **Продакшн URL**: https://magistr.zuev.company
---
## Структура директорий
```
magistr/
├── backend/ # Java Spring Boot приложение
│ └── src/main/java/com/magistr/app/
│ ├── controller/ # REST контроллеры
│ ├── model/ # JPA сущности
│ ├── dto/ # Data Transfer Objects
│ ├── repository/ # Spring Data JPA репозитории
│ ├── config/ # Конфигурация приложения
│ ├── utils/ # Утилиты
│ └── src/main/resources/db/migration/ # Flyway SQL миграции (версионирование схемы БД)
├── frontend/ # Статические файлы
│ ├── admin/ # Интерфейс администратора
│ ├── teacher/ # Интерфейс преподавателя
│ └── student/ # Интерфейс студента
├── compose.yaml # Docker Compose конфигурация
└── .env # Переменные окружения
```
**Внешние зависимости (родительская директория)**
На уровень выше расположен `../caddy-proxy/`. Это реверс-прокси, обрабатывающий трафик для `magistr.zuev.company`. Если возникают проблемы с доменом или внешним доступом, проверяйте `Caddyfile` там.
так же на уровень выше расположен конфиг kubernetes `../k8s/`, все файлы сборки на проде расположены там.
---
## Команды сборки и запуска
### Docker Compose (основной способ)
Сборка и запуск всех сервисов (backend, frontend, PostgreSQL) выполняется через Docker Compose.
```bash
# Сборка и запуск всех сервисов
docker compose up -d --build
# Остановка всех сервисов
docker compose down
# Просмотр логов всех сервисов
docker compose logs -f
# Просмотр логов конкретного сервиса
docker compose logs -f backend
# Пересоздать контейнер базы данных (полный сброс данных и повтор миграций Flyway)
docker compose down -v
docker compose up -d db
```
### Frontend
Статические файлы обслуживаются через Apache (httpd:alpine). Изменения в файлах frontend требуют пересборки контейнера.
---
## Соглашения о коде (Code Style)
### Java (Backend)
**Именование:**
- Классы: PascalCase (например, `LessonsController`, `LessonResponse`)
- Методы и переменные: camelCase
- Константы: UPPER_SNAKE_CASE
- Пакеты: lowercase (например, `com.magistr.app.controller`)
**Импорты:**
- Группировка: static imports, затем external packages, затем internal
- Используйте wildcard imports для пакетов того же модуля: `import com.magistr.app.model.*;`
- Порядок: java.*, javax.*, external.*, internal.*
**Форматирование:**
- Отступы: 4 пробела (стандарт Java)
- Фигурные скобки: K&R style (открывающая на той же строке)
- Длина строки: до 120 символов
- Всегда используйте фигурные скобки для if/for/while
**Типы и аннотации:**
- Используйте явные типы вместо `var` для возвращаемых значений публичных методов
- Аннотации JPA: `@Entity`, `@Table`, `@Id`, `@GeneratedValue`, `@Column`
- Используйте `@JsonInclude(JsonInclude.Include.NON_NULL)` для DTO
- Для логгирования используйте SLF4J: `LoggerFactory.getLogger(ClassName.class)`
**Обработка ошибок:**
- Возвращайте `ResponseEntity<?>` с соответствующим HTTP статусом
- Логируйте ошибки с полным стектрейсом: `logger.error("msg: {}", e.getMessage(), e)`
- Для валидации используйте отдельные классы-валидаторы (см. `DayAndWeekValidator`)
**Архитектура контроллеров:**
- Используйте constructor injection для зависимостей
- Все endpoints имеют префикс `/api/`
- Возвращайте понятные сообщения об ошибках на русском языке
### Frontend (JavaScript)
**Именование:**
- Файлы: kebab-case (например, `main.js`, `schedule-view.js`)
- Функции и переменные: camelCase
- Константы: UPPER_SNAKE_CASE
**Модули:**
- Используйте ES6 modules с `import`/`export`
- Всегда указывайте расширение при импорте: `import { x } from './api.js';`
**Форматирование:**
- Отступы: 4 пробела
- Используйте template literals вместо конкатенации строк
- Предпочитайте `const` переменные, используйте `let` только при необходимости переприсваивания
**Лучшие практики:**
- Используйте `async/await` для асинхронных операций
- Всегда обрабатывайте ошибки в блоках `catch`
- Используйте деструктуризацию объектов
- Кешируйте DOM-элементы в переменные
---
## Работа с базой данных и мультитенантностью
**Мультитенантность:**
- Приложение поддерживает множество клиентов (университетов). Каждый клиент имеет свою изолированную базу данных PostgreSQL.
- Маршрутизация к нужной БД происходит динамически на основе поддомена (`TenantInterceptor` -> `TenantContext` -> `TenantRoutingDataSource`).
- Список клиентов хранится в Kubernetes `ConfigMap` (`tenants-config`), который монтируется в под бэкенда как `/config/tenants.json`.
- Локально список берётся из файла `backend/tenants.json`.
- При добавлении нового клиента в интерфейсе `DatabaseController` через K8s API обновляет `ConfigMap`. Все реплики бэкенда заметят изменения и в фоне инициализируют новый пул соединений (`TenantConfigWatcher`).
**Миграции схемы (Flyway):**
- Автогенерация Hibernate ОТКЛЮЧЕНА (`ddl-auto=none`). Структура баз данных управляется строго через **Flyway**.
- Все изменения схемы БД вносятся путем создания новых файлов в `backend/src/main/resources/db/migration/` (название строго `V2__add_new_table.sql` и т.д.).
- **ЗАПРЕЩЕНО** изменять существующие файлы миграций (например, `V1__init.sql`), которые уже закоммичены. Это сломает контрольные суммы Flyway.
- Flyway запускается программно при первом обращении к базе тенанта. Чтобы запустить Flyway для уже существующих тенантов (накатить V2), необходимо перезапустить бэкенд: `kubectl rollout restart deployment backend -n magistr`.
- Для локального сброса базы до изначального состояния: `docker compose down -v && docker compose up -d`.
**Сущности и связи:**
- Foreign keys с `ON DELETE CASCADE` для поддержания целостности
- Используйте расширение `pgcrypto` для хеширования паролей (bcrypt)
---
## Функциональные требования к системе (Бизнес-логика)
### 1. Ролевая модель
- **Администратор (Деканат)**: Полный доступ, настройка топологии университета, управление аудиторным фондом, подтверждение переносов, регистрация инцидентов.
- **Преподаватель**: Просмотр своего расписания, подача заявок на перенос, отметка о своём отсутствии.
- **Студент**: Только просмотр расписания (Read-only).
### 2. Управление ресурсами и топология
- **Управление аудиториями**:
- Указание вместимости.
- Привязка доступного оборудования (через сущность Equipments: Проектор, ПК, Лаборатория).
- Установка статуса "Не доступно" (блокирует назначение пар в этот период).
- **Управление группами**:
- Управление списком студентов (и возможность деления на подгруппы).
- **Управление дисциплинами**:
- Создание предметов и привязка их к преподавателям (какие дисциплины имеет право вести конкретный преподаватель).
### 3. Логика расписания
- **Сетка**: 7 фиксированных слотов по 1.5 часа (08:00 - 09:30, и т.д.) + поддержка кастомного времени.
- **Проверка конфликтов**:
- *Критический конфликт*: Преподаватель не может находиться в двух разных аудиториях одновременно.
- *Уточнение по преподавателям*: Преподаватель может иметь несколько пар одновременно (для разных групп), только если они проходят в одной и той же аудитории (потоковая лекция).
- **Потоковые занятия**:
- Возможность назначить одну лекцию сразу нескольким группам (технически — несколько записей в БД или одна запись со списком групп).
- Проверка вместимости: вместимость аудитории должна покрывать суммарную численность всех групп, находящихся в этой аудитории в данный слот.
### 4. Управление инцидентами (Инклюзия отсутствия)
- **Отсутствие (Sickness/Business Trip)**: Регистрация отсутствия преподавателя (с указанием причины и периода дат).
- **Обнаружение коллизий**: Автоматическая подсветка конфликтующих пар в расписании (Red Zone).
- **Система разрешения конфликтов (Resolution Wizard)**:
- Предложение подходящей замены преподавателя на этот слот.
- Предложение переноса занятия на другое время или в другую аудиторию.
---
## Языковые требования
- **Все ответы и комментарии на русском языке**
- Сообщения об ошибках и логи на русском
- Пользовательский интерфейс на русском
---
## Существующие правила проекта
См. `.agent/rules/main.md` и `.agent/rules/database_schema.md` для полного контекста о функциональных требованиях и схеме БД.