Files
LehrerApp/LehrerApp.Sync/ReadableSnapshotService.cs
2026-03-29 23:47:31 +02:00

156 lines
5.0 KiB
C#
Raw Permalink 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.
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;
}
}