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

104 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/VERSION``0.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.