#91 — Neuer Listentyp "Priorisierte Liste" #90
Labels
No labels
priority/could
priority/must
priority/should
priority/wont
status/blocked
status/claimed
status/done-migrated
type/bug
type/feature
type/infra
type/tech-debt
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
robert/todo#90
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Story: Neuer Listentyp "Priorisierte Liste"
As a list member,
I want to meine To-Dos nach Dringlichkeit und Wichtigkeit auf einer Skala von 1–100 einordnen und in einer
2D-Matrix sehen können,
so that ich Aufgaben mit hoher Wichtigkeit, aber geringer gefühlter Dringlichkeit (die ich sonst liegen
lasse), tatsächlich umsetze.
Depends on:
#89(Listentyp-Vereinheitlichung — dieser Typ ist "Priorisierte Liste" darin).Acceptance criteria:
#89).Wichtig (1–100) — unabhängig von der bestehenden
Priority-Einstufung (Low/Normal/High), die beidiesem Typ nicht verwendet/angezeigt wird.
Dringend + Faktor × Wichtig, absteigend, Faktor als Listeneinstellung proListe konfigurierbar, Default
1,1.Punkt kann direkt auf der Karte gezogen (Drag) werden, um Dringend/Wichtig nachträglich zu verändern —
nicht nur beim Anlegen über das Modal.
Entscheidung — die Formel-Sortierung ist der Zweck dieser Ansicht, eine Kategorie-Gruppierung würde sie
durchbrechen).
und Einkaufslisten) mit:
umgekehrt aktualisieren Änderungen an den Zahlenfeldern die Position auf der Mini-Karte.
Kommentare, Wiederholung, Kategorien.
Out of scope for this story:
Priority-Einstufung für andere Listentypen — bleibt unangetastet.design (
91_priority_matrix_list_type_design.md)Design:
#91— Priorisierte Liste (Dringend/Wichtig-Matrix)Kernentscheidung: Variante der Todo-Liste, nicht Sibling-Entity
TodoListEntitybekommt eine neueType-Spalte (Standard | Priority),TodoEntitybekommt zweinullable Zusatzfelder (
Urgency,Importance) undTodoListEntityein nullablePriorityMatrixFactor— kein neuer Entity-Baum.Begründung:
#91verlangt explizit "volle bestehende Todo-Feature-Palette bleibt erhalten:Fälligkeitsdatum, Zuweisung, Subtasks/Checkliste, Kommentare, Wiederholung, Kategorien". Eine
Sibling-Entity nach dem Vorbild von
#93(Masterpackliste) müsste jedes dieser Features neu bauen —das widerspricht der AC direkt.
Priorityist inhaltlich eine Variante der Todo-Liste(dieselben Todos, andere Anordnung/Zusatzachsen), nicht eine strukturell andere Domain wie
Shopping/Pantry/Masterpack.
Damit weicht diese Story bewusst von
#89's "keinListType-Enum/-Spalte"-Ruling ab.#89selbsthat diese Öffnung offengelassen: "Für
#91–94 ist das eine eigene künftige Architect-Entscheidung— spekulative Enum-Werte für noch nicht gebaute Typen würden jetzt nur Risiko ohne Nutzen
hinzufügen (YAGNI)." Der Enum-Wert wird hier für einen konkret gebauten Typ eingeführt, nicht
spekulativ; der YAGNI-Grund entfällt damit.
Schema-Änderungen
TodoListEntityType— neuerTodoListType-Enum (Standard = 0, Priority = 1), NOT NULL, defaultStandard.PriorityMatrixFactor— nullabledouble, nur beiType = Prioritygesetzt, Default1.1.Range-Validation im VO (0.0 < factor ≤ 10.0). Nullable statt "nur ignoriert" damit der Zustand
"keine Priorisierungs-Liste" strukturell unmissverständlich bleibt und ein späterer Type-Wechsel
(aktuell nicht vorgesehen — Type ist bei Erstellung fixiert) nicht magisch einen Faktor mitführt.
TodoEntityUrgency— nullableTodoUrgency(1–100), gesetzt nur bei Todos auf einer Priority-Liste.Importance— nullableTodoImportance(1–100), gesetzt nur bei Todos auf einer Priority-Liste.Beide nullable, weil dieselbe
TodoEntity-Tabelle Todos beider List-Typen enthält. BeiStandard-Listen bleiben die Felder
NULLund werden vom Frontend nicht abgefragt/angezeigt.Die bestehende
Priority-Spalte (Low/Normal/High) bleibt strukturell erhalten und wird fürPriority-Listen vom Frontend schlicht nicht mehr angeboten — AC-konform ("bei diesem Typ nicht
verwendet/angezeigt").
Neue Vogen-VOs
TodoListType(Enum,Standard | Priority).TodoUrgency(int, 1–100).TodoImportance(int, 1–100).PriorityMatrixFactor(double, 0.0 < x ≤ 10.0).Bereich 1–100 statt 0–100 spiegelt die AC-Formulierung wörtlich ("auf einer Skala von 1–100").
Neue/erweiterte Commands & Queries
CreateTodoListCommand— bekommt optionalenType-Parameter (defaultStandard) undoptionalen
PriorityMatrixFactor(nur beiType = Prioritygesetzt). Zwei bestehendeHandler-Aufrufe (
CreateTodoListCommandHandler, dessen Tests, Frontend-CreateListDialog) aufdie erweiterte Signatur ziehen.
CreateTodoCommand— bekommt optionaleUrgency/Importance-Parameter, die nur gesetztwerden dürfen wenn die Ziel-Liste
Type = Priorityhat (Handler validiert). Bei Standard-ListenMÜSSEN sie null sein; bei Priority-Listen SOLLEN sie gesetzt sein (nicht zwingend im Handler
erzwungen — Frontend schickt sie immer; sonst greift der Default 50/50 der V1-Semantik).
SetTodoUrgencyImportanceCommand(id + urgency + importance). Muss geprüft werden: dieZiel-Liste ist vom Typ
Priority; sonst 400.SetPriorityMatrixFactorCommand(id + factor). Owner-only (spiegeltSetTodoListAppearanceCommand's Owner-Regel — pro-Liste-Konfig).Migration
Ein Migration-File mit drei DDL-Schritten:
ALTER TABLE "TodoListEntity" ADD COLUMN "Type" TEXT NOT NULL DEFAULT 'Standard'.ALTER TABLE "TodoListEntity" ADD COLUMN "PriorityMatrixFactor" DOUBLE PRECISION NULL.ALTER TABLE "TodoEntity" ADD COLUMN "Urgency" INTEGER NULL,ALTER TABLE "TodoEntity" ADD COLUMN "Importance" INTEGER NULL.Kein Backfill nötig — Bestandslisten sind alle
Type = Standard, Todos habenNULLUrgency/Importance.
Frontend — V1-Scope
Menschlicher PO hat 2026-08-09 in der laufenden Session entschieden, die volle 2D-Scatter-Ansicht
mit Drag-to-Reposition in einen Follow-up zu ziehen. V1 liefert stattdessen:
CreatePriorityTodoListDialog(Titel +Faktor-Eingabe mit Default 1.1).
list.type === 'Priority'):(kommt bald)" — der Karten-Button ist sichtbar, aber deaktiviert; ein
titleerklärt denGrund. Damit ist der Toggle-Slot schon in der UI vorhanden und die Follow-up-Story tauscht nur
den Panel-Inhalt aus, ohne die Page-Shell erneut anzufassen.
Urgency + Faktor × Importanceabsteigend. KeineKategorie-Gruppierung (AC explizit — "würde die Formel-Sortierung durchbrechen").
TodoListwiederverwendet).Neben-Chip; ansonsten dieselbe
TodoRow-Komponente wie Standard-Listen (Checkbox,Fälligkeit, Assignee, Subtasks-Badge, Kommentar-Badge, Recurrence-Badge — alle unverändert).
TodoInput-Zeile bei Priority-Listen —AC: "eigenes Modal, nicht die kleine Eingabezeile unten"):
Zahlen entsprechend der Klick-Koordinate; umgekehrt aktualisiert eine Änderung an den
Zahlen-Inputs die Punkt-Position. Read-only-Karte in V1 — keine Drag-Interaktion (das ist
der explizit deferrte Teil).
LabelPickerPopoverwiederverwendet, falls vorhanden; sonst als Teil dieser Story neu, aber leichtgewichtig).
PriorityMatrixPage(oben rechts,neben dem Ansichts-Toggle), auf
blurgespeichert viaSetPriorityMatrixFactorCommand;Owner-only sichtbar.
Zahlen in der Listenzeile → öffnet dasselbe Zwei-Zahlen-Modal (kleinere Wiederverwendung des
Create-Dialog-Inhalts) → speichert via
SetTodoUrgencyImportanceCommand. Ohne diesen Editier-Weg wäre die Formel-Neujustierung nur durch Löschen und Neuanlegen möglich, was den ganzen
Nutzen der Liste konterkariert.
Explizit deferred: Follow-up-Story
#91bPlaceholder im Toggle. Grund: die Drag-Interaktion (Touch + Desktop, Achsen-Clamping,
Live-Persistierung während des Drags, Kollisionsvermeidung eng beieinander liegender Punkte,
visuelles Label bei Hover/Focus, Screen-Reader-Alternative) ist der Löwenanteil des UI-Aufwands
der Story und trägt gleichzeitig das meiste Fehlerrisiko — sinnvoller als eigene Folge-Story,
sobald V1 in echter Nutzung ist und der genaue Bedarf klar wird (z.B. "wird die Karte auf
Mobile überhaupt praktisch genutzt?"). Backend, Datenmodell, Sortierlogik und
SetTodoUrgencyImportanceCommandsind bereits in V1 vorhanden —#91bist damit reinFrontend-Arbeit ohne API/DB-Erweiterung.
Security-Vorprüfung
Keine neuen Authorisierungs-Pfade:
CreateTodoListCommanderweitert um Typ-Parameter — bestehender Auth-Check unverändert (derUser erstellt seine eigene Liste, kein neuer Fremdzugriff möglich).
CreateTodoCommanderweitert um Urgency/Importance — Handler ruft bestehendenAuthorizeTodoListAccessQuery(Mitglied darf Todos anlegen), zusätzlichType = Priority-Check.SetTodoUrgencyImportanceCommand— spiegeltSetTodoDueDateCommand(Mitglieds-Access, keineOwner-Restriktion — jeder Nutzer darf jedes Todo einer Liste bearbeiten, dieselbe Regel wie für
Titel/Beschreibung/Fälligkeit).
SetPriorityMatrixFactorCommand— Owner-only, spiegeltSetTodoListAppearanceCommand. Faktorist pro-Liste-Konfig, nicht pro-Ansicht — Member sollen nicht die Formel für alle anderen ändern
können.
Numerische Ranges werden per Vogen im Serialisierungspfad validiert (Ungültige Werte → 400 bevor
der Handler läuft). Keine Injection-Vektoren (reine Zahlen/Enum-Werte).
Test-Strategie
CreateTodoListCommandHandlerfür neuen Type-Parameter,CreateTodoCommandHandlerfür Urgency/Importance (inkl. Fehler bei Standard-Liste),SetTodoUrgencyImportanceCommandHandler,SetPriorityMatrixFactorCommandHandler(Owner-only-Ablehnung).
PriorityMatrixPage(Sortierung, Label-Filter, Toggle-Placeholder-Zustand),CreatePriorityTodoDialog(Mini-Karten-Klick synchronisiert Zahlen, Label-Auswahl,Submit-Payload),
CreatePriorityTodoListDialog(Faktor-Default, Erstellung).prüfe Reihenfolge nach Formel → ändere Faktor → prüfe geänderte Reihenfolge → editiere ein
Todo → prüfe neue Position.