chore: Release v0.11.0 (Szenario-Löschen, Grafana-Korrekturen, Tabellensortierung)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+42
-1
@@ -37,7 +37,8 @@ flowchart TD
|
||||
S_balances["balances.py<br/>account_balance(at), total_balance"]
|
||||
S_categorize["categorize.py<br/>apply_rules"]
|
||||
S_suggestions["suggestions.py<br/>suggest_recurring"]
|
||||
S_projection["projection_service.py<br/>run_projection"]
|
||||
S_projection["projection_service.py<br/>run_projection, refresh_stale_projections"]
|
||||
S_planning_chart["planning_chart.py<br/>refresh_planning_chart"]
|
||||
S_admin["admin.py<br/>change_password, apply_rules_retroactively"]
|
||||
end
|
||||
|
||||
@@ -75,6 +76,8 @@ flowchart TD
|
||||
R_gui --> E_loans
|
||||
R_gui --> E_recurrence
|
||||
R_gui --> S_balances
|
||||
R_gui --> S_projection
|
||||
R_gui --> S_planning_chart
|
||||
R_admin --> R_gui
|
||||
|
||||
R_accounts --> S_balances
|
||||
@@ -96,6 +99,9 @@ flowchart TD
|
||||
S_projection --> E_projection
|
||||
S_projection --> E_scenario
|
||||
S_projection --> S_balances
|
||||
S_planning_chart --> E_loans
|
||||
S_planning_chart --> E_recurrence
|
||||
S_planning_chart --> M_tables
|
||||
S_admin --> S_categorize
|
||||
|
||||
E_scenario --> E_loans
|
||||
@@ -300,6 +306,41 @@ ist die einzige Brücke: es lädt ORM-Objekte (`Loan`, `RecurringItem`,
|
||||
`PlannedItem`, `Scenario`, `ScenarioModifier`), baut daraus die Plain-Objekte
|
||||
und ruft `engine.scenario.build_cashflows` → `engine.projection.project`.
|
||||
|
||||
**`v_projection` (Ausbaustufe 11) — System-Ist + Szenarien ab heute.**
|
||||
`models/views.py::VIEWS["v_projection"]` liefert für den Grafana-Szenario-
|
||||
Vergleich drei Teile in einer Tabelle: die Ist-Gesamtsaldo-Serie unter dem
|
||||
Namen `RESERVED_SCENARIO_NAME` (`"System-Ist"`, aus `v_balance_total`, endet
|
||||
heute), je bereits durchgerechnetem Szenario einen Startpunkt exakt heute
|
||||
(Ist-Saldo, damit die Kurve nahtlos ansetzt) sowie dessen gespeicherte
|
||||
Projektionspunkte NACH heute (`projection_points`, `day > CURRENT_DATE`) —
|
||||
Punkte <= heute aus einer älteren Berechnung erscheinen so nie.
|
||||
`RESERVED_SCENARIO_NAME` ist für Szenario-Namen gesperrt:
|
||||
`routers/scenarios.py::_check_reserved_name` lehnt `POST`/`PATCH` mit diesem
|
||||
Namen (case-insensitiv) mit 422 ab.
|
||||
|
||||
**Abgeleitete Tabellen + Advisory-Locks (Ausbaustufe 11).** Zwei Datenstände
|
||||
werden bei GUI-Seitenaufrufen automatisch aufgefrischt, nie beim reinen
|
||||
API-Zugriff (`routers/gui.py::_safe_refresh`, fehlerresistent — ein Fehler
|
||||
rollt zurück, loggt und lässt die Seite mit dem alten Stand rendern):
|
||||
`services/projection_service.py::refresh_stale_projections` rechnet jedes
|
||||
bereits durchgerechnete, aber veraltete Szenario mit dem Standard-Horizont
|
||||
neu (Advisory-Lock `STALE_PROJECTION_LOCK = 110_001`), aufgerufen von
|
||||
`index` und `szenarien_page`. `services/planning_chart.py::refresh_planning_chart`
|
||||
schreibt die Tabelle `planning_monthly` (`models/tables.py::PlanningMonthly`,
|
||||
Migration `d5e8b3c7a410`) komplett neu — Monatssummen je Kategorie aus
|
||||
Planung (wiederkehrende Posten, Einmalposten, Kreditraten aller Kredite
|
||||
unter Kategorie „Kreditraten") für das Grafana-Panel „Planung nach
|
||||
Kategorie" (`Advisory-Lock PLANNING_CHART_LOCK = 110_002`), aufgerufen von
|
||||
`index` und `planung_page`. Beide Tabellen sind jederzeit reproduzierbar
|
||||
(kein Backup-Sonderfall).
|
||||
|
||||
**Tabellensortierung (Ausbaustufe 11).** `static/sort.js` sortiert generische
|
||||
Tabellen client-seitig per Spaltenkopf-Klick (⇅/▲/▼, deutsche Zahlen-/
|
||||
Datumsformate, `htmx.onLoad`-Reinit für nachgeladene Fragmente) — Ausnahme
|
||||
`table[data-sort-mode="server"]`. Die Buchungsliste (`/buchungen`) ist so
|
||||
markiert und sortiert stattdessen serverseitig über alle Seiten
|
||||
(`routers/transactions.py::SORT_COLUMNS`, `normalize_sort`, `_apply_sort`).
|
||||
|
||||
**`VERSION`-Datei als Single Source.** `finance/VERSION` (ein Einzeiler, z.B.
|
||||
`0.4.0`) ist die einzige Versionsquelle: `app/version.py::get_version()`
|
||||
liest sie (Fallback `"0.0.0-dev"`), gespeist in den Jinja2-Footer
|
||||
|
||||
Reference in New Issue
Block a user