156 lines
5.0 KiB
C#
156 lines
5.0 KiB
C#
using System.Net.Http.Json;
|
||
using LehrerApp.Core.Interfaces;
|
||
using LehrerApp.Core.Models;
|
||
using LehrerApp.Core.Services;
|
||
|
||
namespace LehrerApp.Sync;
|
||
|
||
/// <summary>
|
||
/// Exportiert einen lesbaren Snapshot der lokalen LiteDB
|
||
/// und pusht ihn zur API – wo er für die WebApp abrufbar ist.
|
||
///
|
||
/// Wird automatisch nach jedem Sync-Zyklus ausgeführt
|
||
/// und kann manuell angestoßen werden.
|
||
/// </summary>
|
||
public class ReadableSnapshotService
|
||
{
|
||
private readonly HttpClient _http;
|
||
private readonly IStudentRepository _students;
|
||
private readonly IGroupRepository _groups;
|
||
private readonly IEnrollmentRepository _enrollments;
|
||
private readonly IExamRepository _exams;
|
||
private readonly IExamResultRepository _examResults;
|
||
private readonly IGradeRepository _grades;
|
||
private readonly IUnitRepository _units;
|
||
private readonly ILessonRepository _lessons;
|
||
private readonly IWorkTaskRepository _tasks;
|
||
private readonly SchoolYearService _schoolYear;
|
||
private readonly string _deviceId;
|
||
|
||
public event Action<string>? StatusChanged;
|
||
|
||
public ReadableSnapshotService(
|
||
HttpClient http,
|
||
IStudentRepository students,
|
||
IGroupRepository groups,
|
||
IEnrollmentRepository enrollments,
|
||
IExamRepository exams,
|
||
IExamResultRepository examResults,
|
||
IGradeRepository grades,
|
||
IUnitRepository units,
|
||
ILessonRepository lessons,
|
||
IWorkTaskRepository tasks,
|
||
SchoolYearService schoolYear,
|
||
string deviceId)
|
||
{
|
||
_http = http;
|
||
_students = students;
|
||
_groups = groups;
|
||
_enrollments = enrollments;
|
||
_exams = exams;
|
||
_examResults = examResults;
|
||
_grades = grades;
|
||
_units = units;
|
||
_lessons = lessons;
|
||
_tasks = tasks;
|
||
_schoolYear = schoolYear;
|
||
_deviceId = deviceId;
|
||
}
|
||
|
||
// ── Export ────────────────────────────────────────────────────────────────
|
||
|
||
public async Task<bool> ExportAndPushAsync(
|
||
CancellationToken ct = default)
|
||
{
|
||
StatusChanged?.Invoke("Snapshot wird erstellt…");
|
||
|
||
try
|
||
{
|
||
var snapshot = BuildSnapshot();
|
||
|
||
StatusChanged?.Invoke("Snapshot wird übertragen…");
|
||
var response = await _http.PostAsJsonAsync(
|
||
"/api/snapshot/readable", snapshot, ct);
|
||
|
||
if (!response.IsSuccessStatusCode)
|
||
{
|
||
StatusChanged?.Invoke(
|
||
$"Übertragung fehlgeschlagen: {response.StatusCode}");
|
||
return false;
|
||
}
|
||
|
||
StatusChanged?.Invoke(
|
||
$"Snapshot übertragen – {snapshot.Meta.StudentCount} Schüler, " +
|
||
$"{snapshot.Meta.GroupCount} Gruppen");
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusChanged?.Invoke($"Fehler: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// ── Snapshot aufbauen ─────────────────────────────────────────────────────
|
||
|
||
private ReadableSnapshot BuildSnapshot()
|
||
{
|
||
var schoolYear = _schoolYear.CurrentSchoolYear();
|
||
var groups = _groups.GetBySchoolYear(schoolYear);
|
||
var groupIds = groups.Select(g => g.Id).ToHashSet();
|
||
|
||
var students = _students.GetAll();
|
||
var enrollments = groups
|
||
.SelectMany(g => _enrollments.GetByGroupAndYear(g.Id, schoolYear))
|
||
.ToList();
|
||
|
||
var exams = groupIds
|
||
.SelectMany(gid => _exams.GetByGroup(gid))
|
||
.ToList();
|
||
|
||
var examResults = exams
|
||
.SelectMany(e => _examResults.GetByExam(e.Id))
|
||
.ToList();
|
||
|
||
var grades = groupIds
|
||
.SelectMany(gid => _grades.GetByGroup(gid))
|
||
.ToList();
|
||
|
||
var units = groupIds
|
||
.SelectMany(gid => _units.GetByGroup(gid))
|
||
.ToList();
|
||
|
||
var lessons = units
|
||
.SelectMany(u => _lessons.GetByUnit(u.Id))
|
||
.ToList();
|
||
|
||
var tasks = _tasks.GetAll()
|
||
.Where(t => t.Status != WorkTaskStatus.Done)
|
||
.ToList();
|
||
|
||
var snapshot = new ReadableSnapshot
|
||
{
|
||
SchoolYear = schoolYear,
|
||
Students = students,
|
||
Groups = groups,
|
||
Enrollments = enrollments,
|
||
Exams = exams,
|
||
ExamResults = examResults,
|
||
Grades = grades,
|
||
Units = units,
|
||
Lessons = lessons,
|
||
Tasks = tasks,
|
||
Meta = new SnapshotMeta
|
||
{
|
||
StudentCount = students.Count,
|
||
GroupCount = groups.Count,
|
||
ExamCount = exams.Count,
|
||
ExportedByDevice = _deviceId,
|
||
OldestData = DateTime.UtcNow.AddYears(-1), // vereinfacht
|
||
},
|
||
};
|
||
|
||
return snapshot;
|
||
}
|
||
}
|