Files
bin/docs/superpowers/specs/2026-07-20-szenario-eintraege-design.md
2026-07-20 12:37:45 +02:00

5.2 KiB
Raw Permalink Blame History

Design — Ausbaustufe 6: Szenario-Einträge-Tabelle (v0.7.0)

Status: vom Nutzer freigegeben (Chat 2026-07-20, inkl. Freigabe zum Direktdurchlauf Spec → Plan → Umsetzung). Anlass: Nutzerfeedback nach v0.6.0 — die Szenario-Änderungen (Modifikatoren, Einmalzahlungen) waren auf zwei zugeklappte <details>-Tabellen verteilt und nicht editierbar; erwartet wurde EINE editierbare Tabelle aller Einträge (Zielbild: 1520 Änderungen pro Szenario bequem pflegen).

Ziel

Pro Szenario eine immer sichtbare Tabelle „Einträge", die Modifikatoren und szenario-eigene Einmalzahlungen gemeinsam zeigt, mit Inline-Bearbeiten und Löschen je Zeile und einem gemeinsamen Anlege-Formular mit Eintragsart-Umschaltung.

Entscheidungen

  • Datenmodell unverändert. „Eintrag" ist eine reine Darstellungssicht auf ScenarioModifier und ScenarioPlannedItem. Keine Migration.
  • Typ bleibt beim Bearbeiten erhalten: ein Modifikator kann Art (percent/absolute/remove/ende), Ziel und Wert/Datum ändern; eine Einmalzahlung bleibt Einmalzahlung (Name/Betrag/Datum änderbar).
  • „Kredite zuordnen" bleibt eigener Abschnitt (Zuordnung, kein Eintrag).
  • Beschreibung des Szenarios bleibt Freitext ohne Funktion.

API

Zwei neue Endpunkte in app/routers/scenarios.py (Full-Body-Update — die Edit-Formulare senden immer alle Felder des Typs):

  • PATCH /api/scenarios/{id}/modifiers/{mod_id} — Body = ModifierIn (inkl. bestehender Validierung: ende erfordert end_date, andere Arten nullen es). 404 „Modifikator nicht gefunden" bei fremder/fehlender ID (Muster delete_modifier). Antwort ModifierOut.
  • PATCH /api/scenarios/{id}/planned/{item_id} — Body = ScenarioPlannedIn. 404 „Einmalzahlung nicht gefunden" (Muster delete_scenario_planned). Antwort ScenarioPlannedOut.

Sortierung für stabile Anzeige: Modifikator-Query in _scenario_rows bekommt .order_by(ScenarioModifier.id); Einmalzahlungen sind bereits nach due sortiert.

GUI (app/templates/planning.html)

Die zwei <details>-Abschnitte „Modifikatoren" und „Einmalzahlungen in diesem Szenario" werden ersetzt durch eine offene Tabelle „Einträge":

  • Spalten: Was | Art | Wert/Betrag | Datum | Aktionen.
    • Modifikator: Was = „Posten: X" / „Kategorie: Y"; Art = |de_label; Wert = value|eur bei percent/absolute, sonst „–"; Datum = end_date TT.MM.JJJJ bei ende, sonst „–".
    • Einmalzahlung: Was = Name; Art = „Einmalzahlung"; Wert = amount|eur € (neg-Klasse wie bisher); Datum = due TT.MM.JJJJ.
  • Zeilen-Reihenfolge: erst Modifikatoren (nach id), dann Einmalzahlungen (nach Fälligkeit).
  • Inline-Bearbeiten je Zeile nach dem toggleEdit-Muster aus v0.6.0: IDs mod-row-{id}/mod-edit-{id} bzw. spi-row-{id}/spi-edit-{id}. Modifikator-Edit-Formular = Felder des Anlege-Formulars (Ziel-Typ, Ziel, Art, Wert, Datum, vorbelegt, mit denselben Umschaltern), sendet hx-patch auf den neuen Endpunkt. Einmalzahlungs-Edit: Name/Betrag/Datum.
  • Ein Anlege-Formular „Neuer Eintrag" mit Dropdown Eintragsart (Ende, Prozent, Absolut, Entfällt, Einmalzahlung; Werte ende|percent|absolute|remove|einmal):
    • Feld-Umschaltung ausschließlich per disabled (UX-Regel): Ziel-Typ/Ziel aktiv bei den vier Modifikator-Arten; Wert aktiv bei Prozent/Absolut; Datum „Endet am" (end_date) aktiv bei Ende; Name/Betrag/„Fällig am" (due) aktiv bei Einmalzahlung.
    • Der Eintragsart-Select trägt name="kind"; beim Absenden an den Einmalzahlungs-Endpunkt wird das überzählige kind von Pydantic ignoriert (Default extra=ignore), disabled-Felder fehlen in der Serialisierung.
    • Ziel-Endpunkt-Wechsel: JS setzt das hx-post-Attribut des Formulars um (…/modifiers…/planned) und ruft htmx.process(form) auf.
  • Bestehende Helfer (onModTargetTypeChange, toggleEdit) werden weiterverwendet; neue Funktion onEntryArtChange(select) ersetzt onModKindChange (Umschaltmatrix oben). Scoping wie bisher über closest('form'), damit Anlege- und Edit-Formulare sich nicht stören.

hilfe.html: der Szenarien-Absatz wird auf die neue Einträge-Tabelle angepasst (weiterhin generisch, keine echten Daten).

Tests (TDD, Suite bleibt grün — Basis 178)

  • API: PATCH Modifikator (Wert ändern; Art auf ende wechseln mit Datum; ende ohne Datum → 422; fremde scenario_id → 404), PATCH Einmalzahlung (Betrag/Datum ändern; fremde scenario_id → 404).
  • GUI: eine Einträge-Tabelle statt der zwei details-Abschnitte (Summary-Texte „Modifikatoren"/„Einmalzahlungen in diesem Szenario" verschwinden), gemischte Zeilen inkl. „Einmalzahlung"-Art, Edit-Formulare mit hx-patch-URLs, Anlege-Formular mit Eintragsart-Optionen.

Release

finance/VERSION0.7.0, Redeploy via ./create_pod_finance.sh (keine Migration nötig), Live-Check am bestehenden Szenario „Best Case" (drei Einträge sichtbar in einer Tabelle, ein Bearbeiten-Roundtrip live). Fable-Testagent-Gate je Task vor Commit (CLAUDE.md). Datenschutz-Regel unverändert: echte Namen/Beträge nur Live-DB/Chat.

Außerhalb des Scopes: Typwechsel Modifikator↔Einmalzahlung beim Bearbeiten, Mehrfach-Bearbeitung/Bulk-Aktionen, Kredit-Zuordnung als Eintrag, Änderungen an Engine/Projektion.