using System.ComponentModel; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; namespace LehrerApp.Desktop.Services.Mcp.Tools; /// MCP-Tools "get_grades" (Phase 1) und "create_grade_entry" (Phase 2), siehe /// Planungsdokument. public class GradeTools(IGradeRepository grades, IStudentRepository students, IMcpConfirmationService confirmation) { [Description("Listet Noten einer Lerngruppe, optional gefiltert auf einen einzelnen Schüler.")] public List GetGrades( [Description("Lerngruppen-ID.")] Guid groupId, [Description("Optionale Schüler-ID zum Filtern auf einen einzelnen Schüler.")] Guid? studentId = null) { var list = studentId is { } sid ? grades.GetByStudentAndGroup(sid, groupId) : grades.GetByGroup(groupId); return list.Select(g => new GradeDto( g.Id, g.StudentId, g.GroupId, g.Category, g.Value, g.Date, g.Weight, g.Note)).ToList(); } [Description("Schlägt eine neue Note für einen Schüler vor. Muss der Nutzer erst in einem Dialog in LehrerApp bestätigen, bevor sie gespeichert wird.")] public async Task CreateGradeEntry( [Description("Schüler-ID.")] Guid studentId, [Description("Lerngruppen-ID.")] Guid groupId, [Description("Kategorie: Oral, Homework, Participation, Project oder Other.")] GradeCategory category, [Description("Notenwert als Text, z.B. \"2+\" oder \"gut\".")] string value, [Description("Datum, Format YYYY-MM-DD.")] DateOnly date, [Description("Gewichtung, Standard 1.0.")] double weight = 1.0, [Description("Optionale Notiz.")] string? note = null, CancellationToken ct = default) { var student = students.GetById(studentId); if (student is null) return new WriteResultDto(false, null, "Unbekannte Schüler-ID."); var message = $"Neue Note für {student.FullName}: {GradeCategoryDisplayName(category)} = {value}" + (weight != 1.0 ? $" (Gewichtung {weight:0.##})" : "") + $", am {date:dd.MM.yyyy}" + (string.IsNullOrWhiteSpace(note) ? "" : $"\n„{note}“"); if (!await confirmation.ConfirmAsync("Note anlegen?", message, ct)) return new WriteResultDto(false, null, "Vom Nutzer abgelehnt oder nicht bestätigt."); var grade = new Grade { StudentId = studentId, GroupId = groupId, Category = category, Value = value, Date = date, Weight = weight, Note = note, }; grades.Save(grade); return new WriteResultDto(true, grade.Id, "Note gespeichert."); } // Eigene, schlanke Beschriftung statt Wiederverwendung von ViewModels.Groups.GradeCategoryDisplay: // Tool-Klassen unter Services/Mcp sollen nicht von ViewModel-Klassen abhängen. private static string GradeCategoryDisplayName(GradeCategory c) => c switch { GradeCategory.Oral => "Mündlich", GradeCategory.Homework => "Hausaufgaben", GradeCategory.Participation => "Mitarbeit", GradeCategory.Project => "Projekt", GradeCategory.Other => "Sonstiges", _ => c.ToString(), }; }