Files
LehrerApp/LehrerApp.Desktop/ViewModels/Settings/SettingsViewModel.cs
T
adminandClaude Sonnet 5 f97edff2fe feat: Bildungsplan-Versionierung für Kompetenzkataloge, vollständig über MCP exponiert
Neue Bildungspläne wachsen je Fach klassenstufenweise hoch, sodass Kurse abhängig vom
Einschulungsjahr entweder dem alten oder dem neuen Bildungsplan folgen. CompetencyCatalogVersion
(Fach + Name + IsDefault) macht das abbildbar: CompetencyDomain bekommt eine VersionId, Kurse
wählen über LearningGroup.CompetencyCatalogVersionId (null = Standardversion des Fachs) welche
Version gilt. Migration legt für bestehende Kataloge automatisch eine Standardversion an, damit
alte Datenbanken unverändert weiterlaufen.

MCP: neue Tools für Versions-CRUD (get/create/update/delete_competency_plan_version,
update_group_competency_version), get_competency_catalog/create_competency_domain um optionalen
versionId-Parameter erweitert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 00:07:29 +02:00

189 lines
8.2 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LehrerApp.Core.Interfaces;
using LehrerApp.Core.Models;
using LehrerApp.Core.Services;
using LehrerApp.Data;
using LehrerApp.Desktop.Services;
using LehrerApp.Desktop.ViewModels.Planning;
using LehrerApp.Sync;
using LehrerApp.Sync.Crypto;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Security.Cryptography;
using System.Text.Json;
using System.Text.Json.Serialization;
using LehrerApp.Templating;
namespace LehrerApp.Desktop.ViewModels.Settings;
/// <summary>
/// Reihenfolge MUSS exakt der Reihenfolge der ContentPage-Elemente in SettingsView.axaml
/// entsprechen (ActiveTabIndex bindet per Index, nicht per Name) — beim Umsortieren eines
/// Tabs in der XAML immer auch hier den Enum-Wert verschieben.
/// </summary>
public enum SettingsTab
{
Subjects = 0,
ShorthandCodes = 1,
Competencies = 2,
GradingKeyTemplates = 3,
GradingScheme = 4,
LetterTemplates = 5,
Holidays = 6,
PeriodSchedule = 7,
SupervisionDuties = 8,
Security = 9,
Privacy = 10,
Sync = 11,
Ai = 12,
WebUntis = 13,
Appearance = 14,
Trash = 15,
Mcp = 16,
}
// ── Haupt-ViewModel ───────────────────────────────────────────────────────────
public partial class SettingsViewModel : ObservableObject
{
private readonly ISubjectRepository _subjects;
private readonly ICompetencyDomainRepository _domainRepo;
private readonly ICompetencyCatalogVersionRepository _versionRepo;
private readonly IGradingKeyTemplateRepository _gradingKeyTemplates;
private readonly IGradingSchemeRepository _gradingSchemes;
private readonly GradingService _grading;
private readonly BackupService _backups;
private readonly BackupSettingsService _backupSettings;
private readonly DatabaseEncryptionService _dbEncryption;
private readonly AppLockService _appLock;
private readonly LiteDbContext _dbContext;
private readonly PrivacySettingsService _privacy;
private readonly IDocumentationRepository _documentation;
private readonly IStudentRepository _students;
private readonly IShorthandCodeRepository _shorthandCodes;
private readonly TemplateStore _letterTemplates;
private readonly WorksheetTemplateStore _worksheetTemplates;
[ObservableProperty] private int _activeTabIndex;
// ── Konstruktor ───────────────────────────────────────────────────────────
private readonly ISchoolHolidayRepository _schoolHolidays;
private readonly SchoolCalendarSettingsService _calendarSettings;
private readonly SchoolWeatherService? _schoolWeather;
private readonly PeriodScheduleService _periodSchedule;
private readonly ISupervisionDutyRepository _supervisionDuties;
private readonly AiSettingsService _aiSettings;
private readonly AiPlanningService _aiPlanning;
private readonly McpSettingsService _mcpSettings;
private readonly Services.Mcp.McpClientRegistrationService _mcpRegistration;
private readonly WebUntisSettingsService _untisSettings;
private readonly WebUntisIntegrationService? _untisIntegration;
private readonly UntisSyncService? _untisSync;
private readonly AnnualPlanSettingsService _annualPlanSettings;
private readonly AnnualPlanSyncService? _annualPlanSync;
private readonly SyncSettingsService _syncSettings;
private readonly SyncAuthService _syncAuth;
private readonly EventQueue _eventQueue;
private readonly SyncEngine? _syncEngine;
private readonly SnapshotService? _snapshotService;
private readonly SyncKeyRecoveryService _syncKeyRecovery;
private readonly AppearanceSettingsService _appearance;
private readonly CompetencyCatalogImportService _catalogImport;
private readonly AppLogger _logger;
public TrashViewModel TrashTab { get; }
public SettingsViewModel(ISubjectRepository subjects, ICompetencyDomainRepository domainRepo,
ICompetencyCatalogVersionRepository versionRepo,
IGradingKeyTemplateRepository gradingKeyTemplates, IGradingSchemeRepository gradingSchemes,
GradingService grading, BackupService backups, BackupSettingsService backupSettings,
DatabaseEncryptionService dbEncryption,
AppLockService appLock, LiteDbContext dbContext, PrivacySettingsService privacy,
IDocumentationRepository documentation, IStudentRepository students,
IShorthandCodeRepository shorthandCodes, ISchoolHolidayRepository schoolHolidays,
SchoolCalendarSettingsService calendarSettings, PeriodScheduleService periodSchedule,
ISupervisionDutyRepository supervisionDuties, TemplateStore letterTemplates,
WorksheetTemplateStore worksheetTemplates,
AiSettingsService aiSettings, AiPlanningService aiPlanning, McpSettingsService mcpSettings,
Services.Mcp.McpClientRegistrationService mcpRegistration,
WebUntisSettingsService untisSettings,
AnnualPlanSettingsService annualPlanSettings,
SyncSettingsService syncSettings, SyncAuthService syncAuth, EventQueue eventQueue,
AppLogger logger, SyncKeyStatus syncKeyStatus, SyncKeyRecoveryService syncKeyRecovery,
AppearanceSettingsService appearance, TrashViewModel trashTab,
SnapshotService? snapshotService = null, SyncEngine? syncEngine = null,
UntisSyncService? untisSync = null, AnnualPlanSyncService? annualPlanSync = null,
SchoolWeatherService? schoolWeather = null, WebUntisIntegrationService? untisIntegration = null)
{
_logger = logger;
_syncKeyRecovery = syncKeyRecovery;
SyncKeyWasRegenerated = syncKeyStatus.KeyWasRegenerated;
_appearance = appearance;
_selectedTheme = appearance.Load();
TrashTab = trashTab;
_subjects = subjects;
_domainRepo = domainRepo;
_versionRepo = versionRepo;
_gradingKeyTemplates = gradingKeyTemplates;
_gradingSchemes = gradingSchemes;
_grading = grading;
_backups = backups;
_backupSettings = backupSettings;
_dbEncryption = dbEncryption;
_appLock = appLock;
_dbContext = dbContext;
_privacy = privacy;
_documentation = documentation;
_students = students;
_shorthandCodes = shorthandCodes;
_schoolHolidays = schoolHolidays;
_calendarSettings = calendarSettings;
_schoolWeather = schoolWeather;
_periodSchedule = periodSchedule;
_supervisionDuties = supervisionDuties;
_letterTemplates = letterTemplates;
_worksheetTemplates = worksheetTemplates;
_aiSettings = aiSettings;
_aiPlanning = aiPlanning;
_mcpSettings = mcpSettings;
_mcpRegistration = mcpRegistration;
_untisSettings = untisSettings;
_untisIntegration = untisIntegration;
_untisSync = untisSync;
_annualPlanSettings = annualPlanSettings;
_annualPlanSync = annualPlanSync;
_syncSettings = syncSettings;
_syncAuth = syncAuth;
_eventQueue = eventQueue;
_snapshotService = snapshotService;
_syncEngine = syncEngine;
_catalogImport = new CompetencyCatalogImportService(domainRepo);
LoadSubjects();
LoadShorthandCodes();
LoadGradingKeyTemplates();
LoadGradingSchemes();
LoadBackups();
IsDbEncrypted = _dbEncryption.IsEncrypted(AppBootstrapper.DbPath);
AppLockEnabled = _appLock.IsEnabled;
AppLockTimeoutMinutes = _appLock.TimeoutMinutes;
RetentionYears = _privacy.RetentionYears;
LoadExpiredDocuments();
SelectedStateName = GermanStateDisplay.Label(_calendarSettings.State);
LoadSchoolHolidays();
LoadPeriodTimes();
LoadSupervisionDuties();
LoadLetterTemplates();
LoadWorksheetTemplates();
LoadAiSettings();
LoadMcpSettings();
LoadMcpRegistrationStatus();
LoadUntisSettings();
LoadAnnualPlanSettings();
LoadSyncSettings();
LoadSyncConflicts();
}
}