Baustein 3: Repositories verdrahten Teil A (Kapitel 10)
OnChange-Hook auf den 19 einfachen Repositories (keine Kaskaden/Batches) ergaenzt: SeatingPlan, GroupMembership, GradingKeyTemplate, Grade, GradingScheme, ReportGrade, Unit, Lesson, WorkTask, TimeEntry, ParticipationAspect, ParticipationSection, Subject, ShorthandCode, AlternativeLessonPath, TimetableSlot, SchoolHoliday, SupervisionDuty, SubstitutionEntry. Mechanisch, ein Aufruf nach dem bestehenden Upsert/Delete. Tabellengetriebener Test statt 19 fast identischer Testdateien. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,204 @@
|
|||||||
|
using LehrerApp.Core.Models;
|
||||||
|
using LehrerApp.Data.Repositories;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace LehrerApp.Data.Tests;
|
||||||
|
|
||||||
|
// Baustein 3: prüft für jedes der ~19 "einfachen" Repositories (keine Kaskaden/Batches), dass
|
||||||
|
// Save/Delete den OnChange-Hook mit dem korrekten EntityType auslöst. Tabellengetrieben statt
|
||||||
|
// eine Datei pro Repository, um die immer gleiche Prüfung nicht 19x zu wiederholen.
|
||||||
|
public sealed class ChangeHookMatrixTests
|
||||||
|
{
|
||||||
|
public static IEnumerable<object[]> Cases()
|
||||||
|
{
|
||||||
|
yield return Case("SeatingPlan", nameof(SeatingPlan), db =>
|
||||||
|
{
|
||||||
|
var group = new LearningGroup { Name = "8a", SchoolYear = "2025/26" };
|
||||||
|
new GroupRepository(db).Save(group);
|
||||||
|
var repo = new SeatingPlanRepository(db);
|
||||||
|
var plan = new SeatingPlan { GroupId = group.Id, Name = "Standard", Rows = 2, Columns = 2 };
|
||||||
|
repo.Save(plan);
|
||||||
|
return (plan.Id, () => repo.Delete(plan.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("GroupMembership", nameof(GroupMembership), db =>
|
||||||
|
{
|
||||||
|
var repo = new GroupMembershipRepository(db);
|
||||||
|
var membership = new GroupMembership { StudentId = Guid.NewGuid(), GroupId = Guid.NewGuid() };
|
||||||
|
repo.Save(membership);
|
||||||
|
return (membership.Id, () => repo.Delete(membership.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("GradingKeyTemplate", nameof(GradingKeyTemplate), db =>
|
||||||
|
{
|
||||||
|
var repo = new GradingKeyTemplateRepository(db);
|
||||||
|
var template = new GradingKeyTemplate { Name = "Standard", GradingSystem = GradingSystem.Points0To15 };
|
||||||
|
repo.Save(template);
|
||||||
|
return (template.Id, () => repo.Delete(template.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("Grade", nameof(Grade), db =>
|
||||||
|
{
|
||||||
|
var repo = new GradeRepository(db);
|
||||||
|
var grade = new Grade { GroupId = Guid.NewGuid(), StudentId = Guid.NewGuid(), Value = "2" };
|
||||||
|
repo.Save(grade);
|
||||||
|
return (grade.Id, () => repo.Delete(grade.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("GradingScheme", nameof(GradingScheme), db =>
|
||||||
|
{
|
||||||
|
var repo = new GradingSchemeRepository(db);
|
||||||
|
var scheme = new GradingScheme { GroupId = Guid.NewGuid(), ExamsPercent = 60, ParticipationPercent = 30, OtherPercent = 10 };
|
||||||
|
repo.Save(scheme);
|
||||||
|
return (scheme.Id, () => repo.Delete(scheme.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("ReportGrade", nameof(ReportGrade), db =>
|
||||||
|
{
|
||||||
|
var repo = new ReportGradeRepository(db);
|
||||||
|
var grade = new ReportGrade { StudentId = Guid.NewGuid(), GroupId = Guid.NewGuid(), Period = "1. Halbjahr" };
|
||||||
|
repo.Save(grade);
|
||||||
|
return (grade.Id, () => repo.Delete(grade.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("Unit", nameof(Unit), db =>
|
||||||
|
{
|
||||||
|
var repo = new UnitRepository(db);
|
||||||
|
var unit = new Unit { GroupId = Guid.NewGuid(), Title = "Einheit" };
|
||||||
|
repo.Save(unit);
|
||||||
|
return (unit.Id, () => repo.Delete(unit.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("Lesson", nameof(Lesson), db =>
|
||||||
|
{
|
||||||
|
var repo = new LessonRepository(db);
|
||||||
|
var lesson = new Lesson { UnitId = Guid.NewGuid(), GroupId = Guid.NewGuid(), Date = new DateOnly(2026, 3, 12) };
|
||||||
|
repo.Save(lesson);
|
||||||
|
return (lesson.Id, () => repo.Delete(lesson.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("WorkTask", nameof(WorkTask), db =>
|
||||||
|
{
|
||||||
|
var repo = new WorkTaskRepository(db);
|
||||||
|
var task = new WorkTask { Title = "Klausur korrigieren", Category = TaskCategory.Correction };
|
||||||
|
repo.Save(task);
|
||||||
|
return (task.Id, () => repo.Delete(task.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("TimeEntry", nameof(TimeEntry), db =>
|
||||||
|
{
|
||||||
|
var repo = new TimeEntryRepository(db);
|
||||||
|
var entry = new TimeEntry { Date = new DateOnly(2026, 3, 12), DurationMinutes = 30, Category = "Vorbereitung" };
|
||||||
|
repo.Save(entry);
|
||||||
|
return (entry.Id, () => repo.Delete(entry.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("ParticipationAspect", nameof(ParticipationAspect), db =>
|
||||||
|
{
|
||||||
|
var repo = new ParticipationAspectRepository(db);
|
||||||
|
var aspect = new ParticipationAspect { GroupId = Guid.NewGuid(), Key = "quality", Label = "Qualität" };
|
||||||
|
repo.Save(aspect);
|
||||||
|
return (aspect.Id, () => repo.Delete(aspect.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("ParticipationSection", nameof(ParticipationSection), db =>
|
||||||
|
{
|
||||||
|
var repo = new ParticipationSectionRepository(db);
|
||||||
|
var section = new ParticipationSection
|
||||||
|
{
|
||||||
|
GroupId = Guid.NewGuid(), Label = "1. Abschnitt",
|
||||||
|
StartDate = new DateOnly(2026, 3, 1), EndDate = new DateOnly(2026, 4, 1),
|
||||||
|
};
|
||||||
|
repo.Save(section);
|
||||||
|
return (section.Id, () => repo.Delete(section.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("Subject", nameof(Subject), db =>
|
||||||
|
{
|
||||||
|
var repo = new SubjectRepository(db);
|
||||||
|
var subject = new Subject { Name = "Chemie" };
|
||||||
|
repo.Save(subject);
|
||||||
|
return (subject.Id, () => repo.Delete(subject.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("ShorthandCode", nameof(ShorthandCode), db =>
|
||||||
|
{
|
||||||
|
var repo = new ShorthandCodeRepository(db);
|
||||||
|
var code = new ShorthandCode { Code = "Tb", Label = "Tafelbild" };
|
||||||
|
repo.Save(code);
|
||||||
|
return (code.Id, () => repo.Delete(code.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("AlternativeLessonPath", nameof(AlternativeLessonPath), db =>
|
||||||
|
{
|
||||||
|
var repo = new AlternativeLessonPathRepository(db);
|
||||||
|
var path = new AlternativeLessonPath { Name = "Kurzversion" };
|
||||||
|
repo.Save(path);
|
||||||
|
return (path.Id, () => repo.Delete(path.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("TimetableSlot", nameof(TimetableSlot), db =>
|
||||||
|
{
|
||||||
|
var repo = new TimetableSlotRepository(db);
|
||||||
|
var slot = new TimetableSlot { GroupId = Guid.NewGuid(), Weekday = DayOfWeek.Tuesday, PeriodNumber = 3 };
|
||||||
|
repo.Save(slot);
|
||||||
|
return (slot.Id, () => repo.Delete(slot.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("SchoolHoliday", nameof(SchoolHoliday), db =>
|
||||||
|
{
|
||||||
|
var repo = new SchoolHolidayRepository(db);
|
||||||
|
var holiday = new SchoolHoliday { Name = "Osterferien", StartDate = new DateOnly(2026, 3, 30), EndDate = new DateOnly(2026, 4, 10) };
|
||||||
|
repo.Save(holiday);
|
||||||
|
return (holiday.Id, () => repo.Delete(holiday.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("SupervisionDuty", nameof(SupervisionDuty), db =>
|
||||||
|
{
|
||||||
|
var repo = new SupervisionDutyRepository(db);
|
||||||
|
var duty = new SupervisionDuty { Weekday = DayOfWeek.Monday, AfterPeriod = 2, Location = "Pausenhof" };
|
||||||
|
repo.Save(duty);
|
||||||
|
return (duty.Id, () => repo.Delete(duty.Id));
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return Case("SubstitutionEntry", nameof(SubstitutionEntry), db =>
|
||||||
|
{
|
||||||
|
var repo = new SubstitutionEntryRepository(db);
|
||||||
|
var entry = new SubstitutionEntry { Date = new DateOnly(2026, 3, 12), Kind = SubstitutionKind.Lesson, PeriodNumber = 3, Description = "Vertretung 8a" };
|
||||||
|
repo.Save(entry);
|
||||||
|
return (entry.Id, () => repo.Delete(entry.Id));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(Cases))]
|
||||||
|
public void Save_LoestOnChangeMitKorrektemEntityTypeAus(
|
||||||
|
string _, string entityType, Func<LiteDbContext, (Guid Id, Action Delete)> setup)
|
||||||
|
{
|
||||||
|
using var db = new LiteDbContext(new MemoryStream());
|
||||||
|
var calls = new List<(string EntityType, string Operation)>();
|
||||||
|
db.OnChange = (type, id, op, payload) => calls.Add((type, op));
|
||||||
|
|
||||||
|
setup(db);
|
||||||
|
|
||||||
|
Assert.Contains((entityType, "Save"), calls);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(Cases))]
|
||||||
|
public void Delete_LoestOnChangeMitKorrektemEntityTypeAus(
|
||||||
|
string _, string entityType, Func<LiteDbContext, (Guid Id, Action Delete)> setup)
|
||||||
|
{
|
||||||
|
using var db = new LiteDbContext(new MemoryStream());
|
||||||
|
var (id, delete) = setup(db);
|
||||||
|
var calls = new List<(string EntityType, string EntityId, string Operation)>();
|
||||||
|
db.OnChange = (type, entId, op, payload) => calls.Add((type, entId, op));
|
||||||
|
|
||||||
|
delete();
|
||||||
|
|
||||||
|
Assert.Contains((entityType, id.ToString(), "Delete"), calls);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object[] Case(string name, string entityType, Func<LiteDbContext, (Guid Id, Action Delete)> setup) =>
|
||||||
|
[name, entityType, setup];
|
||||||
|
}
|
||||||
@@ -132,6 +132,7 @@ public class SeatingPlanRepository(LiteDbContext db) : ISeatingPlanRepository
|
|||||||
|
|
||||||
plan.UpdatedAt = DateTime.UtcNow;
|
plan.UpdatedAt = DateTime.UtcNow;
|
||||||
db.SeatingPlans.Upsert(plan);
|
db.SeatingPlans.Upsert(plan);
|
||||||
|
db.OnChange?.Invoke(nameof(SeatingPlan), plan.Id.ToString(), "Save", plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
@@ -139,6 +140,7 @@ public class SeatingPlanRepository(LiteDbContext db) : ISeatingPlanRepository
|
|||||||
if (db.SeatingPlans.FindById(id) is { } plan)
|
if (db.SeatingPlans.FindById(id) is { } plan)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, plan.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, plan.GroupId);
|
||||||
db.SeatingPlans.Delete(id);
|
db.SeatingPlans.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(SeatingPlan), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,12 +159,14 @@ public class GroupMembershipRepository(LiteDbContext db) : IGroupMembershipRepos
|
|||||||
if (existing is not null && existing.Id != membership.Id)
|
if (existing is not null && existing.Id != membership.Id)
|
||||||
throw new InvalidOperationException("Der Schüler ist dieser Lerngruppe bereits zugeordnet.");
|
throw new InvalidOperationException("Der Schüler ist dieser Lerngruppe bereits zugeordnet.");
|
||||||
db.Memberships.Upsert(membership);
|
db.Memberships.Upsert(membership);
|
||||||
|
db.OnChange?.Invoke(nameof(GroupMembership), membership.Id.ToString(), "Save", membership);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.Memberships.FindById(id) is { } membership)
|
if (db.Memberships.FindById(id) is { } membership)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, membership.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, membership.GroupId);
|
||||||
db.Memberships.Delete(id);
|
db.Memberships.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(GroupMembership), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,8 +225,17 @@ public class GradingKeyTemplateRepository(LiteDbContext db) : IGradingKeyTemplat
|
|||||||
public List<GradingKeyTemplate> GetByGradingSystem(GradingSystem system) =>
|
public List<GradingKeyTemplate> GetByGradingSystem(GradingSystem system) =>
|
||||||
db.GradingKeyTemplates.Find(t => t.GradingSystem == system).OrderBy(t => t.Name).ToList();
|
db.GradingKeyTemplates.Find(t => t.GradingSystem == system).OrderBy(t => t.Name).ToList();
|
||||||
public GradingKeyTemplate? GetById(Guid id) => db.GradingKeyTemplates.FindById(id);
|
public GradingKeyTemplate? GetById(Guid id) => db.GradingKeyTemplates.FindById(id);
|
||||||
public void Save(GradingKeyTemplate t) { t.UpdatedAt = DateTime.UtcNow; db.GradingKeyTemplates.Upsert(t); }
|
public void Save(GradingKeyTemplate t)
|
||||||
public void Delete(Guid id) => db.GradingKeyTemplates.Delete(id);
|
{
|
||||||
|
t.UpdatedAt = DateTime.UtcNow;
|
||||||
|
db.GradingKeyTemplates.Upsert(t);
|
||||||
|
db.OnChange?.Invoke(nameof(GradingKeyTemplate), t.Id.ToString(), "Save", t);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.GradingKeyTemplates.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(GradingKeyTemplate), id.ToString(), "Delete", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GradeRepository(LiteDbContext db) : IGradeRepository
|
public class GradeRepository(LiteDbContext db) : IGradeRepository
|
||||||
@@ -235,12 +248,14 @@ public class GradeRepository(LiteDbContext db) : IGradeRepository
|
|||||||
{
|
{
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, g.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, g.GroupId);
|
||||||
db.Grades.Upsert(g);
|
db.Grades.Upsert(g);
|
||||||
|
db.OnChange?.Invoke(nameof(Grade), g.Id.ToString(), "Save", g);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.Grades.FindById(id) is { } grade)
|
if (db.Grades.FindById(id) is { } grade)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, grade.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, grade.GroupId);
|
||||||
db.Grades.Delete(id);
|
db.Grades.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(Grade), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,12 +269,14 @@ public class GradingSchemeRepository(LiteDbContext db) : IGradingSchemeRepositor
|
|||||||
if (s.GroupId is Guid groupId) ArchivedGroupWriteGuard.EnsureActive(db, groupId);
|
if (s.GroupId is Guid groupId) ArchivedGroupWriteGuard.EnsureActive(db, groupId);
|
||||||
s.UpdatedAt = DateTime.UtcNow;
|
s.UpdatedAt = DateTime.UtcNow;
|
||||||
db.GradingSchemes.Upsert(s);
|
db.GradingSchemes.Upsert(s);
|
||||||
|
db.OnChange?.Invoke(nameof(GradingScheme), s.Id.ToString(), "Save", s);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.GradingSchemes.FindById(id)?.GroupId is Guid groupId)
|
if (db.GradingSchemes.FindById(id)?.GroupId is Guid groupId)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, groupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, groupId);
|
||||||
db.GradingSchemes.Delete(id);
|
db.GradingSchemes.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(GradingScheme), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,12 +290,14 @@ public class ReportGradeRepository(LiteDbContext db) : IReportGradeRepository
|
|||||||
ArchivedGroupWriteGuard.EnsureActive(db, r.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, r.GroupId);
|
||||||
r.UpdatedAt = DateTime.UtcNow;
|
r.UpdatedAt = DateTime.UtcNow;
|
||||||
db.ReportGrades.Upsert(r);
|
db.ReportGrades.Upsert(r);
|
||||||
|
db.OnChange?.Invoke(nameof(ReportGrade), r.Id.ToString(), "Save", r);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.ReportGrades.FindById(id) is { } grade)
|
if (db.ReportGrades.FindById(id) is { } grade)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, grade.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, grade.GroupId);
|
||||||
db.ReportGrades.Delete(id);
|
db.ReportGrades.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(ReportGrade), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,12 +311,14 @@ public class UnitRepository(LiteDbContext db) : IUnitRepository
|
|||||||
ArchivedGroupWriteGuard.EnsureActive(db, u.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, u.GroupId);
|
||||||
u.UpdatedAt = DateTime.UtcNow;
|
u.UpdatedAt = DateTime.UtcNow;
|
||||||
db.Units.Upsert(u);
|
db.Units.Upsert(u);
|
||||||
|
db.OnChange?.Invoke(nameof(Unit), u.Id.ToString(), "Save", u);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.Units.FindById(id) is { } unit)
|
if (db.Units.FindById(id) is { } unit)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, unit.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, unit.GroupId);
|
||||||
db.Units.Delete(id);
|
db.Units.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(Unit), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,12 +336,14 @@ public class LessonRepository(LiteDbContext db) : ILessonRepository
|
|||||||
ArchivedGroupWriteGuard.EnsureActive(db, l.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, l.GroupId);
|
||||||
l.UpdatedAt = DateTime.UtcNow;
|
l.UpdatedAt = DateTime.UtcNow;
|
||||||
db.Lessons.Upsert(l);
|
db.Lessons.Upsert(l);
|
||||||
|
db.OnChange?.Invoke(nameof(Lesson), l.Id.ToString(), "Save", l);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.Lessons.FindById(id) is { } lesson)
|
if (db.Lessons.FindById(id) is { } lesson)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, lesson.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, lesson.GroupId);
|
||||||
db.Lessons.Delete(id);
|
db.Lessons.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(Lesson), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,8 +380,17 @@ public class WorkTaskRepository(LiteDbContext db) : IWorkTaskRepository
|
|||||||
db.Tasks.Find(t => t.Status == s).OrderBy(t => t.DueDate).ToList();
|
db.Tasks.Find(t => t.Status == s).OrderBy(t => t.DueDate).ToList();
|
||||||
public List<WorkTask> GetAll() =>
|
public List<WorkTask> GetAll() =>
|
||||||
db.Tasks.FindAll().OrderBy(t => t.Status).ThenBy(t => t.DueDate).ToList();
|
db.Tasks.FindAll().OrderBy(t => t.Status).ThenBy(t => t.DueDate).ToList();
|
||||||
public void Save(WorkTask t) { t.UpdatedAt = DateTime.UtcNow; db.Tasks.Upsert(t); }
|
public void Save(WorkTask t)
|
||||||
public void Delete(Guid id) => db.Tasks.Delete(id);
|
{
|
||||||
|
t.UpdatedAt = DateTime.UtcNow;
|
||||||
|
db.Tasks.Upsert(t);
|
||||||
|
db.OnChange?.Invoke(nameof(WorkTask), t.Id.ToString(), "Save", t);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.Tasks.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(WorkTask), id.ToString(), "Delete", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TimeEntryRepository(LiteDbContext db) : ITimeEntryRepository
|
public class TimeEntryRepository(LiteDbContext db) : ITimeEntryRepository
|
||||||
@@ -369,8 +401,16 @@ public class TimeEntryRepository(LiteDbContext db) : ITimeEntryRepository
|
|||||||
db.TimeEntries.Find(e => e.Date >= from && e.Date <= to).OrderBy(e => e.Date).ToList();
|
db.TimeEntries.Find(e => e.Date >= from && e.Date <= to).OrderBy(e => e.Date).ToList();
|
||||||
public List<TimeEntry> GetByTask(Guid id) =>
|
public List<TimeEntry> GetByTask(Guid id) =>
|
||||||
db.TimeEntries.Find(e => e.TaskId == id).ToList();
|
db.TimeEntries.Find(e => e.TaskId == id).ToList();
|
||||||
public void Save(TimeEntry e) => db.TimeEntries.Upsert(e);
|
public void Save(TimeEntry e)
|
||||||
public void Delete(Guid id) => db.TimeEntries.Delete(id);
|
{
|
||||||
|
db.TimeEntries.Upsert(e);
|
||||||
|
db.OnChange?.Invoke(nameof(TimeEntry), e.Id.ToString(), "Save", e);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.TimeEntries.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(TimeEntry), id.ToString(), "Delete", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ParticipationSessionRepository(LiteDbContext db) : IParticipationSessionRepository
|
public class ParticipationSessionRepository(LiteDbContext db) : IParticipationSessionRepository
|
||||||
@@ -453,12 +493,14 @@ public class ParticipationAspectRepository(LiteDbContext db) : IParticipationAsp
|
|||||||
throw new InvalidOperationException("Ein Aspekt mit diesem Schlüssel existiert für diese Gruppe bereits.");
|
throw new InvalidOperationException("Ein Aspekt mit diesem Schlüssel existiert für diese Gruppe bereits.");
|
||||||
a.UpdatedAt = DateTime.UtcNow;
|
a.UpdatedAt = DateTime.UtcNow;
|
||||||
db.ParticipationAspects.Upsert(a);
|
db.ParticipationAspects.Upsert(a);
|
||||||
|
db.OnChange?.Invoke(nameof(ParticipationAspect), a.Id.ToString(), "Save", a);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.ParticipationAspects.FindById(id)?.GroupId is Guid groupId)
|
if (db.ParticipationAspects.FindById(id)?.GroupId is Guid groupId)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, groupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, groupId);
|
||||||
db.ParticipationAspects.Delete(id);
|
db.ParticipationAspects.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(ParticipationAspect), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,12 +512,14 @@ public class ParticipationSectionRepository(LiteDbContext db) : IParticipationSe
|
|||||||
{
|
{
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, s.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, s.GroupId);
|
||||||
db.ParticipationSections.Upsert(s);
|
db.ParticipationSections.Upsert(s);
|
||||||
|
db.OnChange?.Invoke(nameof(ParticipationSection), s.Id.ToString(), "Save", s);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.ParticipationSections.FindById(id) is { } section)
|
if (db.ParticipationSections.FindById(id) is { } section)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, section.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, section.GroupId);
|
||||||
db.ParticipationSections.Delete(id);
|
db.ParticipationSections.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(ParticipationSection), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,12 +539,14 @@ public class SubjectRepository(LiteDbContext db) : ISubjectRepository
|
|||||||
throw new InvalidOperationException("Ein Fach mit diesem Namen existiert bereits.");
|
throw new InvalidOperationException("Ein Fach mit diesem Namen existiert bereits.");
|
||||||
s.UpdatedAt = DateTime.UtcNow;
|
s.UpdatedAt = DateTime.UtcNow;
|
||||||
db.Subjects.Upsert(s);
|
db.Subjects.Upsert(s);
|
||||||
|
db.OnChange?.Invoke(nameof(Subject), s.Id.ToString(), "Save", s);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.Groups.Exists(g => g.SubjectId == id) || db.CompetencyDomains.Exists(d => d.SubjectId == id))
|
if (db.Groups.Exists(g => g.SubjectId == id) || db.CompetencyDomains.Exists(d => d.SubjectId == id))
|
||||||
throw new InvalidOperationException("Das Fach wird noch von einer Lerngruppe oder einem Kompetenzkatalog verwendet.");
|
throw new InvalidOperationException("Das Fach wird noch von einer Lerngruppe oder einem Kompetenzkatalog verwendet.");
|
||||||
db.Subjects.Delete(id);
|
db.Subjects.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(Subject), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,8 +564,13 @@ public class ShorthandCodeRepository(LiteDbContext db) : IShorthandCodeRepositor
|
|||||||
throw new InvalidOperationException("Ein Kürzel mit diesem Code existiert bereits.");
|
throw new InvalidOperationException("Ein Kürzel mit diesem Code existiert bereits.");
|
||||||
c.UpdatedAt = DateTime.UtcNow;
|
c.UpdatedAt = DateTime.UtcNow;
|
||||||
db.ShorthandCodes.Upsert(c);
|
db.ShorthandCodes.Upsert(c);
|
||||||
|
db.OnChange?.Invoke(nameof(ShorthandCode), c.Id.ToString(), "Save", c);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.ShorthandCodes.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(ShorthandCode), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id) => db.ShorthandCodes.Delete(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AlternativeLessonPathRepository(LiteDbContext db) : IAlternativeLessonPathRepository
|
public class AlternativeLessonPathRepository(LiteDbContext db) : IAlternativeLessonPathRepository
|
||||||
@@ -537,8 +588,13 @@ public class AlternativeLessonPathRepository(LiteDbContext db) : IAlternativeLes
|
|||||||
throw new InvalidOperationException("Ein alternativer Ablauf mit diesem Namen existiert bereits.");
|
throw new InvalidOperationException("Ein alternativer Ablauf mit diesem Namen existiert bereits.");
|
||||||
p.UpdatedAt = DateTime.UtcNow;
|
p.UpdatedAt = DateTime.UtcNow;
|
||||||
db.AlternativeLessonPaths.Upsert(p);
|
db.AlternativeLessonPaths.Upsert(p);
|
||||||
|
db.OnChange?.Invoke(nameof(AlternativeLessonPath), p.Id.ToString(), "Save", p);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.AlternativeLessonPaths.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(AlternativeLessonPath), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id) => db.AlternativeLessonPaths.Delete(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TimetableSlotRepository(LiteDbContext db) : ITimetableSlotRepository
|
public class TimetableSlotRepository(LiteDbContext db) : ITimetableSlotRepository
|
||||||
@@ -555,20 +611,30 @@ public class TimetableSlotRepository(LiteDbContext db) : ITimetableSlotRepositor
|
|||||||
if (occupied is not null && occupied.Id != slot.Id)
|
if (occupied is not null && occupied.Id != slot.Id)
|
||||||
throw new InvalidOperationException("Diese Stunde ist bereits belegt.");
|
throw new InvalidOperationException("Diese Stunde ist bereits belegt.");
|
||||||
db.TimetableSlots.Upsert(slot);
|
db.TimetableSlots.Upsert(slot);
|
||||||
|
db.OnChange?.Invoke(nameof(TimetableSlot), slot.Id.ToString(), "Save", slot);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id)
|
public void Delete(Guid id)
|
||||||
{
|
{
|
||||||
if (db.TimetableSlots.FindById(id) is { } slot)
|
if (db.TimetableSlots.FindById(id) is { } slot)
|
||||||
ArchivedGroupWriteGuard.EnsureActive(db, slot.GroupId);
|
ArchivedGroupWriteGuard.EnsureActive(db, slot.GroupId);
|
||||||
db.TimetableSlots.Delete(id);
|
db.TimetableSlots.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(TimetableSlot), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SchoolHolidayRepository(LiteDbContext db) : ISchoolHolidayRepository
|
public class SchoolHolidayRepository(LiteDbContext db) : ISchoolHolidayRepository
|
||||||
{
|
{
|
||||||
public List<SchoolHoliday> GetAll() => db.SchoolHolidays.FindAll().OrderBy(h => h.StartDate).ToList();
|
public List<SchoolHoliday> GetAll() => db.SchoolHolidays.FindAll().OrderBy(h => h.StartDate).ToList();
|
||||||
public void Save(SchoolHoliday holiday) => db.SchoolHolidays.Upsert(holiday);
|
public void Save(SchoolHoliday holiday)
|
||||||
public void Delete(Guid id) => db.SchoolHolidays.Delete(id);
|
{
|
||||||
|
db.SchoolHolidays.Upsert(holiday);
|
||||||
|
db.OnChange?.Invoke(nameof(SchoolHoliday), holiday.Id.ToString(), "Save", holiday);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.SchoolHolidays.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(SchoolHoliday), id.ToString(), "Delete", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SupervisionDutyRepository(LiteDbContext db) : ISupervisionDutyRepository
|
public class SupervisionDutyRepository(LiteDbContext db) : ISupervisionDutyRepository
|
||||||
@@ -582,8 +648,13 @@ public class SupervisionDutyRepository(LiteDbContext db) : ISupervisionDutyRepos
|
|||||||
if (occupied is not null && occupied.Id != duty.Id)
|
if (occupied is not null && occupied.Id != duty.Id)
|
||||||
throw new InvalidOperationException("Für diese Pause ist bereits eine Aufsicht eingetragen.");
|
throw new InvalidOperationException("Für diese Pause ist bereits eine Aufsicht eingetragen.");
|
||||||
db.SupervisionDuties.Upsert(duty);
|
db.SupervisionDuties.Upsert(duty);
|
||||||
|
db.OnChange?.Invoke(nameof(SupervisionDuty), duty.Id.ToString(), "Save", duty);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.SupervisionDuties.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(SupervisionDuty), id.ToString(), "Delete", null);
|
||||||
}
|
}
|
||||||
public void Delete(Guid id) => db.SupervisionDuties.Delete(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SubstitutionEntryRepository(LiteDbContext db) : ISubstitutionEntryRepository
|
public class SubstitutionEntryRepository(LiteDbContext db) : ISubstitutionEntryRepository
|
||||||
@@ -591,8 +662,16 @@ public class SubstitutionEntryRepository(LiteDbContext db) : ISubstitutionEntryR
|
|||||||
public List<SubstitutionEntry> GetAll() => db.SubstitutionEntries.FindAll().OrderBy(e => e.Date).ToList();
|
public List<SubstitutionEntry> GetAll() => db.SubstitutionEntries.FindAll().OrderBy(e => e.Date).ToList();
|
||||||
public List<SubstitutionEntry> GetByDate(DateOnly date) =>
|
public List<SubstitutionEntry> GetByDate(DateOnly date) =>
|
||||||
db.SubstitutionEntries.Find(e => e.Date == date).ToList();
|
db.SubstitutionEntries.Find(e => e.Date == date).ToList();
|
||||||
public void Save(SubstitutionEntry entry) => db.SubstitutionEntries.Upsert(entry);
|
public void Save(SubstitutionEntry entry)
|
||||||
public void Delete(Guid id) => db.SubstitutionEntries.Delete(id);
|
{
|
||||||
|
db.SubstitutionEntries.Upsert(entry);
|
||||||
|
db.OnChange?.Invoke(nameof(SubstitutionEntry), entry.Id.ToString(), "Save", entry);
|
||||||
|
}
|
||||||
|
public void Delete(Guid id)
|
||||||
|
{
|
||||||
|
db.SubstitutionEntries.Delete(id);
|
||||||
|
db.OnChange?.Invoke(nameof(SubstitutionEntry), id.ToString(), "Delete", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CompetencyDomainRepository(LiteDbContext db) : ICompetencyDomainRepository
|
public class CompetencyDomainRepository(LiteDbContext db) : ICompetencyDomainRepository
|
||||||
|
|||||||
Reference in New Issue
Block a user