chore: Release v0.12.0 (System-Präfix, Doppelzählungs-Warnung)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+35
-1
@@ -40,8 +40,11 @@ flowchart TD
|
||||
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"]
|
||||
S_doublecount["double_count.py<br/>all_conflicts, conflicts_for_recurring,<br/>conflicts_for_loan"]
|
||||
end
|
||||
|
||||
N_reserved["app/reserved.py<br/>check_reserved_name"]
|
||||
|
||||
subgraph ENGINE["engine/ (rein, kein DB-Zugriff)"]
|
||||
E_loans["loans.py<br/>loan_schedule, annuity_payment, add_months"]
|
||||
E_recurrence["recurrence.py<br/>occurrences"]
|
||||
@@ -86,7 +89,11 @@ flowchart TD
|
||||
R_imports --> S_importer
|
||||
R_planning --> E_loans
|
||||
R_planning --> S_suggestions
|
||||
R_planning --> S_doublecount
|
||||
R_scenarios --> S_projection
|
||||
R_scenarios --> N_reserved
|
||||
R_categories --> N_reserved
|
||||
R_gui --> S_doublecount
|
||||
R_admin --> S_admin
|
||||
|
||||
ROUTERS -.-> M_tables
|
||||
@@ -315,9 +322,36 @@ heute), je bereits durchgerechnetem Szenario einen Startpunkt exakt heute
|
||||
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
|
||||
`app/reserved.py::check_reserved_name` lehnt `POST`/`PATCH` mit diesem
|
||||
Namen (case-insensitiv) mit 422 ab.
|
||||
|
||||
**Präfix `System-` reserviert (Ausbaustufe 12).** `app/reserved.py`
|
||||
(`SYSTEM_PREFIX = "System-"`, `is_reserved_name`, `check_reserved_name`)
|
||||
sperrt diesen Präfix für Kategorie- und Szenario-Namen (`routers/categories.py`,
|
||||
`routers/scenarios.py`, je `check_reserved_name` auf `POST`/`PATCH`, 422 bei
|
||||
Verstoß) — er gehört den vom Tool erzeugten Serien `RESERVED_SCENARIO_NAME`
|
||||
(`"System-Ist"`, `models/views.py`) und `services/planning_chart.py::KREDITRATEN`
|
||||
(`"System-Kreditraten"`).
|
||||
|
||||
**Doppelzählungs-Erkennung Kredit ↔ Fixposten (Ausbaustufe 12).**
|
||||
`app/services/double_count.py` erkennt, wenn ein monatlicher Ausgabe-Posten
|
||||
(`RecurringItem`, `rhythm == "monthly"`) betraglich vermutlich einer regulären
|
||||
Kreditrate (`regular_rate`, Annuität bzw. bei endfälligen Krediten die
|
||||
monatlichen Zinsen) entspricht — Toleranz `max(TOLERANZ_MIN=1.00,
|
||||
rate * TOLERANZ_PROZENT=3 / 100)` — und sich die Zeiträume überschneiden
|
||||
(`rate_period`). `routers/planning.py` ruft `conflicts_for_recurring` bzw.
|
||||
`conflicts_for_loan` bei `POST`/`PATCH` auf `/api/recurring` und
|
||||
`/api/loans` auf; ohne `doppelzaehlung_bestaetigt: true` im Request-Body
|
||||
antwortet es mit `409` (`detail.code == "doppelzaehlung_kredit"`, Konstante
|
||||
`CODE`). `static/doppelzaehlung.js` fängt genau diesen 409 im globalen
|
||||
`htmx:responseError`-Handler ab und zeigt das `<dialog id=
|
||||
"doppelzaehlung-dialog">` aus `base.html`; „Trotzdem speichern“ markiert das
|
||||
Formular (`data-doppelzaehlung-bestaetigt="1"`) und sendet es erneut, die
|
||||
`json-form`-Erweiterung ergänzt dabei `doppelzaehlung_bestaetigt: true`.
|
||||
`routers/gui.py::planung_page` ruft zusätzlich `all_conflicts` auf und zeigt
|
||||
einen dauerhaften ⚠-Hinweis je betroffenem Posten/Kredit in `planning.html`,
|
||||
solange der Konflikt fortbesteht.
|
||||
|
||||
**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
|
||||
|
||||
Reference in New Issue
Block a user