feat: MCP-Tools für Fach-/Kompetenzverwaltung + Kompetenzzuordnung zu Lessons (Nutzer-Nachtrag)
Neue CompetencyTools.cs: create/update/delete_subject, create/update/delete_competency_domain, add/update/remove_competency_item, get_subjects, get_competency_catalog. delete_subject und delete_competency_domain als weitere Destructive-Ausnahmen neben delete_lesson (kein Papierkorb). Lesson bekommt ein neues Competencies-Feld (analog zu Unit.Competencies) sowie add_lesson_competency/remove_lesson_competency in LessonPlanTools.cs. ICompetencyDomainRepository um GetBySubject() erweitert, um den Katalog eines Fachs ohne bekannte Klassenstufe abzufragen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -300,6 +300,54 @@ public class LessonPlanTools(
|
||||
return new WriteResultDto(true, phase.Id, "Phase entfernt.");
|
||||
}
|
||||
|
||||
// ── Einzelstunden (Lesson) — Kompetenzzuordnung ──────────────────────────────────────────
|
||||
// Auf Stundenebene (Lesson.Competencies), noch nicht je Phase - siehe TODO.md 4.5.8. Getrennte
|
||||
// add/remove-Tools statt eines "set_lesson_competencies", das die ganze Liste ersetzt: dieselbe
|
||||
// Race-Condition-Überlegung wie bei den Verlaufsplan-Phasen (add/update/remove_lesson_phase) -
|
||||
// ein Tool-Aufruf ändert nur einen Code, kein "letzter Schreiber gewinnt" über die ganze Liste.
|
||||
|
||||
[Description("Ordnet einer Einzelstunde einen Kompetenzcode aus dem Katalog zu (siehe get_competency_catalog). Muss der Nutzer erst bestätigen.")]
|
||||
public async Task<WriteResultDto> AddLessonCompetency(
|
||||
[Description("ID der Einzelstunde.")] Guid lessonId,
|
||||
[Description("Kompetenzcode, z.B. \"M.5.1\".")] string code,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var lesson = lessons.GetById(lessonId);
|
||||
if (lesson is null) return new WriteResultDto(false, null, "Unbekannte Stunden-ID.");
|
||||
code = code.Trim();
|
||||
if (code.Length == 0) return new WriteResultDto(false, null, "Leerer Kompetenzcode.");
|
||||
if (lesson.Competencies.Contains(code, StringComparer.OrdinalIgnoreCase))
|
||||
return new WriteResultDto(true, lesson.Id, "Kompetenzcode ist bereits zugeordnet.");
|
||||
|
||||
var message = $"Kompetenz „{code}“ zu „{lesson.Topic}“ am {lesson.Date:dd.MM.yyyy} hinzufügen?";
|
||||
if (!await confirmation.ConfirmAsync("Kompetenz zuordnen?", message, ct))
|
||||
return new WriteResultDto(false, null, "Vom Nutzer abgelehnt oder nicht bestätigt.");
|
||||
|
||||
lesson.Competencies.Add(code);
|
||||
lessons.Save(lesson);
|
||||
return new WriteResultDto(true, lesson.Id, "Kompetenz zugeordnet.");
|
||||
}
|
||||
|
||||
[Description("Entfernt einen Kompetenzcode von einer Einzelstunde. Muss der Nutzer erst bestätigen.")]
|
||||
public async Task<WriteResultDto> RemoveLessonCompetency(
|
||||
[Description("ID der Einzelstunde.")] Guid lessonId,
|
||||
[Description("Kompetenzcode, wie in get_lesson_plans hinterlegt.")] string code,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var lesson = lessons.GetById(lessonId);
|
||||
if (lesson is null) return new WriteResultDto(false, null, "Unbekannte Stunden-ID.");
|
||||
var existing = lesson.Competencies.FirstOrDefault(c => string.Equals(c, code, StringComparison.OrdinalIgnoreCase));
|
||||
if (existing is null) return new WriteResultDto(false, null, "Dieser Kompetenzcode ist dieser Stunde nicht zugeordnet.");
|
||||
|
||||
var message = $"Kompetenz „{existing}“ von „{lesson.Topic}“ am {lesson.Date:dd.MM.yyyy} entfernen?";
|
||||
if (!await confirmation.ConfirmAsync("Kompetenz entfernen?", message, ct))
|
||||
return new WriteResultDto(false, null, "Vom Nutzer abgelehnt oder nicht bestätigt.");
|
||||
|
||||
lesson.Competencies.Remove(existing);
|
||||
lessons.Save(lesson);
|
||||
return new WriteResultDto(true, lesson.Id, "Kompetenz entfernt.");
|
||||
}
|
||||
|
||||
// ── Einzelstunden (Lesson) — Verschieben & Löschen ───────────────────────────────────────
|
||||
|
||||
[Description("Verschiebt eine Einzelstunde auf ein neues Datum (und optional eine neue Stundennummer). Mit shiftFollowingLessons=true verschieben sich alle noch nicht durchgeführten, späteren Stunden derselben Einheit um denselben Tages-Versatz mit — so lässt sich eine Lücke für eine neue Stunde öffnen: diese Stunde auf den Termin der übernächsten verschieben (mit shiftFollowingLessons), dann create_lesson auf das dadurch freigewordene ursprüngliche Datum. Muss der Nutzer erst bestätigen.")]
|
||||
@@ -361,7 +409,7 @@ public class LessonPlanTools(
|
||||
}
|
||||
|
||||
private static LessonDto ToDto(Lesson l) => new(
|
||||
l.Id, l.UnitId, l.GroupId, l.Date, l.LessonNumber, l.Topic, l.Homework, l.Status,
|
||||
l.Id, l.UnitId, l.GroupId, l.Date, l.LessonNumber, l.Topic, l.Homework, l.Status, l.Competencies,
|
||||
l.Phases.Select(p => new LessonPhaseDto(p.Id, p.Name, p.DurationMinutes, p.Activity, p.Material, p.Shorthand)).ToList(),
|
||||
l.Attachments.Select(a => new LessonAttachmentDto(a.StorageId, a.FileName, a.SizeBytes)).ToList());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user