CI / build-and-test (push) Canceled after 0s
Ein Zwischenstand ist ein Durchgang aus Stichtag, Anlass und Schülerauswahl (ganze Gruppe, Teilgruppe oder Einzelfall, mit Schnellfilter für gefährdete Schüler). Der Zeugnisnoten-Assistent geht die gewählten Schüler im Zwischenstand-Modus durch und notiert vorläufige schriftliche, mündliche und Gesamtnote samt Notiz. Gespeichert wird das als eigenes Modell InterimGrade, getrennt von der Zeugnisnote. Die Berechnung endet am Stichtag und rechnet den laufenden Mitarbeits-Abschnitt mit ein. Zwischenstände erscheinen im Assistenten als Liste und Marker im Verlauf sowie als graue Spalte in der Notenübersicht (nicht in "Gesamt", nicht im PDF). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
360 lines
14 KiB
C#
360 lines
14 KiB
C#
using LehrerApp.Core.Models;
|
|
|
|
namespace LehrerApp.Core.Interfaces;
|
|
|
|
public interface IStudentRepository
|
|
{
|
|
Student? GetById(Guid id);
|
|
List<Student> GetAll(bool includeInactive = false);
|
|
List<Student> GetByGroup(Guid groupId);
|
|
StudentReferenceSummary GetReferenceSummary(Guid studentId);
|
|
void Save(Student student);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IGroupRepository
|
|
{
|
|
LearningGroup? GetById(Guid id);
|
|
List<LearningGroup> GetAll(bool includeInactive = false);
|
|
List<LearningGroup> GetBySchoolYear(string schoolYear, bool includeInactive = false);
|
|
void Save(LearningGroup group);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ISeatingPlanRepository
|
|
{
|
|
SeatingPlan? GetById(Guid id);
|
|
List<SeatingPlan> GetByGroup(Guid groupId);
|
|
void Save(SeatingPlan plan);
|
|
void Delete(Guid id);
|
|
/// <summary>Stellt einen über <see cref="Delete"/> in den Papierkorb verschobenen Sitzplan
|
|
/// wieder her (14.3). Tut nichts, falls der Papierkorb-Eintrag nicht (mehr) existiert.</summary>
|
|
void Restore(Guid trashId);
|
|
}
|
|
public interface IStudentGroupPlanRepository
|
|
{
|
|
StudentGroupPlan? GetById(Guid id);
|
|
List<StudentGroupPlan> GetByGroup(Guid groupId);
|
|
List<StudentGroupPlan> GetByStudent(Guid studentId);
|
|
void Save(StudentGroupPlan plan);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IGroupMembershipRepository
|
|
{
|
|
List<GroupMembership> GetByStudent(Guid studentId);
|
|
List<GroupMembership> GetByGroup(Guid groupId);
|
|
GroupMembership? GetByStudentAndGroup(Guid studentId, Guid groupId);
|
|
void Save(GroupMembership membership);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IExamRepository
|
|
{
|
|
Exam? GetById(Guid id);
|
|
List<Exam> GetAll();
|
|
List<Exam> GetByGroup(Guid groupId);
|
|
void Save(Exam exam);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IExamResultRepository
|
|
{
|
|
List<ExamResult> GetByExam(Guid examId);
|
|
List<ExamResult> GetByStudent(Guid studentId);
|
|
ExamResult? GetByExamAndStudent(Guid examId, Guid studentId);
|
|
void Save(ExamResult result);
|
|
void SaveMany(List<ExamResult> results);
|
|
}
|
|
public interface IGradingKeyTemplateRepository
|
|
{
|
|
List<GradingKeyTemplate> GetAll();
|
|
List<GradingKeyTemplate> GetByGradingSystem(GradingSystem system);
|
|
GradingKeyTemplate? GetById(Guid id);
|
|
void Save(GradingKeyTemplate template);
|
|
void Delete(Guid id);
|
|
/// <summary>Siehe ISeatingPlanRepository.Restore (14.3).</summary>
|
|
void Restore(Guid trashId);
|
|
}
|
|
public interface IGradeRepository
|
|
{
|
|
List<Grade> GetByStudentAndGroup(Guid studentId, Guid groupId);
|
|
List<Grade> GetByGroup(Guid groupId);
|
|
void Save(Grade grade);
|
|
void Delete(Guid id);
|
|
/// <summary>Siehe ISeatingPlanRepository.Restore (14.3).</summary>
|
|
void Restore(Guid trashId);
|
|
}
|
|
public interface IGradingSchemeRepository
|
|
{
|
|
GradingScheme? GetByGroup(Guid groupId);
|
|
GradingScheme? GetDefaultForType(GroupType type);
|
|
void Save(GradingScheme scheme);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IReportGradeRepository
|
|
{
|
|
List<ReportGrade> GetByGroup(Guid groupId);
|
|
ReportGrade? GetByStudentGroupPeriod(Guid studentId, Guid groupId, string period);
|
|
void Save(ReportGrade grade);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IInterimGradeRepository
|
|
{
|
|
List<InterimGrade> GetByGroup(Guid groupId);
|
|
List<InterimGrade> GetByStudentAndGroup(Guid studentId, Guid groupId);
|
|
void Save(InterimGrade grade);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IUnitRepository
|
|
{
|
|
Unit? GetById(Guid id);
|
|
List<Unit> GetByGroup(Guid groupId);
|
|
void Save(Unit unit);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ILessonRepository
|
|
{
|
|
Lesson? GetById(Guid id);
|
|
List<Lesson> GetByUnit(Guid unitId);
|
|
List<Lesson> GetByGroupAndDate(Guid groupId, DateOnly date);
|
|
List<Lesson> GetByGroupAndRange(Guid groupId, DateOnly from, DateOnly to);
|
|
void Save(Lesson lesson);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ITimetableSlotRepository
|
|
{
|
|
List<TimetableSlot> GetAll();
|
|
List<TimetableSlot> GetByGroup(Guid groupId);
|
|
void Save(TimetableSlot slot);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ISchoolHolidayRepository
|
|
{
|
|
List<SchoolHoliday> GetAll();
|
|
void Save(SchoolHoliday holiday);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ISupervisionDutyRepository
|
|
{
|
|
List<SupervisionDuty> GetAll();
|
|
void Save(SupervisionDuty duty);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ISubstitutionEntryRepository
|
|
{
|
|
List<SubstitutionEntry> GetAll();
|
|
List<SubstitutionEntry> GetByDate(DateOnly date);
|
|
/// Für den WebUntis-Abgleich (idempotentes Update statt Duplikat je iCal-UID).
|
|
SubstitutionEntry? GetByExternalId(string externalId);
|
|
void Save(SubstitutionEntry entry);
|
|
void Delete(Guid id);
|
|
}
|
|
/// Zuletzt bekannter Zustand aller WebUntis-iCal-Termine, für den Abgleich bei jedem Abruf.
|
|
public interface IUntisSnapshotRepository
|
|
{
|
|
List<UntisSnapshotEntry> GetAll();
|
|
void Save(UntisSnapshotEntry entry);
|
|
void Delete(Guid id);
|
|
}
|
|
/// Lokaler Cache der Fehlzeiten-Berichtszeilen fürs Klassenlehrer-Feature (siehe TODO.md) —
|
|
/// bewusst nicht synchronisiert (siehe Implementierung), jedes Gerät ruft WebUntis selbst ab.
|
|
public interface IUntisAbsenceCacheRepository
|
|
{
|
|
List<UntisAbsenceCacheEntry> GetByClassAndRange(string className, int startDate, int endDate);
|
|
/// Löscht vorhandene Zeilen im Bereich und fügt die übergebenen neu ein — fürs "heiße" Fenster,
|
|
/// dessen Inhalt sich seit dem letzten Abruf geändert haben kann.
|
|
void ReplaceRange(string className, int startDate, int endDate, IEnumerable<UntisAbsenceCacheEntry> entries);
|
|
/// Fügt nur ein, ohne zu löschen — fürs Erweitern der als endgültig angenommenen "kalten" Historie.
|
|
void InsertRange(IEnumerable<UntisAbsenceCacheEntry> entries);
|
|
}
|
|
/// Lokaler Cache der Klassenbuch-Berichtszeilen anderer Lehrkräfte fürs Klassenlehrer-Feature —
|
|
/// gleiches Muster wie <see cref="IUntisAbsenceCacheRepository"/>.
|
|
public interface IUntisClassRegisterCacheRepository
|
|
{
|
|
List<UntisClassRegisterCacheEntry> GetByClassAndRange(string className, int startDate, int endDate);
|
|
void ReplaceRange(string className, int startDate, int endDate, IEnumerable<UntisClassRegisterCacheEntry> entries);
|
|
void InsertRange(IEnumerable<UntisClassRegisterCacheEntry> entries);
|
|
}
|
|
/// Lokaler Cache der aktuellen Klassenliste (Roster) fürs Klassenlehrer-Feature — anders als
|
|
/// Fehlzeiten/Klassenbuch keine Historie, deshalb kein ReplaceRange/InsertRange, sondern immer der
|
|
/// komplette Ersatz des zuletzt bekannten Standes einer Klasse.
|
|
public interface IUntisStudentRosterCacheRepository
|
|
{
|
|
List<UntisStudentRosterCacheEntry> GetByClass(string className);
|
|
void ReplaceAll(string className, IEnumerable<UntisStudentRosterCacheEntry> entries);
|
|
}
|
|
/// Merkt sich je Klasse+Berichtsart, wann das heiße Fenster zuletzt aufgefrischt wurde und wie weit
|
|
/// die kalte Historie bereits abgedeckt ist (siehe UntisReportCacheService).
|
|
public interface IUntisCacheFetchStateRepository
|
|
{
|
|
UntisCacheFetchState? Get(string className, UntisCacheKind kind);
|
|
void Save(UntisCacheFetchState state);
|
|
}
|
|
/// Zuletzt-Lauf-Status der Untis-Hub-Jobs (siehe TODO.md) - je (Kind, GroupId), GroupId null bei
|
|
/// den dashboard-weiten Jobs.
|
|
public interface IUntisHubJobStateRepository
|
|
{
|
|
UntisHubJobState? Get(UntisHubJobKind kind, Guid? groupId);
|
|
List<UntisHubJobState> GetAll();
|
|
void Save(UntisHubJobState state);
|
|
}
|
|
/// Vom Nutzer bestätigte Zuordnungen WebUntis-Wochenmuster → LearningGroup.
|
|
public interface IUntisSlotMappingRepository
|
|
{
|
|
List<UntisSlotMapping> GetAll();
|
|
void Save(UntisSlotMapping mapping);
|
|
void Delete(Guid id);
|
|
}
|
|
/// Lokal importierter, rein informativer Schuljahresplan. Bewusst getrennt von WebUntis-
|
|
/// Stundenplanabweichungen und nicht über den App-Sync repliziert; jedes Gerät bezieht denselben
|
|
/// externen Feed selbst.
|
|
public interface IAnnualPlanEventRepository
|
|
{
|
|
List<AnnualPlanEvent> GetAll();
|
|
List<AnnualPlanEvent> GetByRange(DateOnly from, DateOnly to);
|
|
AnnualPlanEvent? GetByExternalId(string externalId);
|
|
void Save(AnnualPlanEvent entry);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IDocumentationRepository
|
|
{
|
|
List<Documentation> GetByStudent(Guid studentId);
|
|
List<Documentation> GetByStudentAndType(Guid studentId, DocumentationType type);
|
|
/// Alle nicht gelöschten Einträge, über alle Schüler hinweg (z.B. für Dashboard-Auswertungen).
|
|
List<Documentation> GetAll();
|
|
void Save(Documentation doc);
|
|
/// Markiert den Eintrag als gelöscht, statt ihn hart zu entfernen (5.1.4).
|
|
void Delete(Guid id);
|
|
/// Entfernt den Eintrag endgültig — nur für die Löschfristen-Bereinigung (5.4.2).
|
|
void HardDelete(Guid id);
|
|
}
|
|
public interface IVorgangRepository
|
|
{
|
|
List<Vorgang> GetAll();
|
|
List<Vorgang> GetByStudent(Guid studentId);
|
|
Vorgang? GetById(Guid id);
|
|
void Save(Vorgang vorgang);
|
|
/// Markiert den Vorgang als gelöscht, statt ihn hart zu entfernen (gleiches Muster wie Documentation).
|
|
void Delete(Guid id);
|
|
}
|
|
/// "Zurückstellen"-Zeitstempel für Dashboard-Warnungen je (StudentId, WarningTag) — wird
|
|
/// synchronisiert, siehe DashboardWarningSnooze.
|
|
public interface IDashboardWarningSnoozeRepository
|
|
{
|
|
DashboardWarningSnooze? Get(Guid studentId, string warningTag);
|
|
List<DashboardWarningSnooze> GetAll();
|
|
void Save(DashboardWarningSnooze snooze);
|
|
}
|
|
public interface IWorkTaskRepository
|
|
{
|
|
List<WorkTask> GetByStatus(WorkTaskStatus status);
|
|
List<WorkTask> GetAll();
|
|
/// Für das "Anstehende Aufgaben"-Widget im Kurs-Dashboard (9.2/7.2).
|
|
List<WorkTask> GetByGroup(Guid groupId);
|
|
void Save(WorkTask task);
|
|
void Delete(Guid id);
|
|
/// <summary>Siehe ISeatingPlanRepository.Restore (14.3).</summary>
|
|
void Restore(Guid trashId);
|
|
}
|
|
public interface ITimeEntryRepository
|
|
{
|
|
List<TimeEntry> GetByDate(DateOnly date);
|
|
List<TimeEntry> GetByDateRange(DateOnly from, DateOnly to);
|
|
List<TimeEntry> GetByTask(Guid taskId);
|
|
void Save(TimeEntry entry);
|
|
void Delete(Guid id);
|
|
/// <summary>Siehe ISeatingPlanRepository.Restore (14.3).</summary>
|
|
void Restore(Guid trashId);
|
|
}
|
|
public interface IParticipationSessionRepository
|
|
{
|
|
List<ParticipationSession> GetByGroup(Guid groupId);
|
|
ParticipationSession? GetById(Guid id);
|
|
// Für Aggregationen über alle Gruppen (z.B. Dashboard-Fehlzeiten-Warnung), die sonst pro
|
|
// Eintrag einzeln GetById aufrufen müssten — ein Bulk-Laden vermeidet dieses N+1-Muster.
|
|
List<ParticipationSession> GetAll();
|
|
void Save(ParticipationSession session);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IParticipationRepository
|
|
{
|
|
List<ParticipationEntry> GetBySession(Guid sessionId);
|
|
List<ParticipationEntry> GetByStudent(Guid studentId);
|
|
ParticipationEntry? GetBySessionAndStudent(Guid sessionId, Guid studentId);
|
|
void Save(ParticipationEntry entry);
|
|
void SaveMany(List<ParticipationEntry> entries);
|
|
void DeleteBySession(Guid sessionId);
|
|
}
|
|
public interface IParticipationAspectRepository
|
|
{
|
|
List<ParticipationAspect> GetDefaults();
|
|
List<ParticipationAspect> GetByGroup(Guid groupId);
|
|
// Wie GetByGroup, aber inkl. deaktivierter Aspekte — für die Verwaltungsansicht (3.1),
|
|
// damit ein deaktivierter Aspekt dort sichtbar bleibt und wieder aktiviert werden kann.
|
|
List<ParticipationAspect> GetAllByGroup(Guid groupId);
|
|
void Save(ParticipationAspect aspect);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IParticipationSectionRepository
|
|
{
|
|
List<ParticipationSection> GetByGroup(Guid groupId);
|
|
void Save(ParticipationSection section);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ISubjectRepository
|
|
{
|
|
List<Subject> GetAll();
|
|
Subject? GetById(Guid id);
|
|
Subject? GetByName(string name);
|
|
void Save(Subject subject);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface ICompetencyDomainRepository
|
|
{
|
|
List<CompetencyDomain> GetBySubjectAndGrade(Guid subjectId, int gradeLevel, Guid versionId);
|
|
// Über alle Klassenstufen einer Version eines Fachs hinweg - für einen Überblick über den
|
|
// gesamten Katalog einer Version (z.B. MCP-Tool get_competency_catalog ohne gradeLevel-Filter),
|
|
// ohne dass der Aufrufer erst jede vorkommende Klassenstufe einzeln erraten/abfragen müsste.
|
|
List<CompetencyDomain> GetBySubjectAndVersion(Guid subjectId, Guid versionId);
|
|
// Über alle Fächer/Klassenstufen/Versionen hinweg - für Aufrufer, die eine CompetencyItem.Id
|
|
// auflösen müssen, ohne vorher das Fach der Zuordnung zu kennen (z.B. MCP add_lesson_competency).
|
|
List<CompetencyDomain> GetAll();
|
|
CompetencyDomain? GetById(Guid id);
|
|
void Save(CompetencyDomain domain);
|
|
void Delete(Guid id);
|
|
void DeleteBySubjectGradeAndVersion(Guid subjectId, int gradeLevel, Guid versionId);
|
|
void ReplaceForSubjectGradeAndVersion(Guid subjectId, int gradeLevel, Guid versionId, List<CompetencyDomain> domains);
|
|
}
|
|
|
|
public interface ICompetencyCatalogVersionRepository
|
|
{
|
|
List<CompetencyCatalogVersion> GetBySubject(Guid subjectId);
|
|
CompetencyCatalogVersion? GetById(Guid id);
|
|
/// <summary>Liefert die Standardversion des Fachs und legt sie an ("Bestehender Kompetenzkatalog"),
|
|
/// falls noch keine existiert - so brauchen Aufrufer, die nur einen Guid für die Domain-Suche
|
|
/// benötigen, keinen eigenen Anlegen-oder-Lesen-Ablauf.</summary>
|
|
CompetencyCatalogVersion GetOrCreateDefault(Guid subjectId);
|
|
void Save(CompetencyCatalogVersion version);
|
|
/// <summary>Blockiert (InvalidOperationException), wenn noch ein CompetencyDomain oder eine
|
|
/// LearningGroup diese Version referenziert, oder wenn sie die Standardversion ihres Fachs ist
|
|
/// (erst eine andere Version des Fachs als Standard setzen).</summary>
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IShorthandCodeRepository
|
|
{
|
|
List<ShorthandCode> GetAll();
|
|
void Save(ShorthandCode code);
|
|
void Delete(Guid id);
|
|
}
|
|
public interface IAlternativeLessonPathRepository
|
|
{
|
|
List<AlternativeLessonPath> GetAll();
|
|
AlternativeLessonPath? GetById(Guid id);
|
|
void Save(AlternativeLessonPath path);
|
|
void Delete(Guid id);
|
|
}
|
|
/// <summary>Papierkorb (14.3) — reine Übersicht/Aufräumen; das eigentliche Wiederherstellen läuft
|
|
/// über die jeweilige Fach-Repository (z.B. IGradeRepository.Restore), da nur die kennt, wie ein
|
|
/// Schnappschuss ihres Modells korrekt gespeichert wird (Validierung, OnChange-Ereignis).</summary>
|
|
public interface ITrashRepository
|
|
{
|
|
List<TrashedItem> GetAll();
|
|
void PurgeOlderThan(DateTime cutoffUtc);
|
|
}
|