Files
serega404 85ef2a1c22
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Failing after 10m14s
Frontend CI / build-and-check (push) Failing after 16m12s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Failing after 14m7s
🚀 Create and publish a Docker image / Build & publish backend image (push) Failing after 14m59s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Failing after 14m57s
Backend CI / build-and-test (push) Failing after 13m27s
feat: улучшил синхронизацию лекций
2026-05-24 23:47:23 +03:00

80 lines
5.0 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using UniVerse.Application.DTOs.Sync;
using UniVerse.Application.Interfaces;
namespace UniVerse.Api.Controllers;
/// <summary>Синхронизация данных из внешней системы расписания Modeus (только Admin).</summary>
[ApiController]
[Route("api/v1/sync")]
[Authorize(Roles = "Admin")]
[Produces("application/json")]
public class SyncController : ControllerBase
{
private readonly IScheduleSyncService _sync;
public SyncController(IScheduleSyncService sync) => _sync = sync;
/// <summary>Запустить синхронизацию расписания лекций из Modeus.</summary>
/// <remarks>
/// Только Admin. Выполняет upsert лекций и связанных курсов на основе данных
/// из внешнего API `schedule.rdcenter.ru`. Поддерживает фильтрацию по периоду,
/// размеру выборки, аудиториям, участникам, реализациям курсов/циклов,
/// специальностям, годам набора, профилям, учебным планам и типам занятий.
/// </remarks>
/// <param name="req">Параметры поиска событий во внешнем сервисе расписания.</param>
/// <response code="200">Результат синхронизации: кол-во созданных, обновлённых и пропущенных записей.</response>
/// <response code="401">Требуется аутентификация.</response>
/// <response code="403">Требуется роль Admin.</response>
[HttpPost("schedule")]
[ProducesResponseType(typeof(SyncResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<SyncResultDto>> SyncSchedule([FromBody] SyncScheduleRequest req) =>
Ok(await _sync.SyncScheduleAsync(req));
/// <summary>Получить статус последней синхронизации.</summary>
/// <remarks>Только Admin. Возвращает время и результат последней успешной синхронизации.</remarks>
/// <response code="200">Статус синхронизации.</response>
/// <response code="401">Требуется аутентификация.</response>
/// <response code="403">Требуется роль Admin.</response>
[HttpGet("status")]
[ProducesResponseType(typeof(SyncStatusDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<SyncStatusDto>> Status() =>
Ok(await _sync.GetLastSyncStatusAsync());
/// <summary>Синхронизировать аудитории (локации) из Modeus.</summary>
/// <remarks>
/// Только Admin. Импортирует аудитории из `schedule.rdcenter.ru` и создаёт
/// соответствующие записи в таблице locations.
/// </remarks>
/// <response code="200">Результат синхронизации аудиторий.</response>
/// <response code="401">Требуется аутентификация.</response>
/// <response code="403">Требуется роль Admin.</response>
[HttpPost("rooms")]
[ProducesResponseType(typeof(SyncResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<SyncResultDto>> SyncRooms() =>
Ok(await _sync.SyncRoomsAsync());
/// <summary>Поиск преподавателей в Modeus по ФИО.</summary>
/// <remarks>
/// Только Admin. Ищет преподавателей через внешнее API и возвращает список
/// для ручного импорта. Найденные преподаватели не создаются автоматически.
/// </remarks>
/// <param name="fullname">Полное имя или часть имени преподавателя для поиска.</param>
/// <response code="200">Список найденных преподавателей.</response>
/// <response code="401">Требуется аутентификация.</response>
/// <response code="403">Требуется роль Admin.</response>
[HttpPost("employees")]
[ProducesResponseType(typeof(List<EmployeeDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult> SearchEmployees([FromQuery] string fullname) =>
Ok(await _sync.SearchEmployeesAsync(fullname));
}