feat: goal-driven learning workflow (Lernziele, adaptive workspace, new study plan)#23
Merged
Merged
Conversation
…sessment Introduce per-module learning goals (1..n, freely combinable) as the foundation for the goal-driven learning workflow: - new module_goal + goal_attempt tables (GoalType, GoalGradingRole, GoalConfig) - drop module.examType/isThesis/maxAttempts/passFail/bonus*, add toolOverrides - generalize thesis_project -> writing_project (kind thesis|term_paper, variant, taskDescription, goalId) + writing_milestone - grade pipeline computes a weight-weighted average over grade-role goals with bonus from the bonus-role goal; single-goal modules keep identical results - data-preserving migration 0038 with backfill; goal helpers in lib/studies/goals.ts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- goal-actions: createGoal/updateGoal/deleteGoal/reorderGoals with zod validation over GoalConfig (bonus, term_paper variant, presentation, ...) - goal-dialog: type-conditional create/edit dialog (FormDialog-based) - module-goals-card: lists a module's goals with role badges + deadlines, per-row edit/delete, and an empty-state setup card with type chips - module-dialog: create-time "Was musst du leisten?" goal-type chips - createModule seeds one grade goal per selected type - i18n: goals namespace (de/en, full key parity) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- module-tabs config: paper + plan tabs; defaultToolsForGoals matrix and
enabledTools(goalTypes, overrides); visibleModuleTabs takes {aiAvailable,
enabledTools} (overview/materials/plan always, chat AI-gated, optional
tools by goal + override)
- "more tools" popover toggles optional tools -> updateModuleTools action
- sidebar + module layout compute enabled tools from goals + toolOverrides
- context: SemesterModule carries toolOverrides
- paper/plan stub pages (replaced in phases 5/7)
- module-tabs.test.ts: 16 pure matrix/override/gating cases
- i18n: moduleTabs.paper/.plan/.moreTools/.comingSoon (de/en parity)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- goal-card: one rich card per learning goal, variant by type/gradingRole (exam readiness + countdown + attempts, assignments status + bonus bar, term_paper/thesis countdown + write-up link, presentation checklist) - attempts are now goal-scoped: addAttempt(goalId, ...) enforces that goal's maxAttempts; removed the module-level ensureGradeGoal default - module-grade-summary-card: compact module final grade + legacy grades + aggregate bonus (no per-goal attempts table) - module-goals-card renders a GoalCard per goal, keeps add + empty-state chips - overview page builds per-goal DTOs (attempts, per-goal grade, assignment roll-ups); delete unused module-assessment-card - i18n: goalCard namespace (de/en parity) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- lib/writing: shared phase sequences (scientific/task) + pure AI prompt
builders (outline, milestones, brainstorm, sources) shared by thesis and
term-paper actions (no prompt duplication)
- writing-actions: ensureModuleWritingProject (resolve thesis>term_paper>
project goal, get/create the writing_project), variant-aware outline/
milestone/source generation, milestone CRUD
- writing-workspace: generalized component; task variant swaps research
question for editable taskDescription ("Bearbeitungsschritte"), scientific
keeps thesis behavior; requiresSources adds source-term suggestions
- paper tab renders the module's writing project; a thesis module shares the
same writing_project row as /thesis (via goalId + programId)
- /thesis now renders WritingWorkspace; delete old thesis-workspace/milestone-row
- i18n: writing namespace (de/en parity)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
New goal-driven study-plan foundation alongside the old system (removed in phase 7): - schema plan.ts: module_plan (per-module strategy: active/weight/weeklyHours/ phase/preferredWeekdays), plan_task (goal-derived, source-tagged, editable), plan_session (scheduled appointment); semester_plan gains config - lib/plan/scheduler.ts: pure deterministic scheduler (availability minus blockers, weighted round-robin within active phase, deadline-first, weeklyHours caps) + 15 property tests (availability, overlaps, caps, durations, deadlines, phases, weights, determinism, preferred weekdays) - lib/plan/tasks.ts: goal-based task drafts with source idempotency + 8 tests - plan-task-actions + schedule-actions (recompute/replan/moveSession pin) - additive migration 0039 (no drops) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- module plan tab: editable goal-derived task list (dnd), "generate from goals", per-module strategy prefs (active/weight/weeklyHours/phase/weekdays), upcoming sessions - semester strategy board: per-module phase (Jetzt/Danach/Später) + weights + availability, "Plan berechnen" (deterministic scheduler) with warnings, and a week-grouped session preview - calendar: plan sessions are now editable (drag/resize pins them, click opens a task checklist); dashboard + daily reminder read plan_session - remove the old study_plan/study_plan_item/semester_plan_item tables, their actions, routes and components; migration 0040 maps old rows then drops - i18n: plan namespace; drop dead plan keys (de/en parity) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- lib/studies/goal-context: shared getModuleGoalContext + pure formatters (formatGoalContext for the system prompt, formatExamContext for generation) - chat: module conversations get the goal-context paragraph; auto-mode picks writing/thesis from goals when the stored mode is general (explicit mode still wins); getContext exposes goalTypes + nextDueDate, getModuleDetails description updated - generation: examContext threaded through GenParams into card/quiz prompts and the batch path; deck/quiz/coverage entry points assemble it - analyzeProgress relates recommendations to upcoming goal deadlines - createAssignment tool takes an optional goalId, defaults to the module's assignments goal Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
- move retry-thesis-button + thesis-create into components/writing (thesis dir removed); update the /thesis imports - drop unused uniqueIndex import (plan schema) and unused daysUntil (scheduler) Verified: typecheck, eslint (0 warnings), 168 tests, and a clean production build (next build) covering the new paper/plan routes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warum
Bisher behandelte die App jedes Modul identisch: gleiche Tabs, gleiche AI‑Prompts, egal ob es mit Klausur, Hausarbeit, Abgaben oder Präsentation abschließt. Die vorhandenen Daten (
module_assessment,examType, Bonus‑Felder,isThesis) steuerten nur die Notenberechnung, nicht den Workflow. Die Hausarbeit hatte keine eigene Unterstützung, und es gab zwei entkoppelte Plan‑Systeme (LLM‑generierter Semesterplan ohne Kollisionsgarantie + reine Modul‑Taskliste ohne Kalender).Dieser PR macht den Lern‑Workflow zielgerichtet: Der Student definiert pro Modul, was und wofür gelernt werden muss, und UI + AI + Lernplan richten sich danach aus.
Was sich ändert
Lernziele pro Modul (statt 1:1‑Assessment)
module_goal(1..n pro Modul, frei kombinierbar):exam,assignments,term_paper,presentation,oral_exam,project,thesis,other— je mit Benotungsrolle (grade/bonus/practice), Gewicht, Deadline, Versuchen und typspezifischer Config.grade‑Ziele + Bonus aus dembonus‑Ziel; Ein‑Ziel‑Module verhalten sich exakt wie zuvor.Adaptiver Workspace
defaultToolsForGoals); nicht passende Werkzeuge sind ausgeblendet, aber per „Weitere Werkzeuge" pro Modul zuschaltbar (toolOverrides).Hausarbeit & Thesis als Writing‑Workspace
thesis_project→writing_projectverallgemeinert (kindthesis|term_paper,variantscientific|task). Paper‑Tab flext zwischen wissenschaftlicher Arbeit (Forschungsfrage, Quellen, Gliederung) und konkreter Aufgabenbearbeitung (Aufgabenstellung, Bearbeitungsschritte).writing_project‑Zeile erscheint im Paper‑Tab (pergoalId) und unter/thesis(perprogramId) — keine Duplikate. Geteilte AI‑Builder für Brainstorm/Outline/Meilensteine + Quellen‑Suchbegriffe.Neuer Lernplan: Termine mit Tasks, semesterweit koordiniert
plan_task, aus Lernzielen abgeleitet, editierbar); Zeit pro Semester über einen deterministischen Scheduler (kein LLM) →plan_session(kollisionsfreie Termine mit Datum/Uhrzeit/Dauer).plan_session. Der alte LLM‑Semesterplan und die alte Modul‑Taskliste wurden entfernt.Zielbewusste AI
getModuleGoalContext: Chat kennt die Ziele/Deadlines des Moduls und wählt bei Modus „general" automatisch Schreib-/Thesis‑Modus; Karten‑/Quiz‑Generierung spiegelt das Prüfungsformat;analyzeProgressbezieht Empfehlungen auf anstehende Deadlines;createAssignmentkennt das Abgaben‑Ziel.Datenmodell / Migrationen
0038— Lernziele:module_goal+goal_attempt,writing_project/writing_milestone, Modul‑Spalten entfernt (examType/isThesis/maxAttempts/passFail/bonus*),toolOverrides. Data‑preserving Backfill ausmodule_assessment/Bonus/isThesis.0039— Plan‑Fundament (additiv):module_plan,plan_task,plan_session,semester_plan.config.0040— Plan‑Cutover: Alt‑Zeilen nachplan_session/plan_taskgemappt, dannstudy_plan/study_plan_item/semester_plan_itementfernt.Umgesetzt in 9 verifizierten Phasen (jede grün auf typecheck + tests). Details im Plan unter
.claude/plans/.Verifikation
npm run typecheck→ 0npm run test→ 168 bestanden (u. a. 15 Scheduler‑Property‑Tests: Verfügbarkeit, Überlappungen, Kapazität, Fristen, Phasen, Gewichte, Determinismus, Wunsch‑Wochentage; 8 Task‑Tests; 16 Tab‑Matrix‑Tests; erweiterte Noten‑Tests inkl. Ein‑Ziel‑Parität)npm run lint→ 0 Warnungennpm run build→ erfolgreich (inkl. neuer Routen/paper,/plan)db:generate‑Snapshot‑Konsistenz und Review der handgeschriebenen Backfills.Note
Dev‑Umgebung: bewusste Breaking‑Schema‑Änderungen, Migration lossy‑but‑reasonable (Plan‑Zeilen ohne Modul werden verworfen). Kein Backward‑Compat nötig.
🤖 Generated with Claude Code
https://claude.ai/code/session_012Nrz9bERddhwVXWuZyVBn7
Generated by Claude Code