feat: Добавил синхронизацию преподавателей из лекций
Backend CI / build-and-test (push) Successful in 55s
Frontend CI / build-and-check (push) Failing after 5m9s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Failing after 12s
🚀 Create and publish a Docker image / Build & publish backend image (push) Has been skipped
🚀 Create and publish a Docker image / Build & publish frontend image (push) Has been skipped
🚀 Create and publish a Docker image / Update stack on Portainer (push) Has been skipped
Backend CI / build-and-test (push) Successful in 55s
Frontend CI / build-and-check (push) Failing after 5m9s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Failing after 12s
🚀 Create and publish a Docker image / Build & publish backend image (push) Has been skipped
🚀 Create and publish a Docker image / Build & publish frontend image (push) Has been skipped
🚀 Create and publish a Docker image / Update stack on Portainer (push) Has been skipped
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Text.Json;
|
||||
using UniVerse.Application.DTOs.Sync;
|
||||
using UniVerse.Application.Interfaces;
|
||||
using UniVerse.Domain.Entities;
|
||||
using UniVerse.Domain.Enums;
|
||||
using UniVerse.Infrastructure.Data;
|
||||
|
||||
namespace UniVerse.Infrastructure.Services;
|
||||
@@ -44,6 +45,7 @@ public class ScheduleSyncService : IScheduleSyncService
|
||||
var courseExternalId = courseUnit?.Id ?? ev.TypeId ?? ev.Id;
|
||||
var courseName = courseUnit?.Name ?? ev.Name;
|
||||
var location = await UpsertEventLocationAsync(events, ev.Id);
|
||||
var teacher = await UpsertEventTeacherAsync(events, ev.Id);
|
||||
var roomId = GetEventRoomId(events, ev.Id);
|
||||
var maxEnrollments = GetRoomCapacity(embeddedRoomCapacityById, roomId);
|
||||
if (maxEnrollments is null && !string.IsNullOrWhiteSpace(roomId))
|
||||
@@ -64,6 +66,7 @@ public class ScheduleSyncService : IScheduleSyncService
|
||||
existing.StartsAt = startsAt;
|
||||
existing.EndsAt = endsAt;
|
||||
existing.LocationId = location?.Id;
|
||||
existing.TeacherId = teacher?.Id;
|
||||
existing.MaxEnrollments = lectureCapacity;
|
||||
existing.UpdatedAt = DateTime.UtcNow;
|
||||
updated++;
|
||||
@@ -81,6 +84,7 @@ public class ScheduleSyncService : IScheduleSyncService
|
||||
_db.Lectures.Add(new Lecture
|
||||
{
|
||||
CourseId = course.Id,
|
||||
TeacherId = teacher?.Id,
|
||||
LocationId = location?.Id,
|
||||
Title = ev.Name,
|
||||
Description = ev.Description,
|
||||
@@ -190,6 +194,79 @@ public class ScheduleSyncService : IScheduleSyncService
|
||||
|
||||
public Task<SyncStatusDto> GetLastSyncStatusAsync() => Task.FromResult(_lastStatus);
|
||||
|
||||
private async Task<User?> UpsertEventTeacherAsync(ModeusEventsResponse events, string eventId)
|
||||
{
|
||||
var personId = events.Embedded?.EventAttendees?
|
||||
.Where(attendee => string.Equals(attendee.RoleId, "TEACH", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(attendee => new
|
||||
{
|
||||
EventId = GetHrefId(attendee.Links?.Event?.Href),
|
||||
PersonId = GetHrefId(attendee.Links?.Person?.Href)
|
||||
})
|
||||
.FirstOrDefault(link => link.EventId == eventId)
|
||||
?.PersonId;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(personId))
|
||||
return null;
|
||||
|
||||
var person = events.Embedded?.Persons?.FirstOrDefault(item => item.Id == personId);
|
||||
var fullName = BuildPersonFullName(person);
|
||||
if (string.IsNullOrWhiteSpace(fullName))
|
||||
return null;
|
||||
|
||||
var existingProfile = await _db.TeacherProfiles
|
||||
.Include(profile => profile.User)
|
||||
.ThenInclude(user => user.Roles)
|
||||
.FirstOrDefaultAsync(profile => profile.ModeusId == personId);
|
||||
|
||||
if (existingProfile != null)
|
||||
{
|
||||
existingProfile.User.DisplayName = fullName;
|
||||
existingProfile.User.UpdatedAt = DateTime.UtcNow;
|
||||
EnsureTeacherRole(existingProfile.User);
|
||||
return existingProfile.User;
|
||||
}
|
||||
|
||||
var email = BuildModeusTeacherEmail(personId);
|
||||
var user = await _db.Users
|
||||
.Include(item => item.Roles)
|
||||
.Include(item => item.TeacherProfile)
|
||||
.FirstOrDefaultAsync(item => item.Email == email);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
user = new User
|
||||
{
|
||||
Email = email,
|
||||
DisplayName = fullName,
|
||||
IsActive = true,
|
||||
TeacherProfile = new TeacherProfile { ModeusId = personId }
|
||||
};
|
||||
user.Roles.Add(new UserRoleAssignment { User = user, Role = UserRole.Teacher });
|
||||
_db.Users.Add(user);
|
||||
await _db.SaveChangesAsync();
|
||||
return user;
|
||||
}
|
||||
|
||||
user.DisplayName = fullName;
|
||||
user.UpdatedAt = DateTime.UtcNow;
|
||||
if (user.TeacherProfile == null)
|
||||
user.TeacherProfile = new TeacherProfile { UserId = user.Id, ModeusId = personId };
|
||||
else
|
||||
user.TeacherProfile.ModeusId = personId;
|
||||
|
||||
EnsureTeacherRole(user);
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
return user;
|
||||
}
|
||||
|
||||
private static void EnsureTeacherRole(User user)
|
||||
{
|
||||
if (!user.Roles.Any(role => role.Role == UserRole.Teacher))
|
||||
user.Roles.Add(new UserRoleAssignment { UserId = user.Id, Role = UserRole.Teacher });
|
||||
}
|
||||
|
||||
private async Task<Location?> UpsertEventLocationAsync(ModeusEventsResponse events, string eventId)
|
||||
{
|
||||
var roomId = GetEventRoomId(events, eventId);
|
||||
@@ -274,6 +351,25 @@ public class ScheduleSyncService : IScheduleSyncService
|
||||
private static int? NormalizeCapacity(int? capacity) =>
|
||||
capacity is > 0 ? capacity : null;
|
||||
|
||||
private static string BuildModeusTeacherEmail(string personId) =>
|
||||
$"modeus-{personId}@modeus.local".ToLowerInvariant();
|
||||
|
||||
private static string? BuildPersonFullName(ModeusPerson? person)
|
||||
{
|
||||
if (person == null)
|
||||
return null;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(person.FullName))
|
||||
return person.FullName.Trim();
|
||||
|
||||
var parts = new[] { person.LastName, person.FirstName, person.MiddleName }
|
||||
.Where(part => !string.IsNullOrWhiteSpace(part))
|
||||
.Select(part => part!.Trim());
|
||||
|
||||
var fullName = string.Join(" ", parts);
|
||||
return string.IsNullOrWhiteSpace(fullName) ? null : fullName;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<string> BuildErrorDetails(
|
||||
Exception exception,
|
||||
string stage,
|
||||
|
||||
Reference in New Issue
Block a user